/*   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.DefaultClassLoaderResourceLoader;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XBeanDebug;
import org.apache.xmlbeans.impl.repackage.Repackager;
import org.apache.xmlbeans.impl.util.FilerImpl;
import org.apache.xmlbeans.impl.util.HexBin;
import org.apache.xmlbeans.impl.values.XmlObjectBase;
import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroupDocument;
import org.apache.xmlbeans.impl.xb.xsdschema.GroupDocument;
import org.apache.xmlbeans.soap.SOAPArrayType;
import org.apache.xmlbeans.soap.SchemaWSDLArrayType;

import javax.xml.namespace.QName;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class SchemaTypeSystemImpl extends SchemaTypeLoaderBase implements SchemaTypeSystem {
    public static final int DATA_BABE = 0xDA7ABABE;
    public static final int MAJOR_VERSION = 2;  // must match == to be compatible
    public static final int MINOR_VERSION = 24; // must be <= to be compatible
    public static final int RELEASE_NUMBER = 0; // should be compatible even if < or >

    public static final int FILETYPE_SCHEMAINDEX = 1;
    public static final int FILETYPE_SCHEMATYPE = 2;
    public static final int FILETYPE_SCHEMAELEMENT = 3;
    public static final int FILETYPE_SCHEMAATTRIBUTE = 4;
    public static final int FILETYPE_SCHEMAPOINTER = 5;
    public static final int FILETYPE_SCHEMAMODELGROUP = 6;
    public static final int FILETYPE_SCHEMAATTRIBUTEGROUP = 7;
    public static final int FILETYPE_SCHEMAIDENTITYCONSTRAINT = 8;

    public static final int FLAG_PART_SKIPPABLE = 1;
    public static final int FLAG_PART_FIXED = 4;
    public static final int FLAG_PART_NILLABLE = 8;
    public static final int FLAG_PART_BLOCKEXT = 16;
    public static final int FLAG_PART_BLOCKREST = 32;
    public static final int FLAG_PART_BLOCKSUBST = 64;
    public static final int FLAG_PART_ABSTRACT = 128;
    public static final int FLAG_PART_FINALEXT = 256;
    public static final int FLAG_PART_FINALREST = 512;

    public static final int FLAG_PROP_ISATTR = 1;
    public static final int FLAG_PROP_JAVASINGLETON = 2;
    public static final int FLAG_PROP_JAVAOPTIONAL = 4;
    public static final int FLAG_PROP_JAVAARRAY = 8;

    public static final int FIELD_NONE = 0;
    public static final int FIELD_GLOBAL = 1;
    public static final int FIELD_LOCALATTR = 2;
    public static final int FIELD_LOCALELT = 3;

    // type flags
    static final int FLAG_SIMPLE_TYPE = 0x1;
    static final int FLAG_DOCUMENT_TYPE = 0x2;
    static final int FLAG_ORDERED = 0x4;
    static final int FLAG_BOUNDED = 0x8;
    static final int FLAG_FINITE = 0x10;
    static final int FLAG_NUMERIC = 0x20;
    static final int FLAG_STRINGENUM = 0x40;
    static final int FLAG_UNION_OF_LISTS = 0x80;
    static final int FLAG_HAS_PATTERN = 0x100;
    static final int FLAG_ORDER_SENSITIVE = 0x200;
    static final int FLAG_TOTAL_ORDER = 0x400;
    static final int FLAG_COMPILED = 0x800;
    static final int FLAG_BLOCK_EXT = 0x1000;
    static final int FLAG_BLOCK_REST = 0x2000;
    static final int FLAG_FINAL_EXT = 0x4000;
    static final int FLAG_FINAL_REST = 0x8000;
    static final int FLAG_FINAL_UNION = 0x10000;
    static final int FLAG_FINAL_LIST = 0x20000;
    static final int FLAG_ABSTRACT = 0x40000;
    static final int FLAG_ATTRIBUTE_TYPE = 0x80000;

    /**
     * regex to identify the type system holder package namespace
     */
    private static final Pattern packPat = Pattern.compile("^(.+)(\\.[^.]+){2}$");

    /**
     * This is to support the feature of a separate/private XMLBeans
     * distribution that will not colide with the public org apache
     * xmlbeans one.
     * METADATA_PACKAGE_GEN will be "" for the original and something like
     * com.mycompany.private.xmlbeans for a private distribution of XMLBeans.
     * <p>
     * There are two properties:
     * METADATA_PACKAGE_GEN - used for generating metadata
     * and METADATA_PACKAGE_LOAD - used for loading the metadata.
     * Most of the time they have the same value, with one exception, during the
     * repackage process scomp needs to load from old package and generate into
     * a new package.
     */
    public static String METADATA_PACKAGE_GEN = "org/apache/xmlbeans/metadata";
//    public static String METADATA_PACKAGE_GEN;
//    static
//    {
//        // fix for maven classloader
//        Package stsPackage = SchemaTypeSystem.class.getPackage();
//        String stsPackageName = (stsPackage==null) ?
//            SchemaTypeSystem.class.getName().substring(0, SchemaTypeSystem.class.getName().lastIndexOf(".")) :
//            stsPackage.getName();
//
//        METADATA_PACKAGE_GEN = stsPackageName.replace('.', '/') + "/metadata";
//    }

    private static String nameToPathString(String nameForSystem) {
        nameForSystem = nameForSystem.replace('.', '/');

        if (!nameForSystem.endsWith("/") && nameForSystem.length() > 0) {
            nameForSystem = nameForSystem + "/";
        }

        return nameForSystem;
    }

    protected SchemaTypeSystemImpl() {
        String fullname = getClass().getName();
        _name = fullname.substring(0, fullname.lastIndexOf('.'));
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Loading type system " + _name, 1);
        _basePackage = nameToPathString(_name);
        _classloader = getClass().getClassLoader();
        _linker = this;
        _resourceLoader = new ClassLoaderResourceLoader(_classloader);
        try {
            initFromHeader();
        } catch (Error | RuntimeException e) {
            XBeanDebug.logException(e);
            throw e;
        }
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1);
    }

    public SchemaTypeSystemImpl(Class indexclass) {
        String fullname = indexclass.getName();
        _name = fullname.substring(0, fullname.lastIndexOf('.'));
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Loading type system " + _name, 1);
        _basePackage = nameToPathString(_name);
        _classloader = indexclass.getClassLoader();
        _linker = SchemaTypeLoaderImpl.build(null, null, _classloader, getMetadataPath());
        _resourceLoader = new ClassLoaderResourceLoader(_classloader);
        try {
            initFromHeader();
        } catch (RuntimeException e) {
            XBeanDebug.logException(e);
            throw e;
        } catch (Error e) {
            XBeanDebug.logException(e);
            throw e;
        }
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1);
    }

    public static boolean fileContainsTypeSystem(File file, String name) {
        String indexname = nameToPathString(name) + "index.xsb";

        if (file.isDirectory()) {
            return (new File(file, indexname)).isFile();
        } else {
            try (ZipFile zipfile = new ZipFile(file)) {
                ZipEntry entry = zipfile.getEntry(indexname);
                return (entry != null && !entry.isDirectory());
            } catch (IOException e) {
                XBeanDebug.log("Problem loading SchemaTypeSystem, zipfilename " + file);
                XBeanDebug.logException(e);
                throw new SchemaTypeLoaderException(e.getMessage(), name, "index", SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }
    }

    public static SchemaTypeSystemImpl forName(String name, ClassLoader loader) {
        try {
            Class c = Class.forName(name + "." + SchemaTypeCodePrinter.INDEX_CLASSNAME, true, loader);
            return (SchemaTypeSystemImpl) c.getField("typeSystem").get(null);
        } catch (Throwable e) {
            return null;
        }
    }

    public SchemaTypeSystemImpl(ResourceLoader resourceLoader, String name, SchemaTypeLoader linker) {
        _name = name;
        _basePackage = nameToPathString(_name);
        _linker = linker;
        _resourceLoader = resourceLoader;
        try {
            initFromHeader();
        } catch (RuntimeException e) {
            XBeanDebug.logException(e);
            throw e;
        } catch (Error e) {
            XBeanDebug.logException(e);
            throw e;
        }
    }

    private void initFromHeader() {
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Reading unresolved handles for type system " + _name, 0);
        XsbReader reader = null;
        try {
            // Read the index file, which starts with a header.
            reader = new XsbReader("index", FILETYPE_SCHEMAINDEX);

            // has a handle pool (count, handle/type, handle/type...)
            _localHandles = new HandlePool();
            reader.readHandlePool(_localHandles);

            // then a qname map of global elements (count, qname/handle, qname/handle...)
            _globalElements = reader.readQNameRefMap();

            // qname map of global attributes
            _globalAttributes = reader.readQNameRefMap();

            // qname map of model groups
            _modelGroups = reader.readQNameRefMap();

            // qname map of attribute groups
            _attributeGroups = reader.readQNameRefMap();

            _identityConstraints = reader.readQNameRefMap();

            // qname map of global types
            _globalTypes = reader.readQNameRefMap();

            // qname map of document types, by the qname of the contained element
            _documentTypes = reader.readQNameRefMap();

            // qname mape of attribute types, by the qname of the contained attribute
            _attributeTypes = reader.readQNameRefMap();

            // string map of all types, by fully qualified classname
            _typeRefsByClassname = reader.readClassnameRefMap();

            _namespaces = reader.readNamespaces();

            // support for redefine, at the end of the file
            List typeNames = new ArrayList();
            List modelGroupNames = new ArrayList();
            List attributeGroupNames = new ArrayList();
            if (reader.atLeast(2, 15, 0)) {
                _redefinedGlobalTypes = reader.readQNameRefMapAsList(typeNames);
                _redefinedModelGroups = reader.readQNameRefMapAsList(modelGroupNames);
                _redefinedAttributeGroups = reader.readQNameRefMapAsList(attributeGroupNames);
            }
            if (reader.atLeast(2, 19, 0)) {
                _annotations = reader.readAnnotations();
            }

            buildContainers(typeNames, modelGroupNames, attributeGroupNames);
        } finally {
            if (reader != null) {
                reader.readEnd();
            }
        }
    }

    void saveIndex() {
        String handle = "index";
        XsbReader saver = new XsbReader(handle);
        saver.writeIndexData();
        saver.writeRealHeader(handle, FILETYPE_SCHEMAINDEX);
        saver.writeIndexData();
        saver.writeEnd();
    }

    void savePointers() {
        savePointersForComponents(globalElements(), getMetadataPath() + "/element/");
        savePointersForComponents(globalAttributes(), getMetadataPath() + "/attribute/");
        savePointersForComponents(modelGroups(), getMetadataPath() + "/modelgroup/");
        savePointersForComponents(attributeGroups(), getMetadataPath() + "/attributegroup/");
        savePointersForComponents(globalTypes(), getMetadataPath() + "/type/");
        savePointersForComponents(identityConstraints(), getMetadataPath() + "/identityconstraint/");
        savePointersForNamespaces(_namespaces, getMetadataPath() + "/namespace/");
        savePointersForClassnames(_typeRefsByClassname.keySet(), getMetadataPath() + "/javaname/");
        savePointersForComponents(redefinedModelGroups(), getMetadataPath() + "/redefinedmodelgroup/");
        savePointersForComponents(redefinedAttributeGroups(), getMetadataPath() + "/redefinedattributegroup/");
        savePointersForComponents(redefinedGlobalTypes(), getMetadataPath() + "/redefinedtype/");
    }

    void savePointersForComponents(SchemaComponent[] components, String dir) {
        for (int i = 0; i < components.length; i++) {
            savePointerFile(dir + QNameHelper.hexsafedir(components[i].getName()), _name);
        }
    }

    void savePointersForClassnames(Set classnames, String dir) {
        for (Iterator i = classnames.iterator(); i.hasNext(); ) {
            String classname = (String) i.next();
            savePointerFile(dir + classname.replace('.', '/'), _name);
        }
    }

    void savePointersForNamespaces(Set namespaces, String dir) {
        for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
            String ns = (String) i.next();
            savePointerFile(dir + QNameHelper.hexsafedir(new QName(ns, "xmlns")), _name);
        }
    }

    void savePointerFile(String filename, String name) {
        XsbReader saver = new XsbReader(filename);
        saver.writeString(name);
        saver.writeRealHeader(filename, FILETYPE_SCHEMAPOINTER);
        saver.writeString(name);
        saver.writeEnd();
    }

    /**
     * The strategy here is to copy the compiled TypeSystemHolder.template class
     * to a new TypeSystemHolder.class needed by the schema type system.  When
     * saving a loader, we read the TypeSystemHolder.template class file and
     * swap out the utf8 string constants with new ones to create a new
     * TypeSystemHolder class file.  This saves us the need to rely on javac
     * to compile a generated .java file into the class file.
     * <p>
     * See the JVM spec on how to interpret the bytes of a class file.
     */
    void saveLoader() {
        String indexClassName = SchemaTypeCodePrinter.indexClassForSystem(this);
        String[] replace = makeClassStrings(indexClassName);
        assert replace.length == HOLDER_TEMPLATE_NAMES.length;

        Repackager repackager = null;
        if (_filer instanceof FilerImpl) {
            repackager = ((FilerImpl) _filer).getRepackager();
        }

        final String outName = indexClassName.replace('.', '/') + ".class";
        try (DataInputStream in = new DataInputStream(getHolder());
             DataOutputStream out = new DataOutputStream(_filer.createBinaryFile(outName))) {

            // java magic
            out.writeInt(in.readInt());

            // java minor and major version
            out.writeShort(in.readUnsignedShort());
            out.writeShort(in.readUnsignedShort());

            int poolsize = in.readUnsignedShort();
            out.writeShort(poolsize);

            // the constant pool is indexed from 1 to poolsize-1
            for (int i = 1; i < poolsize; i++) {
                int tag = in.readUnsignedByte();
                out.writeByte(tag);

                switch (tag) {
                    case CONSTANT_UTF8:
                        String value = in.readUTF();
                        out.writeUTF(repackageConstant(value, replace, repackager));
                        break;

                    case CONSTANT_CLASS:
                    case CONSTANT_STRING:
                        out.writeShort(in.readUnsignedShort());
                        break;

                    case CONSTANT_NAMEANDTYPE:
                    case CONSTANT_METHOD:
                    case CONSTANT_FIELD:
                    case CONSTANT_INTERFACEMETHOD:
                        out.writeShort(in.readUnsignedShort());
                        out.writeShort(in.readUnsignedShort());
                        break;

                    case CONSTANT_INTEGER:
                    case CONSTANT_FLOAT:
                        out.writeInt(in.readInt());
                        break;

                    case CONSTANT_LONG:
                    case CONSTANT_DOUBLE:
                        out.writeInt(in.readInt());
                        out.writeInt(in.readInt());
                        break;

                    default:
                        throw new RuntimeException("Unexpected constant type: " + tag);
                }
            }

            // we're done with the class' constant pool,
            // we can just copy the rest of the bytes
            copy(in, out);
        } catch (IOException e) {
            // ok
        }
    }

    private InputStream getHolder() {
        InputStream is = SchemaTypeSystemImpl.class.getResourceAsStream(HOLDER_TEMPLATE_CLASSFILE);
        if (is != null) {
            return is;
        }
        DefaultClassLoaderResourceLoader clLoader = new DefaultClassLoaderResourceLoader();
        is = clLoader.getResourceAsStream(HOLDER_TEMPLATE_CLASSFILE);
        if (is != null) {
            return is;
        }
        throw new SchemaTypeLoaderException("couldn't find resource: " + HOLDER_TEMPLATE_CLASSFILE,
            _name, null, SchemaTypeLoaderException.IO_EXCEPTION);
    }

    private static long copy(InputStream inp, OutputStream out) throws IOException {
        final byte[] buff = new byte[4096];
        long totalCount = 0;
        int readBytes;
        do {
            int todoBytes = buff.length;
            readBytes = inp.read(buff, 0, todoBytes);
            if (readBytes > 0) {
                out.write(buff, 0, readBytes);
                totalCount += readBytes;
            }
        } while (readBytes >= 0);

        return totalCount;
    }

    private static final String HOLDER_TEMPLATE_CLASS = "org.apache.xmlbeans.impl.schema.TypeSystemHolder";
    private static final String HOLDER_TEMPLATE_CLASSFILE = "TypeSystemHolder.template";
    private static final String[] HOLDER_TEMPLATE_NAMES = makeClassStrings(HOLDER_TEMPLATE_CLASS);

    // constant pool entry types
    private static final int CONSTANT_UTF8 = 1;
    private static final int CONSTANT_UNICODE = 2;
    private static final int CONSTANT_INTEGER = 3;
    private static final int CONSTANT_FLOAT = 4;
    private static final int CONSTANT_LONG = 5;
    private static final int CONSTANT_DOUBLE = 6;
    private static final int CONSTANT_CLASS = 7;
    private static final int CONSTANT_STRING = 8;
    private static final int CONSTANT_FIELD = 9;
    private static final int CONSTANT_METHOD = 10;
    private static final int CONSTANT_INTERFACEMETHOD = 11;
    private static final int CONSTANT_NAMEANDTYPE = 12;

    // MAX_UNSIGNED_SHORT
    private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1;

    private static String repackageConstant(String value, String[] replace, Repackager repackager) {
        for (int i = 0; i < HOLDER_TEMPLATE_NAMES.length; i++) {
            if (HOLDER_TEMPLATE_NAMES[i].equals(value)) {
                return replace[i];
            }
        }

        if (repackager != null) {
            return repackager.repackage(new StringBuffer(value)).toString();
        }

        return value;
    }

    /**
     * Construct an array of Strings found in a class file for a classname.
     * For the class name 'a.b.C' it will generate an array of:
     * 'a.b.C', 'a/b/C', 'La/b/C;', and 'class$a$b$C'.
     */
    private static String[] makeClassStrings(String classname) {
        String[] result = new String[4];

        result[0] = classname;
        result[1] = classname.replace('.', '/');
        result[2] = "L" + result[1] + ";";
        result[3] = "class$" + classname.replace('.', '$');

        return result;
    }

    /**
     * Only used in the nonbootstrapped case.
     */
    private Map buildTypeRefsByClassname() {
        List allSeenTypes = new ArrayList();
        Map result = new LinkedHashMap();
        allSeenTypes.addAll(Arrays.asList(documentTypes()));
        allSeenTypes.addAll(Arrays.asList(attributeTypes()));
        allSeenTypes.addAll(Arrays.asList(globalTypes()));

        // now fully javaize everything deeply.
        for (int i = 0; i < allSeenTypes.size(); i++) {
            SchemaType gType = (SchemaType) allSeenTypes.get(i);
            String className = gType.getFullJavaName();
            if (className != null) {
                result.put(className.replace('$', '.'), gType.getRef());
            }
            allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes()));
        }
        return result;
    }

    private Map buildTypeRefsByClassname(Map typesByClassname) {
        Map result = new LinkedHashMap();
        for (Iterator i = typesByClassname.keySet().iterator(); i.hasNext(); ) {
            String className = (String) i.next();
            result.put(className, ((SchemaType) typesByClassname.get(className)).getRef());
        }
        return result;
    }

    private static Map buildComponentRefMap(SchemaComponent[] components) {
        Map result = new LinkedHashMap();
        for (int i = 0; i < components.length; i++) {
            result.put(components[i].getName(), components[i].getComponentRef());
        }
        return result;
    }

    private static List buildComponentRefList(SchemaComponent[] components) {
        List result = new ArrayList();
        for (int i = 0; i < components.length; i++) {
            result.add(components[i].getComponentRef());
        }
        return result;
    }

    private static Map buildDocumentMap(SchemaType[] types) {
        Map result = new LinkedHashMap();
        for (int i = 0; i < types.length; i++) {
            result.put(types[i].getDocumentElementName(), types[i].getRef());
        }
        return result;
    }

    private static Map buildAttributeTypeMap(SchemaType[] types) {
        Map result = new LinkedHashMap();
        for (int i = 0; i < types.length; i++) {
            result.put(types[i].getAttributeTypeAttributeName(), types[i].getRef());
        }
        return result;
    }

    // Container operation
    private SchemaContainer getContainer(String namespace) {
        return (SchemaContainer) _containers.get(namespace);
    }

    private void addContainer(String namespace) {
        SchemaContainer c = new SchemaContainer(namespace);
        c.setTypeSystem(this);
        _containers.put(namespace, c);
    }

    private SchemaContainer getContainerNonNull(String namespace) {
        SchemaContainer result = getContainer(namespace);
        if (result == null) {
            addContainer(namespace);
            result = getContainer(namespace);
        }
        return result;
    }

    // Only called during init
    private void buildContainers(List redefTypeNames, List redefModelGroupNames, List redefAttributeGroupNames) {
        // This method walks the reference maps and copies said references
        // into the appropriate container
        for (Iterator it = _globalElements.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addGlobalElement((SchemaGlobalElement.Ref) entry.getValue());
        }
        for (Iterator it = _globalAttributes.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addGlobalAttribute((SchemaGlobalAttribute.Ref) entry.getValue());
        }
        for (Iterator it = _modelGroups.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addModelGroup((SchemaModelGroup.Ref) entry.getValue());
        }
        for (Iterator it = _attributeGroups.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addAttributeGroup((SchemaAttributeGroup.Ref) entry.getValue());
        }
        for (Iterator it = _identityConstraints.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addIdentityConstraint((SchemaIdentityConstraint.Ref) entry.getValue());
        }
        for (Iterator it = _globalTypes.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addGlobalType((SchemaType.Ref) entry.getValue());
        }
        for (Iterator it = _documentTypes.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addDocumentType((SchemaType.Ref) entry.getValue());
        }
        for (Iterator it = _attributeTypes.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String ns = ((QName) entry.getKey()).getNamespaceURI();
            getContainerNonNull(ns).addAttributeType((SchemaType.Ref) entry.getValue());
        }
        // Some earlier .xsb versions don't have records for redefinitions
        if (_redefinedGlobalTypes != null && _redefinedModelGroups != null &&
            _redefinedAttributeGroups != null) {
            assert _redefinedGlobalTypes.size() == redefTypeNames.size();
            for (Iterator it = _redefinedGlobalTypes.iterator(), itname = redefTypeNames.iterator(); it.hasNext(); ) {
                String ns = ((QName) itname.next()).getNamespaceURI();
                getContainerNonNull(ns).addRedefinedType((SchemaType.Ref) it.next());
            }
            for (Iterator it = _redefinedModelGroups.iterator(), itname = redefModelGroupNames.iterator(); it.hasNext(); ) {
                String ns = ((QName) itname.next()).getNamespaceURI();
                getContainerNonNull(ns).addRedefinedModelGroup((SchemaModelGroup.Ref) it.next());
            }
            for (Iterator it = _redefinedAttributeGroups.iterator(), itname = redefAttributeGroupNames.iterator(); it.hasNext(); ) {
                String ns = ((QName) itname.next()).getNamespaceURI();
                getContainerNonNull(ns).addRedefinedAttributeGroup((SchemaAttributeGroup.Ref) it.next());
            }
        }
        // Some earlier .xsb versions don't have records for annotations
        if (_annotations != null) {
            for (Iterator it = _annotations.iterator(); it.hasNext(); ) {
                SchemaAnnotation ann = (SchemaAnnotation) it.next();
                // BUGBUG(radup)
                getContainerNonNull("").addAnnotation(ann);
            }
        }
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            ((SchemaContainer) it.next()).setImmutable();
        }
    }

    /**
     * This is the crux of the container work and role.
     * It makes a sweep over all containers and fixes each container's
     * typesystem to point to this typesystem.
     * Because SchemaComponents have a link to their containers, this has as
     * effect all components now indirectly pointing to this typesystem
     * even though they (as well as the typesystem itself) are immutable.
     */
    private void fixupContainers() {
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            SchemaContainer container = (SchemaContainer) it.next();
            container.setTypeSystem(this);
            container.setImmutable();
        }
    }

    private void assertContainersSynchronized() {
        boolean assertEnabled = false;
        // This code basically checks whether asserts are enabled so we don't do
        // all the work if they arent
        assert assertEnabled = true;
        if (!assertEnabled) {
            return;
        }
        // global elements
        Map temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalElements().toArray(new SchemaComponent[0])));
        }
        assert _globalElements.equals(temp);
        // global attributes
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalAttributes().toArray(new SchemaComponent[0])));
        }
        assert _globalAttributes.equals(temp);
        // model groups
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).modelGroups().toArray(new SchemaComponent[0])));
        }
        assert _modelGroups.equals(temp);
        // redefined model groups
        Set temp2 = new HashSet();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedModelGroups().toArray(new SchemaComponent[0])));
        }
        assert new HashSet(_redefinedModelGroups).equals(temp2);
        // attribute groups
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).attributeGroups().toArray(new SchemaComponent[0])));
        }
        assert _attributeGroups.equals(temp);
        // redefined attribute groups
        temp2 = new HashSet();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedAttributeGroups().toArray(new SchemaComponent[0])));
        }
        assert new HashSet(_redefinedAttributeGroups).equals(temp2);
        // global types
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalTypes().toArray(new SchemaComponent[0])));
        }
        assert _globalTypes.equals(temp);
        // redefined global types
        temp2 = new HashSet();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedGlobalTypes().toArray(new SchemaComponent[0])));
        }
        assert new HashSet(_redefinedGlobalTypes).equals(temp2);
        // document types
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildDocumentMap((SchemaType[]) ((SchemaContainer) it.next()).documentTypes().toArray(new SchemaType[0])));
        }
        assert _documentTypes.equals(temp);
        // attribute types
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildAttributeTypeMap((SchemaType[]) ((SchemaContainer) it.next()).attributeTypes().toArray(new SchemaType[0])));
        }
        assert _attributeTypes.equals(temp);
        // identity constraints
        temp = new HashMap();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).identityConstraints().toArray(new SchemaComponent[0])));
        }
        assert _identityConstraints.equals(temp);
        // annotations
        temp2 = new HashSet();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp2.addAll(((SchemaContainer) it.next()).annotations());
        }
        assert new HashSet(_annotations).equals(temp2);
        // namespaces
        temp2 = new HashSet();
        for (Iterator it = _containers.values().iterator(); it.hasNext(); ) {
            temp2.add(((SchemaContainer) it.next()).getNamespace());
        }
        assert _namespaces.equals(temp2);
    }

    private static Random _random;
    private static byte[] _mask = new byte[128 / 8];

    /**
     * Fun, fun.  Produce 128 bits of uniqueness randomly.
     * We used to use SecureRandom, but now we don't because SecureRandom
     * hits the filesystem and hangs us on a filesystem lock.  It also eats
     * a thread and other expensive resources.. :-).
     * <p>
     * We don't really care that non-secure Random() can only do 48 bits of
     * randomness, since we're certainly not going to be called more than 2^48
     * times within our process lifetime.
     * <p>
     * Our real concern is that by seeding Random() with the current
     * time, two users will end up with the same bits if they start a
     * schema compilation within the same millisecond.  That makes the
     * probability of collision in the real world slightly too high.
     * We're going to have millions of users, remember?  With a million
     * users, and one-compilation-per-day each, we'd see a collision every
     * few months.
     * <p>
     * So we'll just xor the results of random with our few extra
     * bits of information computed below to help reduce the probability
     * of collision by a few decimal places.  To collide, you will have had
     * to have the same amount of free memory, the same user name, timezone,
     * and country, the same current directory, the same java classpath,
     * the same operating system and jvm version, and the same choices of
     * identity hashcodes for a few objects. And be started within the same
     * millisecond. Or you can collide if you have a cosmic 128-bit mathematical
     * coincidence. No worries.
     */
    private static synchronized void nextBytes(byte[] result) {
        if (_random == null) {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                DataOutputStream daos = new DataOutputStream(baos);

                // at least 10 bits of unqieueness, right?  Maybe even 50 or 60.
                daos.writeInt(System.identityHashCode(SchemaTypeSystemImpl.class));
                String[] props = new String[]{"user.name", "user.dir", "user.timezone", "user.country", "java.class.path", "java.home", "java.vendor", "java.version", "os.version"};
                for (int i = 0; i < props.length; i++) {
                    String prop = SystemProperties.getProperty(props[i]);
                    if (prop != null) {
                        daos.writeUTF(prop);
                        daos.writeInt(System.identityHashCode(prop));
                    }
                }
                daos.writeLong(Runtime.getRuntime().freeMemory());
                daos.close();
                byte[] bytes = baos.toByteArray();
                for (int i = 0; i < bytes.length; i++) {
                    int j = i % _mask.length;
                    _mask[j] *= 21;
                    _mask[j] += i;
                }
            } catch (IOException e) {
                XBeanDebug.logException(e);
            }

            _random = new Random(System.currentTimeMillis());
        }
        _random.nextBytes(result);
        for (int i = 0; i < result.length; i++) {
            int j = i & _mask.length;
            result[i] ^= _mask[j];
        }
    }

    public SchemaTypeSystemImpl(String nameForSystem) {
        // if we have no name, select a random one
        if (nameForSystem == null) {
            // get 128 random bits (that'll be 32 hex digits)
            byte[] bytes = new byte[128 / 8];
            nextBytes(bytes);
            nameForSystem = "s" + new String(HexBin.encode(bytes), StandardCharsets.ISO_8859_1);
        }

        _name = SchemaTypeSystemImpl.METADATA_PACKAGE_GEN.replace('/', '.') + ".system." + nameForSystem;
        _basePackage = nameToPathString(_name);
        _classloader = null;
    }

    public void loadFromBuilder(SchemaGlobalElement[] globalElements,
                                SchemaGlobalAttribute[] globalAttributes,
                                SchemaType[] globalTypes,
                                SchemaType[] documentTypes,
                                SchemaType[] attributeTypes) {
        assert (_classloader == null);
        _localHandles = new HandlePool();
        _globalElements = buildComponentRefMap(globalElements);
        _globalAttributes = buildComponentRefMap(globalAttributes);
        _globalTypes = buildComponentRefMap(globalTypes);
        _documentTypes = buildDocumentMap(documentTypes);
        _attributeTypes = buildAttributeTypeMap(attributeTypes);
        _typeRefsByClassname = buildTypeRefsByClassname();
        buildContainers(Collections.EMPTY_LIST, Collections.EMPTY_LIST,
            Collections.EMPTY_LIST);
        _namespaces = new HashSet();
    }

    public void loadFromStscState(StscState state) {
        assert (_classloader == null);
        _localHandles = new HandlePool();
        _globalElements = buildComponentRefMap(state.globalElements());
        _globalAttributes = buildComponentRefMap(state.globalAttributes());
        _modelGroups = buildComponentRefMap(state.modelGroups());
        _redefinedModelGroups = buildComponentRefList(state.redefinedModelGroups());
        _attributeGroups = buildComponentRefMap(state.attributeGroups());
        _redefinedAttributeGroups = buildComponentRefList(state.redefinedAttributeGroups());
        _globalTypes = buildComponentRefMap(state.globalTypes());
        _redefinedGlobalTypes = buildComponentRefList(state.redefinedGlobalTypes());
        _documentTypes = buildDocumentMap(state.documentTypes());
        _attributeTypes = buildAttributeTypeMap(state.attributeTypes());
        _typeRefsByClassname = buildTypeRefsByClassname(state.typesByClassname());
        _identityConstraints = buildComponentRefMap(state.idConstraints());
        _annotations = state.annotations();
        _namespaces = new HashSet(Arrays.asList(state.getNamespaces()));
        _containers = state.getContainerMap();
        fixupContainers();
        // Checks that data in the containers matches the lookup maps
        assertContainersSynchronized();
        setDependencies(state.getDependencies());
    }

    final SchemaTypeSystemImpl getTypeSystem() {
        return this;
    }

    void setDependencies(SchemaDependencies deps) {
        _deps = deps;
    }

    SchemaDependencies getDependencies() {
        return _deps;
    }

    // EXPERIMENTAL
    public boolean isIncomplete() {
        return _incomplete;
    }

    // EXPERIMENTAL
    void setIncomplete(boolean incomplete) {
        _incomplete = incomplete;
    }

    static class StringPool {
        private List intsToStrings = new ArrayList();
        private Map stringsToInts = new HashMap();
        private String _handle;
        private String _name;

        /**
         * Constructs an empty StringPool to be filled with strings.
         */
        StringPool(String handle, String name) {
            _handle = handle;
            _name = name;
            intsToStrings.add(null);
        }

        int codeForString(String str) {
            if (str == null) {
                return 0;
            }
            Integer result = (Integer) stringsToInts.get(str);
            if (result == null) {
                result = new Integer(intsToStrings.size());
                intsToStrings.add(str);
                stringsToInts.put(str, result);
            }
            return result.intValue();
        }

        String stringForCode(int code) {
            if (code == 0) {
                return null;
            }
            return (String) intsToStrings.get(code);
        }

        void writeTo(DataOutputStream output) {
            if (intsToStrings.size() >= MAX_UNSIGNED_SHORT) {
                throw new SchemaTypeLoaderException("Too many strings (" + intsToStrings.size() + ")", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
            }

            try {
                output.writeShort(intsToStrings.size());
                Iterator i = intsToStrings.iterator();
                for (i.next(); i.hasNext(); ) {
                    String str = (String) i.next();
                    output.writeUTF(str);
                }
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        void readFrom(DataInputStream input) {
            if (intsToStrings.size() != 1 || stringsToInts.size() != 0) {
                throw new IllegalStateException();
            }

            try {
                int size = input.readUnsignedShort();
                for (int i = 1; i < size; i++) {
                    String str = input.readUTF().intern();
                    int code = codeForString(str);
                    if (code != i) {
                        throw new IllegalStateException();
                    }
                }
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage() == null ? e.getMessage() : "IO Exception", _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }
    }

    class HandlePool {
        private Map _handlesToRefs = new LinkedHashMap();
        private Map _componentsToHandles = new LinkedHashMap(); // populated on write
        private boolean _started;

        /**
         * Constructs an empty HandlePool to be populated.
         */
        HandlePool() {
        }

        private String addUniqueHandle(SchemaComponent obj, String base) {
            base = base.toLowerCase();  // we lowercase handles because of case-insensitive Windows filenames!!!
            String handle = base;
            for (int index = 2; _handlesToRefs.containsKey(handle); index++) {
                handle = base + index;
            }
            _handlesToRefs.put(handle, obj.getComponentRef());
            _componentsToHandles.put(obj, handle);
            return handle;
        }

        String handleForComponent(SchemaComponent comp) {
            if (comp == null) {
                return null;
            }
            if (comp.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            if (comp instanceof SchemaType) {
                return handleForType((SchemaType) comp);
            }
            if (comp instanceof SchemaGlobalElement) {
                return handleForElement((SchemaGlobalElement) comp);
            }
            if (comp instanceof SchemaGlobalAttribute) {
                return handleForAttribute((SchemaGlobalAttribute) comp);
            }
            if (comp instanceof SchemaModelGroup) {
                return handleForModelGroup((SchemaModelGroup) comp);
            }
            if (comp instanceof SchemaAttributeGroup) {
                return handleForAttributeGroup((SchemaAttributeGroup) comp);
            }
            if (comp instanceof SchemaIdentityConstraint) {
                return handleForIdentityConstraint((SchemaIdentityConstraint) comp);
            }
            throw new IllegalStateException("Component type cannot have a handle");
        }

        String handleForElement(SchemaGlobalElement element) {
            if (element == null) {
                return null;
            }
            if (element.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(element);
            if (handle == null) {
                handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element");
            }
            return handle;
        }

        String handleForAttribute(SchemaGlobalAttribute attribute) {
            if (attribute == null) {
                return null;
            }
            if (attribute.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(attribute);
            if (handle == null) {
                handle = addUniqueHandle(attribute, NameUtil.upperCamelCase(attribute.getName().getLocalPart()) + "Attribute");
            }
            return handle;
        }

        String handleForModelGroup(SchemaModelGroup group) {
            if (group == null) {
                return null;
            }
            if (group.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(group);
            if (handle == null) {
                handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "ModelGroup");
            }
            return handle;
        }

        String handleForAttributeGroup(SchemaAttributeGroup group) {
            if (group == null) {
                return null;
            }
            if (group.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(group);
            if (handle == null) {
                handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "AttributeGroup");
            }
            return handle;
        }

        String handleForIdentityConstraint(SchemaIdentityConstraint idc) {
            if (idc == null) {
                return null;
            }
            if (idc.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(idc);
            if (handle == null) {
                handle = addUniqueHandle(idc, NameUtil.upperCamelCase(idc.getName().getLocalPart()) + "IdentityConstraint");
            }
            return handle;
        }

        String handleForType(SchemaType type) {
            if (type == null) {
                return null;
            }
            if (type.getTypeSystem() != getTypeSystem()) {
                throw new IllegalArgumentException("Cannot supply handles for types from another type system");
            }
            String handle = (String) _componentsToHandles.get(type);
            if (handle == null) {
                QName name = type.getName();
                String suffix = "";
                if (name == null) {
                    if (type.isDocumentType()) {
                        name = type.getDocumentElementName();
                        suffix = "Doc";
                    } else if (type.isAttributeType()) {
                        name = type.getAttributeTypeAttributeName();
                        suffix = "AttrType";
                    } else if (type.getContainerField() != null) {
                        name = type.getContainerField().getName();
                        suffix = type.getContainerField().isAttribute() ? "Attr" : "Elem";
                    }
                }

                String baseName;
                String uniq = Integer.toHexString(type.toString().hashCode() | 0x80000000).substring(4).toUpperCase();
                if (name == null) {
                    baseName = "Anon" + uniq + "Type";
                } else {
                    baseName = NameUtil.upperCamelCase(name.getLocalPart()) + uniq + suffix + "Type";
                }

                handle = addUniqueHandle(type, baseName);
            }

            return handle;
        }

        SchemaComponent.Ref refForHandle(String handle) {
            if (handle == null) {
                return null;
            }

            return (SchemaComponent.Ref) _handlesToRefs.get(handle);
        }

        Set getAllHandles() {
            return _handlesToRefs.keySet();
        }

        void startWriteMode() {
            _started = true;
            _componentsToHandles = new LinkedHashMap();
            for (Iterator i = _handlesToRefs.keySet().iterator(); i.hasNext(); ) {
                String handle = (String) i.next();
//                System.err.println("Writing preexisting handle " + handle);
                SchemaComponent comp = ((SchemaComponent.Ref) _handlesToRefs.get(handle)).getComponent();
                _componentsToHandles.put(comp, handle);
            }
        }

    }

    private final String _name;
    private String _basePackage;

    // EXPERIMENTAL: recovery from compilation errors and partial type systems
    private boolean _incomplete = false;

    // classloader is available for sts's that were compiled and loaded, not dynamic ones
    private ClassLoader _classloader;

    // the loader for loading .xsb resources
    private ResourceLoader _resourceLoader;

    // the following is used to link references during load
    SchemaTypeLoader _linker;

    private HandlePool _localHandles;
    private Filer _filer;

    // top-level annotations
    private List _annotations;

    // container
    private Map _containers = new HashMap();
    // dependencies
    private SchemaDependencies _deps;

    private List _redefinedModelGroups;
    private List _redefinedAttributeGroups;
    private List _redefinedGlobalTypes;

    // actual type system data, map QNames -> SchemaComponent.Ref
    private Map _globalElements;
    private Map _globalAttributes;
    private Map _modelGroups;
    private Map _attributeGroups;
    private Map _globalTypes;
    private Map _documentTypes;
    private Map _attributeTypes;
    private Map _identityConstraints = Collections.EMPTY_MAP;
    private Map _typeRefsByClassname = new HashMap();
    private Set _namespaces;

    static private final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];
    static private final SchemaGlobalElement[] EMPTY_GE_ARRAY = new SchemaGlobalElement[0];
    static private final SchemaGlobalAttribute[] EMPTY_GA_ARRAY = new SchemaGlobalAttribute[0];
    static private final SchemaModelGroup[] EMPTY_MG_ARRAY = new SchemaModelGroup[0];
    static private final SchemaAttributeGroup[] EMPTY_AG_ARRAY = new SchemaAttributeGroup[0];
    static private final SchemaIdentityConstraint[] EMPTY_IC_ARRAY = new SchemaIdentityConstraint[0];
    static private final SchemaAnnotation[] EMPTY_ANN_ARRAY = new SchemaAnnotation[0];

    public void saveToDirectory(File classDir) {
        save(new FilerImpl(classDir, null, null, false, false));
    }

    public void save(Filer filer) {
        if (_incomplete) {
            throw new IllegalStateException("Incomplete SchemaTypeSystems cannot be saved.");
        }

        if (filer == null) {
            throw new IllegalArgumentException("filer must not be null");
        }
        _filer = filer;

        _localHandles.startWriteMode();
        saveTypesRecursively(globalTypes());
        saveTypesRecursively(documentTypes());
        saveTypesRecursively(attributeTypes());
        saveGlobalElements(globalElements());
        saveGlobalAttributes(globalAttributes());
        saveModelGroups(modelGroups());
        saveAttributeGroups(attributeGroups());
        saveIdentityConstraints(identityConstraints());

        saveTypesRecursively(redefinedGlobalTypes());
        saveModelGroups(redefinedModelGroups());
        saveAttributeGroups(redefinedAttributeGroups());

        saveIndex();
        savePointers();

        saveLoader();
    }

    void saveTypesRecursively(SchemaType[] types) {
        for (int i = 0; i < types.length; i++) {
            if (types[i].getTypeSystem() != getTypeSystem()) {
                continue;
            }
            saveType(types[i]);
            saveTypesRecursively(types[i].getAnonymousTypes());
        }
    }

    public void saveGlobalElements(SchemaGlobalElement[] elts) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        for (int i = 0; i < elts.length; i++) {
            saveGlobalElement(elts[i]);
        }
    }

    public void saveGlobalAttributes(SchemaGlobalAttribute[] attrs) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        for (int i = 0; i < attrs.length; i++) {
            saveGlobalAttribute(attrs[i]);
        }
    }

    public void saveModelGroups(SchemaModelGroup[] groups) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        for (int i = 0; i < groups.length; i++) {
            saveModelGroup(groups[i]);
        }
    }

    public void saveAttributeGroups(SchemaAttributeGroup[] groups) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        for (int i = 0; i < groups.length; i++) {
            saveAttributeGroup(groups[i]);
        }
    }

    public void saveIdentityConstraints(SchemaIdentityConstraint[] idcs) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        for (int i = 0; i < idcs.length; i++) {
            saveIdentityConstraint(idcs[i]);
        }
    }

    public void saveGlobalElement(SchemaGlobalElement elt) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        String handle = _localHandles.handleForElement(elt);
        XsbReader saver = new XsbReader(handle);
        saver.writeParticleData((SchemaParticle) elt);
        saver.writeString(elt.getSourceName());
        saver.writeRealHeader(handle, FILETYPE_SCHEMAELEMENT);
        saver.writeParticleData((SchemaParticle) elt);
        saver.writeString(elt.getSourceName());
        saver.writeEnd();
    }

    public void saveGlobalAttribute(SchemaGlobalAttribute attr) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        String handle = _localHandles.handleForAttribute(attr);
        XsbReader saver = new XsbReader(handle);
        saver.writeAttributeData(attr);
        saver.writeString(attr.getSourceName());
        saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTE);
        saver.writeAttributeData(attr);
        saver.writeString(attr.getSourceName());
        saver.writeEnd();
    }

    public void saveModelGroup(SchemaModelGroup grp) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        String handle = _localHandles.handleForModelGroup(grp);
        XsbReader saver = new XsbReader(handle);
        saver.writeModelGroupData(grp);
        saver.writeRealHeader(handle, FILETYPE_SCHEMAMODELGROUP);
        saver.writeModelGroupData(grp);
        saver.writeEnd();
    }

    public void saveAttributeGroup(SchemaAttributeGroup grp) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        String handle = _localHandles.handleForAttributeGroup(grp);
        XsbReader saver = new XsbReader(handle);
        saver.writeAttributeGroupData(grp);
        saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTEGROUP);
        saver.writeAttributeGroupData(grp);
        saver.writeEnd();
    }

    public void saveIdentityConstraint(SchemaIdentityConstraint idc) {
        if (_incomplete) {
            throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
        }
        String handle = _localHandles.handleForIdentityConstraint(idc);
        XsbReader saver = new XsbReader(handle);
        saver.writeIdConstraintData(idc);
        saver.writeRealHeader(handle, FILETYPE_SCHEMAIDENTITYCONSTRAINT);
        saver.writeIdConstraintData(idc);
        saver.writeEnd();
    }

    void saveType(SchemaType type) {
        String handle = _localHandles.handleForType(type);
        XsbReader saver = new XsbReader(handle);
        saver.writeTypeData(type);
        saver.writeRealHeader(handle, FILETYPE_SCHEMATYPE);
        saver.writeTypeData(type);
        saver.writeEnd();
    }

    public static String crackPointer(InputStream stream) {
        DataInputStream input = null;
        try {
            input = new DataInputStream(stream);

            int magic = input.readInt();
            if (magic != DATA_BABE) {
                return null;
            }

            int majorver = input.readShort();
            int minorver = input.readShort();

            if (majorver != MAJOR_VERSION) {
                return null;
            }

            if (minorver > MINOR_VERSION) {
                return null;
            }

            if (majorver > 2 || majorver == 2 && minorver >= 18) {
                input.readShort(); // release number present in atLeast(2, 18, 0)
            }

            int actualfiletype = input.readShort();
            if (actualfiletype != FILETYPE_SCHEMAPOINTER) {
                return null;
            }

            StringPool stringPool = new StringPool("pointer", "unk");
            stringPool.readFrom(input);

            return stringPool.stringForCode(input.readShort());
        } catch (IOException e) {
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private class XsbReader {
        DataInputStream _input;
        DataOutputStream _output;
        StringPool _stringPool;
        String _handle;
        private int _majorver;
        private int _minorver;
        private int _releaseno;
        int _actualfiletype;

        public XsbReader(String handle, int filetype) {
            String resourcename = _basePackage + handle + ".xsb";
            InputStream rawinput = getLoaderStream(resourcename);
            if (rawinput == null) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Could not locate compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NO_RESOURCE);
            }

            _input = new DataInputStream(rawinput);
            _handle = handle;

            int magic = readInt();
            if (magic != DATA_BABE) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", _name, handle, SchemaTypeLoaderException.WRONG_MAGIC_COOKIE);
            }

            _majorver = readShort();
            _minorver = readShort();

            if (_majorver != MAJOR_VERSION) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong major version - expecting " + MAJOR_VERSION + ", got " + _majorver, _name, handle, SchemaTypeLoaderException.WRONG_MAJOR_VERSION);
            }

            if (_minorver > MINOR_VERSION) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting up to " + MINOR_VERSION + ", got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
            }

            // Clip to 14 because we're not backward compatible with earlier
            // minor versions.  Remove this when upgrading to a new major
            // version

            if (_minorver < 14) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting at least 14, got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
            }

            if (atLeast(2, 18, 0)) {
                _releaseno = readShort();
            }

            int actualfiletype = readShort();
            if (actualfiletype != filetype && filetype != 0xFFFF) {
                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, _name, handle, SchemaTypeLoaderException.WRONG_FILE_TYPE);
            }

            _stringPool = new StringPool(_handle, _name);
            _stringPool.readFrom(_input);

            _actualfiletype = actualfiletype;
        }

        protected boolean atLeast(int majorver, int minorver, int releaseno) {
            if (_majorver > majorver) {
                return true;
            }
            if (_majorver < majorver) {
                return false;
            }
            if (_minorver > minorver) {
                return true;
            }
            if (_minorver < minorver) {
                return false;
            }
            return (_releaseno >= releaseno);
        }

        protected boolean atMost(int majorver, int minorver, int releaseno) {
            if (_majorver > majorver) {
                return false;
            }
            if (_majorver < majorver) {
                return true;
            }
            if (_minorver > minorver) {
                return false;
            }
            if (_minorver < minorver) {
                return true;
            }
            return (_releaseno <= releaseno);
        }

        int getActualFiletype() {
            return _actualfiletype;
        }

        XsbReader(String handle) {
            _handle = handle;
            _stringPool = new StringPool(_handle, _name);
        }

        void writeRealHeader(String handle, int filetype) {
            // hackeroo: if handle contains a "/" it's not relative.
            String resourcename;

            if (handle.indexOf('/') >= 0) {
                resourcename = handle + ".xsb";
            } else {
                resourcename = _basePackage + handle + ".xsb";
            }

            OutputStream rawoutput = getSaverStream(resourcename);
            if (rawoutput == null) {
                throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NOT_WRITEABLE);
            }

            _output = new DataOutputStream(rawoutput);
            _handle = handle;

            writeInt(DATA_BABE);
            writeShort(MAJOR_VERSION);
            writeShort(MINOR_VERSION);
            writeShort(RELEASE_NUMBER);
            writeShort(filetype);

            _stringPool.writeTo(_output);
        }

        void readEnd() {
            try {
                if (_input != null) {
                    _input.close();
                }
            } catch (IOException e) {
                // oh, well.
            }
            _input = null;
            _stringPool = null;
            _handle = null;
        }

        void writeEnd() {
            try {
                if (_output != null) {
                    _output.flush();
                    _output.close();
                }
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
            _output = null;
            _stringPool = null;
            _handle = null;
        }

        int fileTypeFromComponentType(int componentType) {
            switch (componentType) {
                case SchemaComponent.TYPE:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMATYPE;
                case SchemaComponent.ELEMENT:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAELEMENT;
                case SchemaComponent.ATTRIBUTE:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTE;
                case SchemaComponent.MODEL_GROUP:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAMODELGROUP;
                case SchemaComponent.ATTRIBUTE_GROUP:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTEGROUP;
                case SchemaComponent.IDENTITY_CONSTRAINT:
                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAIDENTITYCONSTRAINT;
                default:
                    throw new IllegalStateException("Unexpected component type");
            }
        }

        void writeIndexData() {
            // has a handle pool (count, handle/type, handle/type...)
            writeHandlePool(_localHandles);

            // then a qname map of global elements (count, qname/handle, qname/handle...)
            writeQNameMap(globalElements());

            // qname map of global attributes
            writeQNameMap(globalAttributes());

            // qname map of model groups
            writeQNameMap(modelGroups());

            // qname map of attribute groups
            writeQNameMap(attributeGroups());

            // qname map of identity constraints
            writeQNameMap(identityConstraints());

            // qname map of global types
            writeQNameMap(globalTypes());

            // qname map of document types, by the qname of the contained element
            writeDocumentTypeMap(documentTypes());

            // qname map of attribute types, by the qname of the contained attribute
            writeAttributeTypeMap(attributeTypes());

            // all the types by classname
            writeClassnameMap(_typeRefsByClassname);

            // all the namespaces
            writeNamespaces(_namespaces);

            // VERSION 2.15 and newer below
            writeQNameMap(redefinedGlobalTypes());
            writeQNameMap(redefinedModelGroups());
            writeQNameMap(redefinedAttributeGroups());
            writeAnnotations(annotations());
        }

        void writeHandlePool(HandlePool pool) {
            writeShort(pool._componentsToHandles.size());
            for (Iterator i = pool._componentsToHandles.keySet().iterator(); i.hasNext(); ) {
                SchemaComponent comp = (SchemaComponent) i.next();
                String handle = (String) pool._componentsToHandles.get(comp);
                int code = fileTypeFromComponentType(comp.getComponentType());
                writeString(handle);
                writeShort(code);
            }
        }

        void readHandlePool(HandlePool pool) {
            if (pool._handlesToRefs.size() != 0 || pool._started) {
                throw new IllegalStateException("Nonempty handle set before read");
            }

            int size = readShort();
            for (int i = 0; i < size; i++) {
                String handle = readString();
                int code = readShort();
                Object result;
                switch (code) {
                    case FILETYPE_SCHEMATYPE:
                        result = new SchemaType.Ref(getTypeSystem(), handle);
                        break;
                    case FILETYPE_SCHEMAELEMENT:
                        result = new SchemaGlobalElement.Ref(getTypeSystem(), handle);
                        break;
                    case FILETYPE_SCHEMAATTRIBUTE:
                        result = new SchemaGlobalAttribute.Ref(getTypeSystem(), handle);
                        break;
                    case FILETYPE_SCHEMAMODELGROUP:
                        result = new SchemaModelGroup.Ref(getTypeSystem(), handle);
                        break;
                    case FILETYPE_SCHEMAATTRIBUTEGROUP:
                        result = new SchemaAttributeGroup.Ref(getTypeSystem(), handle);
                        break;
                    case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
                        result = new SchemaIdentityConstraint.Ref(getTypeSystem(), handle);
                        break;
                    default:
                        throw new SchemaTypeLoaderException("Schema index has an unrecognized entry of type " + code, _name, handle, SchemaTypeLoaderException.UNRECOGNIZED_INDEX_ENTRY);
                }
                pool._handlesToRefs.put(handle, result);
            }
        }

        int readShort() {
            try {
                return _input.readUnsignedShort();
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        void writeShort(int s) {
            if (s >= MAX_UNSIGNED_SHORT || s < -1) {
                throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit unsigned short.", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
            }
            if (_output != null) {
                try {
                    _output.writeShort(s);
                } catch (IOException e) {
                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
                }
            }
        }

        int readInt() {
            try {
                return _input.readInt();
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        void writeInt(int i) {
            if (_output != null) {
                try {
                    _output.writeInt(i);
                } catch (IOException e) {
                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
                }
            }
        }

        String readString() {
            return _stringPool.stringForCode(readShort());
        }

        void writeString(String str) {
            int code = _stringPool.codeForString(str);
            writeShort(code);
        }

        QName readQName() {
            String namespace = readString();
            String localname = readString();
            if (localname == null) {
                return null;
            }
            return new QName(namespace, localname);
        }

        void writeQName(QName qname) {
            if (qname == null) {
                writeString(null);
                writeString(null);
                return;
            }
            writeString(qname.getNamespaceURI());
            writeString(qname.getLocalPart());
        }

        SOAPArrayType readSOAPArrayType() {
            QName qName = readQName();
            String dimensions = readString();
            if (qName == null) {
                return null;
            }
            return new SOAPArrayType(qName, dimensions);
        }

        void writeSOAPArrayType(SOAPArrayType arrayType) {
            if (arrayType == null) {
                writeQName(null);
                writeString(null);
            } else {
                writeQName(arrayType.getQName());
                writeString(arrayType.soap11DimensionString());
            }
        }

        void writeAnnotation(SchemaAnnotation a) {
            // Write attributes
            if (a == null) {
                writeInt(-1);
                return;
            }
            SchemaAnnotation.Attribute[] attributes = a.getAttributes();
            writeInt(attributes.length);
            for (int i = 0; i < attributes.length; i++) {
                QName name = attributes[i].getName();
                String value = attributes[i].getValue();
                String valueURI = attributes[i].getValueUri();
                writeQName(name);
                writeString(value);
                writeString(valueURI);
            }

            // Write documentation items
            XmlObject[] documentationItems = a.getUserInformation();
            writeInt(documentationItems.length);
            XmlOptions opt = new XmlOptions().setSaveOuter().
                setSaveAggressiveNamespaces();
            for (int i = 0; i < documentationItems.length; i++) {
                XmlObject doc = documentationItems[i];
                writeString(doc.xmlText(opt));
            }

            // Write application info items
            XmlObject[] appInfoItems = a.getApplicationInformation();
            writeInt(appInfoItems.length);
            for (int i = 0; i < appInfoItems.length; i++) {
                XmlObject doc = appInfoItems[i];
                writeString(doc.xmlText(opt));
            }
        }

        SchemaAnnotation readAnnotation(SchemaContainer c) {
            if (!atLeast(2, 19, 0)) {
                return null; // no annotations for this version of the file
            }
            // Read attributes
            int n = readInt();
            if (n == -1) {
                return null;
            }
            SchemaAnnotation.Attribute[] attributes =
                new SchemaAnnotation.Attribute[n];
            for (int i = 0; i < n; i++) {
                QName name = readQName();
                String value = readString();
                String valueUri = null;
                if (atLeast(2, 24, 0)) {
                    valueUri = readString();
                }
                attributes[i] = new SchemaAnnotationImpl.AttributeImpl(name, value, valueUri);
            }

            // Read documentation items
            n = readInt();
            String[] docStrings = new String[n];
            for (int i = 0; i < n; i++) {
                docStrings[i] = readString();
            }

            // Read application info items
            n = readInt();
            String[] appInfoStrings = new String[n];
            for (int i = 0; i < n; i++) {
                appInfoStrings[i] = readString();
            }

            return new SchemaAnnotationImpl(c, appInfoStrings,
                docStrings, attributes);
        }

        void writeAnnotations(SchemaAnnotation[] anns) {
            writeInt(anns.length);
            for (int i = 0; i < anns.length; i++) {
                writeAnnotation(anns[i]);
            }
        }

        List readAnnotations() {
            int n = readInt();
            List result = new ArrayList(n);
            // BUGBUG(radup)
            SchemaContainer container = getContainerNonNull("");
            for (int i = 0; i < n; i++) {
                result.add(readAnnotation(container));
            }
            return result;
        }

        SchemaComponent.Ref readHandle() {
            String handle = readString();
            if (handle == null) {
                return null;
            }

            if (handle.charAt(0) != '_') {
                return _localHandles.refForHandle(handle);
            }

            switch (handle.charAt(2)) {
                case 'I': // _BI_ - built-in schema type system
                    SchemaType st = (SchemaType) BuiltinSchemaTypeSystem.get().resolveHandle(handle);
                    if (st != null) {
                        return st.getRef();
                    }
                    st = (SchemaType) XQuerySchemaTypeSystem.get().resolveHandle(handle);
                    return st.getRef();
                case 'T': // _XT_ - external type
                    return _linker.findTypeRef(QNameHelper.forPretty(handle, 4));
                case 'E': // _XE_ - external element
                    return _linker.findElementRef(QNameHelper.forPretty(handle, 4));
                case 'A': // _XA_ - external attribute
                    return _linker.findAttributeRef(QNameHelper.forPretty(handle, 4));
                case 'M': // _XM_ - external model group
                    return _linker.findModelGroupRef(QNameHelper.forPretty(handle, 4));
                case 'N': // _XN_ - external attribute group
                    return _linker.findAttributeGroupRef(QNameHelper.forPretty(handle, 4));
                case 'D': // _XD_ - external identity constraint
                    return _linker.findIdentityConstraintRef(QNameHelper.forPretty(handle, 4));
                case 'R': // _XR_ - external ref to attribute's type
                    // deprecated: replaced by _XY_
                    SchemaGlobalAttribute attr = _linker.findAttribute(QNameHelper.forPretty(handle, 4));
                    if (attr == null) {
                        throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
                    }
                    return attr.getType().getRef();
                case 'S': // _XS_ - external ref to element's type
                    // deprecated: replaced by _XY_
                    SchemaGlobalElement elem = _linker.findElement(QNameHelper.forPretty(handle, 4));
                    if (elem == null) {
                        throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
                    }
                    return elem.getType().getRef();
                case 'O': // _XO_ - external ref to document type
                    return _linker.findDocumentTypeRef(QNameHelper.forPretty(handle, 4));
                case 'Y': // _XY_ - external ref to any possible type
                    SchemaType type = _linker.typeForSignature(handle.substring(4));
                    if (type == null) {
                        throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
                    }
                    return type.getRef();
                default:
                    throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
            }
        }

        void writeHandle(SchemaComponent comp) {
            if (comp == null || comp.getTypeSystem() == getTypeSystem()) {
                writeString(_localHandles.handleForComponent(comp));
                return;
            }

            switch (comp.getComponentType()) {
                case SchemaComponent.ATTRIBUTE:
                    writeString("_XA_" + QNameHelper.pretty(comp.getName()));
                    return;
                case SchemaComponent.MODEL_GROUP:
                    writeString("_XM_" + QNameHelper.pretty(comp.getName()));
                    return;
                case SchemaComponent.ATTRIBUTE_GROUP:
                    writeString("_XN_" + QNameHelper.pretty(comp.getName()));
                    return;
                case SchemaComponent.ELEMENT:
                    writeString("_XE_" + QNameHelper.pretty(comp.getName()));
                    return;
                case SchemaComponent.IDENTITY_CONSTRAINT:
                    writeString("_XD_" + QNameHelper.pretty(comp.getName()));
                    return;
                case SchemaComponent.TYPE:
                    SchemaType type = (SchemaType) comp;
                    if (type.isBuiltinType()) {
                        writeString("_BI_" + type.getName().getLocalPart());
                        return;
                    }

                    // fix for CR120759 - added output of types _XR_ & _XS_
                    // when an attribute (_XR_) or element (_XS_) declaration
                    // uses ref to refer to an attribute or element in another
                    // schema and the type of that attribute or element
                    // is an anonymous (local) type
                    // kkrouse 02/1/2005: _XR_ and _XS_ refs are replaced by _XY_
                    if (type.getName() != null) {
                        writeString("_XT_" + QNameHelper.pretty(type.getName()));
                    } else if (type.isDocumentType()) {
                        // Substitution groups will create document types that
                        // extend from other document types, possibly in
                        // different jars
                        writeString("_XO_" + QNameHelper.pretty(type.getDocumentElementName()));
                    } else {
                        // fix for XMLBEANS-105:
                        // save out the external type reference using the type's signature.
                        writeString("_XY_" + type.toString());
                    }

                    return;

                default:
                    assert (false);
                    throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
            }
        }

        SchemaType.Ref readTypeRef() {
            return (SchemaType.Ref) readHandle();
        }

        void writeType(SchemaType type) {
            writeHandle(type);
        }

        Map readQNameRefMap() {
            Map result = new HashMap();
            int size = readShort();
            for (int i = 0; i < size; i++) {
                QName name = readQName();
                SchemaComponent.Ref obj = readHandle();
                result.put(name, obj);
            }
            return result;
        }

        List readQNameRefMapAsList(List names) {
            int size = readShort();
            List result = new ArrayList(size);
            for (int i = 0; i < size; i++) {
                QName name = readQName();
                SchemaComponent.Ref obj = readHandle();
                result.add(obj);
                names.add(name);
            }
            return result;
        }

        void writeQNameMap(SchemaComponent[] components) {
            writeShort(components.length);
            for (int i = 0; i < components.length; i++) {
                writeQName(components[i].getName());
                writeHandle(components[i]);
            }
        }

        void writeDocumentTypeMap(SchemaType[] doctypes) {
            writeShort(doctypes.length);
            for (int i = 0; i < doctypes.length; i++) {
                writeQName(doctypes[i].getDocumentElementName());
                writeHandle(doctypes[i]);
            }
        }

        void writeAttributeTypeMap(SchemaType[] attrtypes) {
            writeShort(attrtypes.length);
            for (int i = 0; i < attrtypes.length; i++) {
                writeQName(attrtypes[i].getAttributeTypeAttributeName());
                writeHandle(attrtypes[i]);
            }
        }

        SchemaType.Ref[] readTypeRefArray() {
            int size = readShort();
            SchemaType.Ref[] result = new SchemaType.Ref[size];
            for (int i = 0; i < size; i++) {
                result[i] = readTypeRef();
            }
            return result;
        }

        void writeTypeArray(SchemaType[] array) {
            writeShort(array.length);
            for (int i = 0; i < array.length; i++) {
                writeHandle(array[i]);
            }
        }

        Map readClassnameRefMap() {
            Map result = new HashMap();
            int size = readShort();
            for (int i = 0; i < size; i++) {
                String name = readString();
                SchemaComponent.Ref obj = readHandle();
                result.put(name, obj);
            }
            return result;
        }

        void writeClassnameMap(Map typesByClass) {
            writeShort(typesByClass.size());
            for (Iterator i = typesByClass.keySet().iterator(); i.hasNext(); ) {
                String className = (String) i.next();
                writeString(className);
                writeHandle(((SchemaType.Ref) typesByClass.get(className)).get());
            }
        }

        Set readNamespaces() {
            Set result = new HashSet();
            int size = readShort();
            for (int i = 0; i < size; i++) {
                String ns = readString();
                result.add(ns);
            }
            return result;
        }

        void writeNamespaces(Set namespaces) {
            writeShort(namespaces.size());
            for (Iterator i = namespaces.iterator(); i.hasNext(); ) {
                String ns = (String) i.next();
                writeString(ns);
            }
        }

        OutputStream getSaverStream(String name) {
            try {
                return _filer.createBinaryFile(name);
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        InputStream getLoaderStream(String resourcename) {
            return _resourceLoader.getResourceAsStream(resourcename);
        }

        void checkContainerNotNull(SchemaContainer container, QName name) {
            if (container == null) {
                throw new LinkageError("Loading of resource " + _name + '.' + _handle +
                                       "failed, information from " + _name + ".index.xsb is " +
                                       " out of sync (or conflicting index files found)");
            }
        }

        /**
         * Finishes loading an element after the header has already been loaded.
         */
        public SchemaGlobalElement finishLoadingElement() {
            String handle = null;
            try {
                int particleType = readShort();
                if (particleType != SchemaParticle.ELEMENT) {
                    throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
                }
                int particleFlags = readShort();
                BigInteger minOccurs = readBigInteger();
                BigInteger maxOccurs = readBigInteger();
                QNameSet transitionRules = readQNameSet();
                QName name = readQName();
                SchemaContainer container = getContainer(name.getNamespaceURI());
                checkContainerNotNull(container, name);
                SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(container);
                impl.setParticleType(particleType);
                impl.setMinOccurs(minOccurs);
                impl.setMaxOccurs(maxOccurs);
                impl.setTransitionRules(transitionRules,
                    (particleFlags & FLAG_PART_SKIPPABLE) != 0);
                impl.setNameAndTypeRef(name, readTypeRef());
                impl.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
                if (atLeast(2, 16, 0)) {
                    impl.setDefaultValue(readXmlValueObject());
                }
                impl.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
                impl.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
                    (particleFlags & FLAG_PART_BLOCKREST) != 0,
                    (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
                impl.setWsdlArrayType(readSOAPArrayType());
                impl.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
                impl.setAnnotation(readAnnotation(container));
                impl.setFinal(
                    (particleFlags & FLAG_PART_FINALEXT) != 0,
                    (particleFlags & FLAG_PART_FINALREST) != 0);

                if (atLeast(2, 17, 0)) {
                    impl.setSubstitutionGroup((SchemaGlobalElement.Ref) readHandle());
                }

                int substGroupCount = readShort();
                for (int i = 0; i < substGroupCount; i++) {
                    impl.addSubstitutionGroupMember(readQName());
                }
                SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];

                for (int i = 0; i < idcs.length; i++) {
                    idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
                }

                impl.setIdentityConstraints(idcs);
                impl.setFilename(readString());
                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        public SchemaGlobalAttribute finishLoadingAttribute() {
            try {
                QName name = readQName();
                SchemaContainer container = getContainer(name.getNamespaceURI());
                checkContainerNotNull(container, name);
                SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(container);
                loadAttribute(impl, name, container);
                impl.setFilename(readString());

                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        SchemaModelGroup finishLoadingModelGroup() {
            QName name = readQName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            checkContainerNotNull(container, name);
            SchemaModelGroupImpl impl = new SchemaModelGroupImpl(container);

            try {
                impl.init(name, readString(), readShort() == 1,
                    atLeast(2, 22, 0) ? readString() : null,
                    atLeast(2, 22, 0) ? readString() : null,
                    atLeast(2, 15, 0) ? readShort() == 1 : false,
                    GroupDocument.Factory.parse(readString()).getGroup(), readAnnotation(container), null);
                if (atLeast(2, 21, 0)) {
                    impl.setFilename(readString());
                }
                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        SchemaIdentityConstraint finishLoadingIdentityConstraint() {
            try {
                QName name = readQName();
                SchemaContainer container = getContainer(name.getNamespaceURI());
                checkContainerNotNull(container, name);
                SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(container);
                impl.setName(name);
                impl.setConstraintCategory(readShort());
                impl.setSelector(readString());
                impl.setAnnotation(readAnnotation(container));

                String[] fields = new String[readShort()];
                for (int i = 0; i < fields.length; i++) {
                    fields[i] = readString();
                }
                impl.setFields(fields);

                if (impl.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
                    impl.setReferencedKey((SchemaIdentityConstraint.Ref) readHandle());
                }

                int mapCount = readShort();
                Map nsMappings = new HashMap();
                for (int i = 0; i < mapCount; i++) {
                    String prefix = readString();
                    String uri = readString();
                    nsMappings.put(prefix, uri);
                }
                impl.setNSMap(nsMappings);

                if (atLeast(2, 21, 0)) {
                    impl.setFilename(readString());
                }

                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        SchemaAttributeGroup finishLoadingAttributeGroup() {
            QName name = readQName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            checkContainerNotNull(container, name);
            SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(container);

            try {
                impl.init(name, readString(), readShort() == 1,
                    atLeast(2, 22, 0) ? readString() : null,
                    atLeast(2, 15, 0) ? readShort() == 1 : false,
                    AttributeGroupDocument.Factory.parse(readString()).getAttributeGroup(),
                    readAnnotation(container), null);
                if (atLeast(2, 21, 0)) {
                    impl.setFilename(readString());
                }
                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        public SchemaType finishLoadingType() {
            try {
                SchemaContainer cNonNull = getContainerNonNull(""); //HACKHACK
                SchemaTypeImpl impl = new SchemaTypeImpl(cNonNull, true);
                impl.setName(readQName());
                impl.setOuterSchemaTypeRef(readTypeRef());
                impl.setBaseDepth(readShort());
                impl.setBaseTypeRef(readTypeRef());
                impl.setDerivationType(readShort());
                impl.setAnnotation(readAnnotation(null));

                switch (readShort()) {
                    case FIELD_GLOBAL:
                        impl.setContainerFieldRef(readHandle());
                        break;
                    case FIELD_LOCALATTR:
                        impl.setContainerFieldIndex((short) 1, readShort());
                        break;
                    case FIELD_LOCALELT:
                        impl.setContainerFieldIndex((short) 2, readShort());
                        break;
                }
                // TODO (radup) find the right solution here
                String jn = readString();
                impl.setFullJavaName(jn == null ? "" : jn);
                jn = readString();
                impl.setFullJavaImplName(jn == null ? "" : jn);

                impl.setAnonymousTypeRefs(readTypeRefArray());

                impl.setAnonymousUnionMemberOrdinal(readShort());

                int flags;
                flags = readInt();


                boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0);
                impl.setCompiled((flags & FLAG_COMPILED) != 0);
                impl.setDocumentType((flags & FLAG_DOCUMENT_TYPE) != 0);
                impl.setAttributeType((flags & FLAG_ATTRIBUTE_TYPE) != 0);
                impl.setSimpleType(!isComplexType);

                int complexVariety = SchemaType.NOT_COMPLEX_TYPE;
                if (isComplexType) {
                    impl.setAbstractFinal((flags & FLAG_ABSTRACT) != 0,
                        (flags & FLAG_FINAL_EXT) != 0,
                        (flags & FLAG_FINAL_REST) != 0,
                        (flags & FLAG_FINAL_LIST) != 0,
                        (flags & FLAG_FINAL_UNION) != 0);
                    impl.setBlock((flags & FLAG_BLOCK_EXT) != 0,
                        (flags & FLAG_BLOCK_REST) != 0);

                    impl.setOrderSensitive((flags & FLAG_ORDER_SENSITIVE) != 0);
                    complexVariety = readShort();
                    impl.setComplexTypeVariety(complexVariety);

                    if (atLeast(2, 23, 0)) {
                        impl.setContentBasedOnTypeRef(readTypeRef());
                    }

                    // Attribute Model Table
                    SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl();

                    int attrCount = readShort();
                    for (int i = 0; i < attrCount; i++) {
                        attrModel.addAttribute(readAttributeData());
                    }

                    attrModel.setWildcardSet(readQNameSet());
                    attrModel.setWildcardProcess(readShort());

                    // Attribute Property Table
                    Map attrProperties = new LinkedHashMap();
                    int attrPropCount = readShort();
                    for (int i = 0; i < attrPropCount; i++) {
                        SchemaProperty prop = readPropertyData();
                        if (!prop.isAttribute()) {
                            throw new SchemaTypeLoaderException("Attribute property " + i + " is not an attribute", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
                        }
                        attrProperties.put(prop.getName(), prop);
                    }

                    SchemaParticle contentModel = null;
                    Map elemProperties = null;
                    int isAll = 0;

                    if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT) {
                        // Content Model Tree
                        isAll = readShort();
                        SchemaParticle[] parts = readParticleArray();
                        if (parts.length == 1) {
                            contentModel = parts[0];
                        } else if (parts.length == 0) {
                            contentModel = null;
                        } else {
                            throw new SchemaTypeLoaderException("Content model not well-formed", _name, _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL);
                        }

                        // Element Property Table

                        elemProperties = new LinkedHashMap();
                        int elemPropCount = readShort();
                        for (int i = 0; i < elemPropCount; i++) {
                            SchemaProperty prop = readPropertyData();
                            if (prop.isAttribute()) {
                                throw new SchemaTypeLoaderException("Element property " + i + " is not an element", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
                            }
                            elemProperties.put(prop.getName(), prop);
                        }
                    }

                    impl.setContentModel(contentModel, attrModel, elemProperties, attrProperties, isAll == 1);
                    StscComplexTypeResolver.WildcardResult wcElt = StscComplexTypeResolver.summarizeEltWildcards(contentModel);
                    StscComplexTypeResolver.WildcardResult wcAttr = StscComplexTypeResolver.summarizeAttrWildcards(attrModel);
                    impl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards);
                }

                if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT) {
                    int simpleVariety = readShort();
                    impl.setSimpleTypeVariety(simpleVariety);

                    boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0);

                    impl.setOrdered((flags & FLAG_ORDERED) != 0 ? SchemaType.UNORDERED : ((flags & FLAG_TOTAL_ORDER) != 0 ? SchemaType.TOTAL_ORDER : SchemaType.PARTIAL_ORDER));
                    impl.setBounded((flags & FLAG_BOUNDED) != 0);
                    impl.setFinite((flags & FLAG_FINITE) != 0);
                    impl.setNumeric((flags & FLAG_NUMERIC) != 0);
                    impl.setUnionOfLists((flags & FLAG_UNION_OF_LISTS) != 0);
                    impl.setSimpleFinal((flags & FLAG_FINAL_REST) != 0,
                        (flags & FLAG_FINAL_LIST) != 0,
                        (flags & FLAG_FINAL_UNION) != 0);

                    XmlValueRef[] facets = new XmlValueRef[SchemaType.LAST_FACET + 1];
                    boolean[] fixedFacets = new boolean[SchemaType.LAST_FACET + 1];
                    int facetCount = readShort();
                    for (int i = 0; i < facetCount; i++) {
                        int facetCode = readShort();
                        facets[facetCode] = readXmlValueObject();
                        fixedFacets[facetCode] = (readShort() == 1);
                    }
                    impl.setBasicFacets(facets, fixedFacets);

                    impl.setWhiteSpaceRule(readShort());

                    impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0);

                    int patternCount = readShort();
                    org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = new org.apache.xmlbeans.impl.regex.RegularExpression[patternCount];
                    for (int i = 0; i < patternCount; i++) {
                        patterns[i] = new org.apache.xmlbeans.impl.regex.RegularExpression(readString(), "X");
                    }
                    impl.setPatterns(patterns);

                    int enumCount = readShort();
                    XmlValueRef[] enumValues = new XmlValueRef[enumCount];
                    for (int i = 0; i < enumCount; i++) {
                        enumValues[i] = readXmlValueObject();
                    }
                    impl.setEnumerationValues(enumCount == 0 ? null : enumValues);

                    impl.setBaseEnumTypeRef(readTypeRef());
                    if (isStringEnum) {
                        int seCount = readShort();
                        SchemaStringEnumEntry[] entries = new SchemaStringEnumEntry[seCount];
                        for (int i = 0; i < seCount; i++) {
                            entries[i] = new SchemaStringEnumEntryImpl(readString(), readShort(), readString());
                        }
                        impl.setStringEnumEntries(entries);
                    }

                    switch (simpleVariety) {
                        case SchemaType.ATOMIC:
                            impl.setPrimitiveTypeRef(readTypeRef());
                            impl.setDecimalSize(readInt());
                            break;

                        case SchemaType.LIST:
                            impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
                            impl.setListItemTypeRef(readTypeRef());
                            break;

                        case SchemaType.UNION:
                            impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
                            impl.setUnionMemberTypeRefs(readTypeRefArray());
                            break;

                        default:
                            throw new SchemaTypeLoaderException("Simple type does not have a recognized variety", _name, _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY);
                    }
                }

                impl.setFilename(readString());
                // Set the container for global, attribute or document types
                if (impl.getName() != null) {
                    SchemaContainer container = getContainer(impl.getName().getNamespaceURI());
                    checkContainerNotNull(container, impl.getName());
                    impl.setContainer(container);
                } else if (impl.isDocumentType()) {
                    QName name = impl.getDocumentElementName();
                    if (name != null) {
                        SchemaContainer container = getContainer(name.getNamespaceURI());
                        checkContainerNotNull(container, name);
                        impl.setContainer(container);
                    }
                } else if (impl.isAttributeType()) {
                    QName name = impl.getAttributeTypeAttributeName();
                    if (name != null) {
                        SchemaContainer container = getContainer(name.getNamespaceURI());
                        checkContainerNotNull(container, name);
                        impl.setContainer(container);
                    }
                }

                return impl;
            } catch (SchemaTypeLoaderException e) {
                throw e;
            } catch (Exception e) {
                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
            } finally {
                readEnd();
            }
        }

        void writeTypeData(SchemaType type) {
            writeQName(type.getName());
            writeType(type.getOuterType());
            writeShort(((SchemaTypeImpl) type).getBaseDepth());
            writeType(type.getBaseType());
            writeShort(type.getDerivationType());
            writeAnnotation(type.getAnnotation());
            if (type.getContainerField() == null) {
                writeShort(FIELD_NONE);
            } else if (type.getOuterType().isAttributeType() || type.getOuterType().isDocumentType()) {
                writeShort(FIELD_GLOBAL);
                writeHandle((SchemaComponent) type.getContainerField());
            } else if (type.getContainerField().isAttribute()) {
                writeShort(FIELD_LOCALATTR);
                writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalAttribute((SchemaLocalAttribute) type.getContainerField()));
            } else {
                writeShort(FIELD_LOCALELT);
                writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalElement((SchemaLocalElement) type.getContainerField()));
            }
            writeString(type.getFullJavaName());
            writeString(type.getFullJavaImplName());
            writeTypeArray(type.getAnonymousTypes());
            writeShort(type.getAnonymousUnionMemberOrdinal());

            int flags = 0;
            if (type.isSimpleType()) {
                flags |= FLAG_SIMPLE_TYPE;
            }
            if (type.isDocumentType()) {
                flags |= FLAG_DOCUMENT_TYPE;
            }
            if (type.isAttributeType()) {
                flags |= FLAG_ATTRIBUTE_TYPE;
            }
            if (type.ordered() != SchemaType.UNORDERED) {
                flags |= FLAG_ORDERED;
            }
            if (type.ordered() == SchemaType.TOTAL_ORDER) {
                flags |= FLAG_TOTAL_ORDER;
            }
            if (type.isBounded()) {
                flags |= FLAG_BOUNDED;
            }
            if (type.isFinite()) {
                flags |= FLAG_FINITE;
            }
            if (type.isNumeric()) {
                flags |= FLAG_NUMERIC;
            }
            if (type.hasStringEnumValues()) {
                flags |= FLAG_STRINGENUM;
            }
            if (((SchemaTypeImpl) type).isUnionOfLists()) {
                flags |= FLAG_UNION_OF_LISTS;
            }
            if (type.hasPatternFacet()) {
                flags |= FLAG_HAS_PATTERN;
            }
            if (type.isOrderSensitive()) {
                flags |= FLAG_ORDER_SENSITIVE;
            }

            if (type.blockExtension()) {
                flags |= FLAG_BLOCK_EXT;
            }
            if (type.blockRestriction()) {
                flags |= FLAG_BLOCK_REST;
            }
            if (type.finalExtension()) {
                flags |= FLAG_FINAL_EXT;
            }
            if (type.finalRestriction()) {
                flags |= FLAG_FINAL_EXT;
            }
            if (type.finalList()) {
                flags |= FLAG_FINAL_LIST;
            }
            if (type.finalUnion()) {
                flags |= FLAG_FINAL_UNION;
            }
            if (type.isAbstract()) {
                flags |= FLAG_ABSTRACT;
            }

            writeInt(flags);

            if (!type.isSimpleType()) {
                writeShort(type.getContentType());

                writeType(type.getContentBasedOnType());

                // Attribute Model Table
                SchemaAttributeModel attrModel = type.getAttributeModel();
                SchemaLocalAttribute[] attrs = attrModel.getAttributes();

                writeShort(attrs.length);
                for (int i = 0; i < attrs.length; i++) {
                    writeAttributeData(attrs[i]);
                }

                writeQNameSet(attrModel.getWildcardSet());
                writeShort(attrModel.getWildcardProcess());

                // Attribute Property Table
                SchemaProperty[] attrProperties = type.getAttributeProperties();
                writeShort(attrProperties.length);
                for (int i = 0; i < attrProperties.length; i++) {
                    writePropertyData(attrProperties[i]);
                }

                if (type.getContentType() == SchemaType.ELEMENT_CONTENT ||
                    type.getContentType() == SchemaType.MIXED_CONTENT) {
                    // Content Model Tree
                    writeShort(type.hasAllContent() ? 1 : 0);
                    SchemaParticle[] parts;
                    if (type.getContentModel() != null) {
                        parts = new SchemaParticle[]{type.getContentModel()};
                    } else {
                        parts = new SchemaParticle[0];
                    }

                    writeParticleArray(parts);

                    // Element Property Table
                    SchemaProperty[] eltProperties = type.getElementProperties();
                    writeShort(eltProperties.length);
                    for (int i = 0; i < eltProperties.length; i++) {
                        writePropertyData(eltProperties[i]);
                    }
                }
            }

            if (type.isSimpleType() || type.getContentType() == SchemaType.SIMPLE_CONTENT) {
                writeShort(type.getSimpleVariety());

                int facetCount = 0;
                for (int i = 0; i <= SchemaType.LAST_FACET; i++) {
                    if (type.getFacet(i) != null) {
                        facetCount++;
                    }
                }
                writeShort(facetCount);
                for (int i = 0; i <= SchemaType.LAST_FACET; i++) {
                    XmlAnySimpleType facet = type.getFacet(i);
                    if (facet != null) {
                        writeShort(i);
                        writeXmlValueObject(facet);
                        writeShort(type.isFacetFixed(i) ? 1 : 0);
                    }
                }

                writeShort(type.getWhiteSpaceRule());

                org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = ((SchemaTypeImpl) type).getPatternExpressions();
                writeShort(patterns.length);
                for (int i = 0; i < patterns.length; i++) {
                    writeString(patterns[i].getPattern());
                }

                XmlAnySimpleType[] enumValues = type.getEnumerationValues();
                if (enumValues == null) {
                    writeShort(0);
                } else {
                    writeShort(enumValues.length);
                    for (int i = 0; i < enumValues.length; i++) {
                        writeXmlValueObject(enumValues[i]);
                    }
                }

                // new for version 2.3
                writeType(type.getBaseEnumType());
                if (type.hasStringEnumValues()) {
                    SchemaStringEnumEntry[] entries = type.getStringEnumEntries();
                    writeShort(entries.length);
                    for (SchemaStringEnumEntry entry : entries) {
                        writeString(entry.getString());
                        writeShort(entry.getIntValue());
                        writeString(entry.getEnumName());
                    }
                }

                switch (type.getSimpleVariety()) {
                    case SchemaType.ATOMIC:
                        writeType(type.getPrimitiveType());
                        writeInt(type.getDecimalSize());
                        break;

                    case SchemaType.LIST:
                        writeType(type.getListItemType());
                        break;

                    case SchemaType.UNION:
                        writeTypeArray(type.getUnionMemberTypes());
                        break;
                }
            }

            writeString(type.getSourceName());
        }

        void readExtensionsList() {
            int count = readShort();
            assert count == 0;

            for (int i = 0; i < count; i++) {
                readString();
                readString();
                readString();
            }
        }

        SchemaLocalAttribute readAttributeData() {
            SchemaLocalAttributeImpl result = new SchemaLocalAttributeImpl();
            loadAttribute(result, readQName(), null);
            return result;
        }


        void loadAttribute(SchemaLocalAttributeImpl result, QName name, SchemaContainer container) {
            // name, type, use, deftext, defval, fixed, soaparraytype, annotation
            result.init(name, readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType(), readAnnotation(container), null);
        }

        void writeAttributeData(SchemaLocalAttribute attr) {
            writeQName(attr.getName());
            writeType(attr.getType());
            writeShort(attr.getUse());
            writeString(attr.getDefaultText());
            writeXmlValueObject(attr.getDefaultValue());
            writeShort(attr.isFixed() ? 1 : 0);
            writeSOAPArrayType(((SchemaWSDLArrayType) attr).getWSDLArrayType());
            writeAnnotation(attr.getAnnotation());
        }

        void writeIdConstraintData(SchemaIdentityConstraint idc) {
            writeQName(idc.getName());
            writeShort(idc.getConstraintCategory());
            writeString(idc.getSelector());
            writeAnnotation(idc.getAnnotation());

            String[] fields = idc.getFields();
            writeShort(fields.length);
            for (int i = 0; i < fields.length; i++) {
                writeString(fields[i]);
            }


            if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
                writeHandle(idc.getReferencedKey());
            }

            Set mappings = idc.getNSMap().entrySet();
            writeShort(mappings.size());
            for (Iterator it = mappings.iterator(); it.hasNext(); ) {
                Map.Entry e = (Map.Entry) it.next();
                String prefix = (String) e.getKey();
                String uri = (String) e.getValue();

                writeString(prefix);
                writeString(uri);
            }
            writeString(idc.getSourceName());
        }

        SchemaParticle[] readParticleArray() {
            SchemaParticle[] result = new SchemaParticle[readShort()];
            for (int i = 0; i < result.length; i++) {
                result[i] = readParticleData();
            }
            return result;
        }

        void writeParticleArray(SchemaParticle[] spa) {
            writeShort(spa.length);
            for (int i = 0; i < spa.length; i++) {
                writeParticleData(spa[i]);
            }
        }

        SchemaParticle readParticleData() {
            int particleType = readShort();
            SchemaParticleImpl result;
            if (particleType != SchemaParticle.ELEMENT) {
                result = new SchemaParticleImpl();
            } else {
                result = new SchemaLocalElementImpl();
            }
            loadParticle(result, particleType);
            return result;
        }

        void loadParticle(SchemaParticleImpl result, int particleType) {
            int particleFlags = readShort();

            result.setParticleType(particleType);
            result.setMinOccurs(readBigInteger());
            result.setMaxOccurs(readBigInteger());

            result.setTransitionRules(readQNameSet(),
                (particleFlags & FLAG_PART_SKIPPABLE) != 0);

            switch (particleType) {
                case SchemaParticle.WILDCARD:
                    result.setWildcardSet(readQNameSet());
                    result.setWildcardProcess(readShort());
                    break;

                case SchemaParticle.ELEMENT:
                    SchemaLocalElementImpl lresult = (SchemaLocalElementImpl) result;
                    lresult.setNameAndTypeRef(readQName(), readTypeRef());
                    lresult.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
                    if (atLeast(2, 16, 0)) {
                        lresult.setDefaultValue(readXmlValueObject());
                    }
                    lresult.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
                    lresult.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
                        (particleFlags & FLAG_PART_BLOCKREST) != 0,
                        (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
                    lresult.setWsdlArrayType(readSOAPArrayType());
                    lresult.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
                    lresult.setAnnotation(readAnnotation(null));

                    SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];

                    for (int i = 0; i < idcs.length; i++) {
                        idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
                    }

                    lresult.setIdentityConstraints(idcs);

                    break;

                case SchemaParticle.ALL:
                case SchemaParticle.SEQUENCE:
                case SchemaParticle.CHOICE:
                    result.setParticleChildren(readParticleArray());
                    break;

                default:
                    throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
            }
        }

        void writeParticleData(SchemaParticle part) {
            writeShort(part.getParticleType());
            short flags = 0;
            if (part.isSkippable()) {
                flags |= FLAG_PART_SKIPPABLE;
            }
            if (part.getParticleType() == SchemaParticle.ELEMENT) {
                SchemaLocalElement lpart = (SchemaLocalElement) part;
                if (lpart.isFixed()) {
                    flags |= FLAG_PART_FIXED;
                }
                if (lpart.isNillable()) {
                    flags |= FLAG_PART_NILLABLE;
                }
                if (lpart.blockExtension()) {
                    flags |= FLAG_PART_BLOCKEXT;
                }
                if (lpart.blockRestriction()) {
                    flags |= FLAG_PART_BLOCKREST;
                }
                if (lpart.blockSubstitution()) {
                    flags |= FLAG_PART_BLOCKSUBST;
                }
                if (lpart.isAbstract()) {
                    flags |= FLAG_PART_ABSTRACT;
                }

                if (lpart instanceof SchemaGlobalElement) {
                    SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;
                    if (gpart.finalExtension()) {
                        flags |= FLAG_PART_FINALEXT;
                    }
                    if (gpart.finalRestriction()) {
                        flags |= FLAG_PART_FINALREST;
                    }
                }
            }
            writeShort(flags);
            writeBigInteger(part.getMinOccurs());
            writeBigInteger(part.getMaxOccurs());
            writeQNameSet(part.acceptedStartNames());

            switch (part.getParticleType()) {
                case SchemaParticle.WILDCARD:
                    writeQNameSet(part.getWildcardSet());
                    writeShort(part.getWildcardProcess());
                    break;

                case SchemaParticle.ELEMENT:
                    SchemaLocalElement lpart = (SchemaLocalElement) part;
                    writeQName(lpart.getName());
                    writeType(lpart.getType());
                    writeString(lpart.getDefaultText());
                    writeXmlValueObject(lpart.getDefaultValue());
                    writeSOAPArrayType(((SchemaWSDLArrayType) lpart).getWSDLArrayType());
                    writeAnnotation(lpart.getAnnotation());
                    if (lpart instanceof SchemaGlobalElement) {
                        SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;

                        writeHandle(gpart.substitutionGroup());

                        QName[] substGroupMembers = gpart.substitutionGroupMembers();
                        writeShort(substGroupMembers.length);
                        for (int i = 0; i < substGroupMembers.length; i++) {
                            writeQName(substGroupMembers[i]);
                        }
                    }

                    SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints();

                    writeShort(idcs.length);
                    for (int i = 0; i < idcs.length; i++) {
                        writeHandle(idcs[i]);
                    }

                    break;

                case SchemaParticle.ALL:
                case SchemaParticle.SEQUENCE:
                case SchemaParticle.CHOICE:
                    writeParticleArray(part.getParticleChildren());
                    break;

                default:
                    throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
            }
        }

        SchemaProperty readPropertyData() {
            SchemaPropertyImpl prop = new SchemaPropertyImpl();
            prop.setName(readQName());
            prop.setTypeRef(readTypeRef());
            int propflags = readShort();
            prop.setAttribute((propflags & FLAG_PROP_ISATTR) != 0);
            prop.setContainerTypeRef(readTypeRef());
            prop.setMinOccurs(readBigInteger());
            prop.setMaxOccurs(readBigInteger());
            prop.setNillable(readShort());
            prop.setDefault(readShort());
            prop.setFixed(readShort());
            prop.setDefaultText(readString());

            prop.setJavaPropertyName(readString());
            prop.setJavaTypeCode(readShort());
            prop.setExtendsJava(readTypeRef(),
                (propflags & FLAG_PROP_JAVASINGLETON) != 0,
                (propflags & FLAG_PROP_JAVAOPTIONAL) != 0,
                (propflags & FLAG_PROP_JAVAARRAY) != 0);
            if (atMost(2, 19, 0)) {
                prop.setJavaSetterDelimiter(readQNameSet());
            }
            if (atLeast(2, 16, 0)) {
                prop.setDefaultValue(readXmlValueObject());
            }

            if (!prop.isAttribute() && atLeast(2, 17, 0)) {
                int size = readShort();
                LinkedHashSet qnames = new LinkedHashSet(size);
                for (int i = 0; i < size; i++) {
                    qnames.add(readQName());
                }
                prop.setAcceptedNames(qnames);
            }
            prop.setImmutable();
            return prop;
        }

        void writePropertyData(SchemaProperty prop) {
            writeQName(prop.getName());
            writeType(prop.getType());
            writeShort((prop.isAttribute() ? FLAG_PROP_ISATTR : 0) |
                       (prop.extendsJavaSingleton() ? FLAG_PROP_JAVASINGLETON : 0) |
                       (prop.extendsJavaOption() ? FLAG_PROP_JAVAOPTIONAL : 0) |
                       (prop.extendsJavaArray() ? FLAG_PROP_JAVAARRAY : 0));
            writeType(prop.getContainerType());
            writeBigInteger(prop.getMinOccurs());
            writeBigInteger(prop.getMaxOccurs());
            writeShort(prop.hasNillable());
            writeShort(prop.hasDefault());
            writeShort(prop.hasFixed());
            writeString(prop.getDefaultText());

            writeString(prop.getJavaPropertyName());
            writeShort(prop.getJavaTypeCode());
            writeType(prop.javaBasedOnType());
            writeXmlValueObject(prop.getDefaultValue());

            if (!prop.isAttribute()) {
                QName[] names = prop.acceptedNames();
                writeShort(names.length);
                for (int i = 0; i < names.length; i++) {
                    writeQName(names[i]);
                }
            }
        }

        void writeModelGroupData(SchemaModelGroup grp) {
            SchemaModelGroupImpl impl = (SchemaModelGroupImpl) grp;
            writeQName(impl.getName());
            writeString(impl.getTargetNamespace());
            writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
            writeString(impl.getElemFormDefault()); // new for version 2.22
            writeString(impl.getAttFormDefault()); // new for version 2.22
            writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
            writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
            writeAnnotation(impl.getAnnotation());
            writeString(impl.getSourceName());
        }

        void writeAttributeGroupData(SchemaAttributeGroup grp) {
            SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl) grp;
            writeQName(impl.getName());
            writeString(impl.getTargetNamespace());
            writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
            writeString(impl.getFormDefault()); // new for version 2.22
            writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
            writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
            writeAnnotation(impl.getAnnotation());
            writeString(impl.getSourceName());
        }

        XmlValueRef readXmlValueObject() {
            SchemaType.Ref typeref = readTypeRef();
            if (typeref == null) {
                return null;
            }
            int btc = readShort();
            switch (btc) {
                default:
                    assert (false);
                case 0:
                    return new XmlValueRef(typeref, null);
                case 0xFFFF: {
                    int size = readShort();
                    List values = new ArrayList();
                    writeShort(values.size());
                    for (int i = 0; i < size; i++) {
                        values.add(readXmlValueObject());
                    }
                    return new XmlValueRef(typeref, values);
                }


                case SchemaType.BTC_ANY_SIMPLE:
                case SchemaType.BTC_ANY_URI:
                case SchemaType.BTC_STRING:
                case SchemaType.BTC_DURATION:
                case SchemaType.BTC_DATE_TIME:
                case SchemaType.BTC_TIME:
                case SchemaType.BTC_DATE:
                case SchemaType.BTC_G_YEAR_MONTH:
                case SchemaType.BTC_G_YEAR:
                case SchemaType.BTC_G_MONTH_DAY:
                case SchemaType.BTC_G_DAY:
                case SchemaType.BTC_G_MONTH:
                case SchemaType.BTC_DECIMAL:
                case SchemaType.BTC_BOOLEAN:
                    return new XmlValueRef(typeref, readString());

                case SchemaType.BTC_BASE_64_BINARY:
                case SchemaType.BTC_HEX_BINARY:
                    return new XmlValueRef(typeref, readByteArray());

                case SchemaType.BTC_QNAME:
                case SchemaType.BTC_NOTATION:
                    return new XmlValueRef(typeref, readQName());

                case SchemaType.BTC_FLOAT:
                case SchemaType.BTC_DOUBLE:
                    return new XmlValueRef(typeref, new Double(readDouble()));
            }
        }

        void writeXmlValueObject(XmlAnySimpleType value) {
            SchemaType type = value == null ? null : value.schemaType();
            writeType(type);
            if (type == null) {
                return;
            }

            SchemaType iType = ((SimpleValue) value).instanceType();
            if (iType == null) {
                writeShort(0);
            } else if (iType.getSimpleVariety() == SchemaType.LIST) {
                writeShort(-1);
                List values = ((XmlObjectBase) value).xgetListValue();
                writeShort(values.size());
                for (Iterator i = values.iterator(); i.hasNext(); ) {
                    writeXmlValueObject((XmlAnySimpleType) i.next());
                }
            } else {
                int btc = iType.getPrimitiveType().getBuiltinTypeCode();
                writeShort(btc);
                switch (btc) {
                    case SchemaType.BTC_ANY_SIMPLE:
                    case SchemaType.BTC_ANY_URI:
                    case SchemaType.BTC_STRING:
                    case SchemaType.BTC_DURATION:
                    case SchemaType.BTC_DATE_TIME:
                    case SchemaType.BTC_TIME:
                    case SchemaType.BTC_DATE:
                    case SchemaType.BTC_G_YEAR_MONTH:
                    case SchemaType.BTC_G_YEAR:
                    case SchemaType.BTC_G_MONTH_DAY:
                    case SchemaType.BTC_G_DAY:
                    case SchemaType.BTC_G_MONTH:
                    case SchemaType.BTC_DECIMAL:
                    case SchemaType.BTC_BOOLEAN:
                        writeString(value.getStringValue());
                        break;

                    case SchemaType.BTC_BASE_64_BINARY:
                    case SchemaType.BTC_HEX_BINARY:
                        writeByteArray(((SimpleValue) value).getByteArrayValue());
                        break;

                    case SchemaType.BTC_QNAME:
                    case SchemaType.BTC_NOTATION:
                        writeQName(((SimpleValue) value).getQNameValue());
                        break;

                    case SchemaType.BTC_FLOAT:
                        writeDouble(((SimpleValue) value).getFloatValue());
                        break;

                    case SchemaType.BTC_DOUBLE:
                        writeDouble(((SimpleValue) value).getDoubleValue());
                        break;
                }
            }
        }

        double readDouble() {
            try {
                return _input.readDouble();
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        void writeDouble(double d) {
            if (_output != null) {
                try {
                    _output.writeDouble(d);
                } catch (IOException e) {
                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
                }
            }
        }

        QNameSet readQNameSet() {
            int flag = readShort();

            Set uriSet = new HashSet();
            int uriCount = readShort();
            for (int i = 0; i < uriCount; i++) {
                uriSet.add(readString());
            }

            Set qnameSet1 = new HashSet();
            int qncount1 = readShort();
            for (int i = 0; i < qncount1; i++) {
                qnameSet1.add(readQName());
            }

            Set qnameSet2 = new HashSet();
            int qncount2 = readShort();
            for (int i = 0; i < qncount2; i++) {
                qnameSet2.add(readQName());
            }

            if (flag == 1) {
                return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2);
            } else {
                return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1);
            }
        }

        void writeQNameSet(QNameSet set) {
            boolean invert = (set.excludedURIs() != null);
            writeShort(invert ? 1 : 0);

            Set uriSet = invert ? set.excludedURIs() : set.includedURIs();
            writeShort(uriSet.size());
            for (Iterator i = uriSet.iterator(); i.hasNext(); ) {
                writeString((String) i.next());
            }

            Set qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs();
            writeShort(qnameSet1.size());
            for (Iterator i = qnameSet1.iterator(); i.hasNext(); ) {
                writeQName((QName) i.next());
            }

            Set qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs();
            writeShort(qnameSet2.size());
            for (Iterator i = qnameSet2.iterator(); i.hasNext(); ) {
                writeQName((QName) i.next());
            }
        }

        byte[] readByteArray() {
            try {
                int len = _input.readShort();
                byte[] result = new byte[len];
                _input.readFully(result);
                return result;
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        void writeByteArray(byte[] ba) {
            try {
                writeShort(ba.length);
                if (_output != null) {
                    _output.write(ba);
                }
            } catch (IOException e) {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
            }
        }

        BigInteger readBigInteger() {
            byte[] result = readByteArray();
            if (result.length == 0) {
                return null;
            }
            if (result.length == 1 && result[0] == 0) {
                return BigInteger.ZERO;
            }
            if (result.length == 1 && result[0] == 1) {
                return BigInteger.ONE;
            }
            return new BigInteger(result);
        }

        void writeBigInteger(BigInteger bi) {
            if (bi == null) {
                writeShort(0);
            } else if (bi.signum() == 0) {
                writeByteArray(SINGLE_ZERO_BYTE);
            } else {
                writeByteArray(bi.toByteArray());
            }
        }

    }

    static final byte[] SINGLE_ZERO_BYTE = new byte[]{(byte) 0};

    public SchemaType typeForHandle(String handle) {
        synchronized (_resolvedHandles) {
            return (SchemaType) _resolvedHandles.get(handle);
        }
    }

    public SchemaType typeForClassname(String classname) {
        SchemaType.Ref ref = (SchemaType.Ref) _typeRefsByClassname.get(classname);
        return (ref != null) ? ref.get() : null;
    }

    public SchemaComponent resolveHandle(String handle) {
        SchemaComponent result;

        synchronized (_resolvedHandles) {
            result = (SchemaComponent) _resolvedHandles.get(handle);
        }
        if (result == null) {
            XsbReader reader = new XsbReader(handle, 0xFFFF);
            int filetype = reader.getActualFiletype();
            switch (filetype) {
                case FILETYPE_SCHEMATYPE:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving type for handle " + handle, 0);
                    result = reader.finishLoadingType();
                    break;
                case FILETYPE_SCHEMAELEMENT:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving element for handle " + handle, 0);
                    result = reader.finishLoadingElement();
                    break;
                case FILETYPE_SCHEMAATTRIBUTE:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute for handle " + handle, 0);
                    result = reader.finishLoadingAttribute();
                    break;
                case FILETYPE_SCHEMAMODELGROUP:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving model group for handle " + handle, 0);
                    result = reader.finishLoadingModelGroup();
                    break;
                case FILETYPE_SCHEMAATTRIBUTEGROUP:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute group for handle " + handle, 0);
                    result = reader.finishLoadingAttributeGroup();
                    break;
                case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
                    XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving id constraint for handle " + handle, 0);
                    result = reader.finishLoadingIdentityConstraint();
                    break;
                default:
                    throw new IllegalStateException("Illegal handle type");
            }

            synchronized (_resolvedHandles) {
                if (!_resolvedHandles.containsKey(handle)) {
                    _resolvedHandles.put(handle, result);
                } else {
                    result = (SchemaComponent) _resolvedHandles.get(handle);
                }
            }
        }
        return result;
    }

    private final Map _resolvedHandles = new HashMap();
    private boolean _allNonGroupHandlesResolved = false;

    public void resolve() {
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolve called type system " + _name, 0);
        if (_allNonGroupHandlesResolved) {
            return;
        }

        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving all handles for type system " + _name, 1);

        List refs = new ArrayList();
        refs.addAll(_globalElements.values());
        refs.addAll(_globalAttributes.values());
        refs.addAll(_globalTypes.values());
        refs.addAll(_documentTypes.values());
        refs.addAll(_attributeTypes.values());
        refs.addAll(_identityConstraints.values());

        for (Iterator i = refs.iterator(); i.hasNext(); ) {
            SchemaComponent.Ref ref = (SchemaComponent.Ref) i.next();
            ref.getComponent(); // Forces ref to be resolved
        }

        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished resolving type system " + _name, -1);
        _allNonGroupHandlesResolved = true;
    }


    public boolean isNamespaceDefined(String namespace) {
        return _namespaces.contains(namespace);
    }

    public SchemaType.Ref findTypeRef(QName name) {
        return (SchemaType.Ref) _globalTypes.get(name);
    }

    public SchemaType.Ref findDocumentTypeRef(QName name) {
        return (SchemaType.Ref) _documentTypes.get(name);
    }

    public SchemaType.Ref findAttributeTypeRef(QName name) {
        return (SchemaType.Ref) _attributeTypes.get(name);
    }

    public SchemaGlobalElement.Ref findElementRef(QName name) {
        return (SchemaGlobalElement.Ref) _globalElements.get(name);
    }

    public SchemaGlobalAttribute.Ref findAttributeRef(QName name) {
        return (SchemaGlobalAttribute.Ref) _globalAttributes.get(name);
    }

    public SchemaModelGroup.Ref findModelGroupRef(QName name) {
        return (SchemaModelGroup.Ref) _modelGroups.get(name);
    }

    public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name) {
        return (SchemaAttributeGroup.Ref) _attributeGroups.get(name);
    }

    public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name) {
        return (SchemaIdentityConstraint.Ref) _identityConstraints.get(name);
    }

    public SchemaType[] globalTypes() {
        if (_globalTypes.isEmpty()) {
            return EMPTY_ST_ARRAY;
        }

        SchemaType[] result = new SchemaType[_globalTypes.size()];
        int j = 0;
        for (Iterator i = _globalTypes.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaType.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaType[] redefinedGlobalTypes() {
        if (_redefinedGlobalTypes == null || _redefinedGlobalTypes.isEmpty()) {
            return EMPTY_ST_ARRAY;
        }

        SchemaType[] result = new SchemaType[_redefinedGlobalTypes.size()];
        int j = 0;
        for (Iterator i = _redefinedGlobalTypes.iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaType.Ref) i.next()).get();
        }
        return result;
    }

    public InputStream getSourceAsStream(String sourceName) {
        if (!sourceName.startsWith("/")) {
            sourceName = "/" + sourceName;
        }

        return _resourceLoader.getResourceAsStream(getMetadataPath() + "/src" + sourceName);
    }

    SchemaContainer[] containers() {
        SchemaContainer[] result = new SchemaContainer[_containers.size()];
        int j = 0;
        for (Iterator i = _containers.values().iterator(); i.hasNext(); j++) {
            result[j] = (SchemaContainer) i.next();
        }
        return result;
    }

    public SchemaType[] documentTypes() {
        if (_documentTypes.isEmpty()) {
            return EMPTY_ST_ARRAY;
        }

        SchemaType[] result = new SchemaType[_documentTypes.size()];
        int j = 0;
        for (Iterator i = _documentTypes.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaType.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaType[] attributeTypes() {
        if (_attributeTypes.isEmpty()) {
            return EMPTY_ST_ARRAY;
        }

        SchemaType[] result = new SchemaType[_attributeTypes.size()];
        int j = 0;
        for (Iterator i = _attributeTypes.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaType.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaGlobalElement[] globalElements() {
        if (_globalElements.isEmpty()) {
            return EMPTY_GE_ARRAY;
        }

        SchemaGlobalElement[] result = new SchemaGlobalElement[_globalElements.size()];
        int j = 0;
        for (Iterator i = _globalElements.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaGlobalElement.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaGlobalAttribute[] globalAttributes() {
        if (_globalAttributes.isEmpty()) {
            return EMPTY_GA_ARRAY;
        }

        SchemaGlobalAttribute[] result = new SchemaGlobalAttribute[_globalAttributes.size()];
        int j = 0;
        for (Iterator i = _globalAttributes.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaGlobalAttribute.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaModelGroup[] modelGroups() {
        if (_modelGroups.isEmpty()) {
            return EMPTY_MG_ARRAY;
        }

        SchemaModelGroup[] result = new SchemaModelGroup[_modelGroups.size()];
        int j = 0;
        for (Iterator i = _modelGroups.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaModelGroup.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaModelGroup[] redefinedModelGroups() {
        if (_redefinedModelGroups == null || _redefinedModelGroups.isEmpty()) {
            return EMPTY_MG_ARRAY;
        }

        SchemaModelGroup[] result = new SchemaModelGroup[_redefinedModelGroups.size()];
        int j = 0;
        for (Iterator i = _redefinedModelGroups.iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaModelGroup.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaAttributeGroup[] attributeGroups() {
        if (_attributeGroups.isEmpty()) {
            return EMPTY_AG_ARRAY;
        }

        SchemaAttributeGroup[] result = new SchemaAttributeGroup[_attributeGroups.size()];
        int j = 0;
        for (Iterator i = _attributeGroups.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaAttributeGroup.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaAttributeGroup[] redefinedAttributeGroups() {
        if (_redefinedAttributeGroups == null || _redefinedAttributeGroups.isEmpty()) {
            return EMPTY_AG_ARRAY;
        }

        SchemaAttributeGroup[] result = new SchemaAttributeGroup[_redefinedAttributeGroups.size()];
        int j = 0;
        for (Iterator i = _redefinedAttributeGroups.iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaAttributeGroup.Ref) i.next()).get();
        }
        return result;
    }

    public SchemaAnnotation[] annotations() {
        if (_annotations == null || _annotations.isEmpty()) {
            return EMPTY_ANN_ARRAY;
        }

        SchemaAnnotation[] result = new SchemaAnnotation[_annotations.size()];
        result = (SchemaAnnotation[]) _annotations.toArray(result);
        return result;
    }

    public SchemaIdentityConstraint[] identityConstraints() {
        if (_identityConstraints.isEmpty()) {
            return EMPTY_IC_ARRAY;
        }

        SchemaIdentityConstraint[] result = new SchemaIdentityConstraint[_identityConstraints.size()];
        int j = 0;
        for (Iterator i = _identityConstraints.values().iterator(); i.hasNext(); j++) {
            result[j] = ((SchemaIdentityConstraint.Ref) i.next()).get();
        }
        return result;
    }

    public ClassLoader getClassLoader() {
        return _classloader;
    }

    /**
     * Used INTERNALLY ONLY by the code output AFTER the type system has
     * been saved and a handle has been established for each type.
     */
    public String handleForType(SchemaType type) {
        return _localHandles.handleForType(type);
    }

    public String getName() {
        return _name;
    }

    public SchemaTypeSystem typeSystemForName(String name) {
        if (_name != null && name.equals(_name)) {
            return this;
        }
        return null;
    }


    /**
     * Provide method to be overriden by user typesystems using a different metadata path
     *
     * @return the metadata directory
     * @since XmlBeans 3.1.0
     */
    public String getMetadataPath() {
        Matcher m = packPat.matcher(_name);
        m.find();
        return m.group(1).replace('.', '/');
    }
}
