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

package org.apache.xmlbeans.impl.schema;

import javax.xml.namespace.QName;
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.common.XmlErrorWatcher;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.math.BigInteger;


import org.apache.xmlbeans.impl.regex.RegularExpression;
import org.apache.xmlbeans.impl.util.HexBin;
import org.apache.xmlbeans.impl.values.XmlObjectBase;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaComponent;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaModelGroup;
import org.apache.xmlbeans.SchemaAttributeGroup;
import org.apache.xmlbeans.SchemaAttributeModel;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.SchemaLocalAttribute;
import org.apache.xmlbeans.SchemaLocalElement;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.apache.xmlbeans.SchemaStringEnumEntry;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.SchemaIdentityConstraint;
import org.apache.xmlbeans.SimpleValue;
import org.apache.xmlbeans.SchemaTypeLoaderException;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.soap.SOAPArrayType;
import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
import com.bea.x2002.x09.xbean.config.ConfigDocument.Config;
import com.bea.x2002.x09.xbean.config.ConfigDocument;
import org.w3.x2001.xmlSchema.SchemaDocument;
import org.w3.x2001.xmlSchema.GroupDocument;
import org.w3.x2001.xmlSchema.AttributeGroupDocument;
import org.w3.x2001.xmlSchema.SchemaDocument.Schema;

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


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

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

        return nameForSystem;
    }

    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);
        _resourceLoader = new ClassLoaderResourceLoader(_classloader);
        initFromHeader();
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1);
    }

    private static final Schema[] EMPTY_SCHEMA_ARRAY = new Schema[0];
    private static final Config[] EMPTY_CONFIG_ARRAY = new Config[0];

    public static SchemaTypeSystemImpl forSchemaXml(
        XmlObject[] input, SchemaTypeLoader linkTo, XmlOptions options)
            throws XmlException
    {
        options = XmlOptions.maskNull(options);
        ArrayList schemas = new ArrayList();
        ArrayList configs = new ArrayList();

        for (int i = 0; i < input.length; i++)
        {
            if (input[i] instanceof Schema)
                schemas.add(input[i]);
            else if (input[i] instanceof SchemaDocument && ((SchemaDocument)input[i]).getSchema() != null)
                schemas.add(((SchemaDocument)input[i]).getSchema());
            else if (input[i] instanceof Config)
                configs.add(input[i]);
            else if (input[i] instanceof ConfigDocument && ((ConfigDocument)input[i]).getConfig() != null)
                configs.add(((ConfigDocument)input[i]).getConfig());
            else
                throw new XmlException("Thread " + Thread.currentThread().getName() +  ": The " + i + "th supplied input is not a schema or a config document: its type is " + input[i].schemaType());
        }



        Collection userErrors = (Collection)options.get(XmlOptions.ERROR_LISTENER);
        XmlErrorWatcher errorWatcher = new XmlErrorWatcher(userErrors);

        SchemaTypeSystemImpl stsi =
            SchemaTypeSystemCompiler.compileImpl(
                null, (Schema[])schemas.toArray(EMPTY_SCHEMA_ARRAY),
                (Config[])configs.toArray(EMPTY_CONFIG_ARRAY), linkTo, options, errorWatcher, false, null, null);

        if (errorWatcher.hasError())
        {
            throw new XmlException(errorWatcher.firstError());
        }

        return stsi;
    }

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

        if (file.isDirectory())
        {
            return (new File(file, indexname)).isFile();
        }
        else
        {
            ZipFile zipfile = null;
            try
            {
                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);
            }
            finally
            {
                if (zipfile != null)
                    try { zipfile.close(); } catch (IOException 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 (Exception 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
            if (reader.atLeast(2, 15, 0))
            {
                _redefinedGlobalTypes = reader.readQNameRefMap();
                _redefinedModelGroups = reader.readQNameRefMap();
                _redefinedAttributeGroups = reader.readQNameRefMap();
            }
        }
        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(), "schema/element/");
        savePointersForComponents(globalAttributes(), "schema/attribute/");
        savePointersForComponents(modelGroups(), "schema/modelgroup/");
        savePointersForComponents(attributeGroups(), "schema/attributegroup/");
        savePointersForComponents(globalTypes(), "schema/type/");
        savePointersForComponents(identityConstraints(), "schema/identityconstraint/");
        savePointersForNamespaces(_namespaces, "schema/namespace/");
        savePointersForClassnames(_typeRefsByClassname.keySet(), "schema/javaname/");
        savePointersForComponents(redefinedModelGroups(), "schema/redefinedmodelgroup/");
        savePointersForComponents(redefinedAttributeGroups(), "schema/redefinedattributegroup/");
        savePointersForComponents(redefinedGlobalTypes(), "schema/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();
    }

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

    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.. :-).
     *
     * 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.
     *
     * 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.
     *
     * 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 = System.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));
        }

        _name = "schema.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 = buildDocumentMap(attributeTypes);
        _typeRefsByClassname = buildTypeRefsByClassname();
        _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 = buildComponentRefMap(state.redefinedModelGroups());
        _attributeGroups = buildComponentRefMap(state.attributeGroups());
        _redefinedAttributeGroups = buildComponentRefMap(state.redefinedAttributeGroups());
        _globalTypes = buildComponentRefMap(state.globalTypes());
        _redefinedGlobalTypes = buildComponentRefMap(state.redefinedGlobalTypes());
        _documentTypes = buildDocumentMap(state.documentTypes());
        _attributeTypes = buildAttributeTypeMap(state.attributeTypes());
        _typeRefsByClassname = buildTypeRefsByClassname(state.typesByClassname());
        _identityConstraints = buildComponentRefMap(state.idConstraints());
        _namespaces = new HashSet(Arrays.asList(state.getNamespaces()));
    }

    final SchemaTypeSystemImpl getTypeSystem()
    {
        return this;
    }

    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() > Short.MAX_VALUE)
                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);
            }
        }

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

            try
            {
                int size = input.readShort();
                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 String _name;
    private String _basePackage;

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

    // actual type system data, map QNames -> SchemaComponent.Ref
    private Map _redefinedModelGroups;
    private Map _redefinedAttributeGroups;
    private Map _redefinedGlobalTypes;

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

    public void saveToDirectory(File classDir)
    {
        _baseSaveDir = classDir;

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

    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)
    {
        for (int i = 0; i < elts.length; i++)
        {
            saveGlobalElement(elts[i]);
        }
    }

    public void saveGlobalAttributes(SchemaGlobalAttribute[] attrs)
    {
        for (int i = 0; i < attrs.length; i++)
        {
            saveGlobalAttribute(attrs[i]);
        }
    }

    public void saveModelGroups(SchemaModelGroup[] groups)
    {
        for (int i = 0; i < groups.length; i++)
        {
            saveModelGroup(groups[i]);
        }
    }

    public void saveAttributeGroups(SchemaAttributeGroup[] groups)
    {
        for (int i = 0; i < groups.length; i++)
        {
            saveAttributeGroup(groups[i]);
        }
    }

    public void saveIdentityConstraints(SchemaIdentityConstraint[] idcs)
    {
        for (int i = 0; i < idcs.length; i++)
        {
            saveIdentityConstraint(idcs[i]);
        }
    }

    public void saveGlobalElement(SchemaGlobalElement elt)
    {
        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)
    {
        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)
    {
        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)
    {
        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)
    {
        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 != -1)
                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);
            }
            _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());
        }

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

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

        void writeShort(int s)
        {
            if (s > Short.MAX_VALUE || s < Short.MIN_VALUE)
                throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit 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);
                }
            }
        }

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

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

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

        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
                    return ((SchemaType)BuiltinSchemaTypeSystem.get().resolveHandle(handle)).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
                    return _linker.findAttribute(QNameHelper.forPretty(handle, 4)).getType().getRef();
                case 'S': // _XS_ - external ref to element's type
                    return _linker.findElement(QNameHelper.forPretty(handle, 4)).getType().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
                    if (type.getName() != null)
                    {
                        writeString("_XT_" + QNameHelper.pretty(type.getName()));
                    }
                    else
                    {
                        SchemaField sf = type.getContainerField();
                        assert (sf != null);
                        if (sf.isAttribute())
                        {
                            writeString("_XR_" + QNameHelper.pretty(sf.getName()));
                        }
                        else
                        {
                            writeString("_XS_" + QNameHelper.pretty(sf.getName()));
                        }
                    }

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

        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)
        {
            File targetFile = new File(_baseSaveDir, name);
            try
            {
                targetFile.getParentFile().mkdirs();
                return new FileOutputStream(targetFile);
            }
            catch (IOException e)
            {
                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
            }
        }

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

        /**
         * Finishes loading an element after the header has already been loaded.
         */
        public SchemaGlobalElement finishLoadingElement()
        {
            String handle = null;
            try
            {
                SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(getTypeSystem());
                short particleType = readShort();
                if (particleType != SchemaParticle.ELEMENT)
                    throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
                loadParticle(impl, SchemaParticle.ELEMENT, true);
                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()
        {
            SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(getTypeSystem());
            try
            {
                loadAttribute(impl);
                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()
        {
            SchemaModelGroupImpl impl = new SchemaModelGroupImpl(getTypeSystem());

            try
            {
                loadModelGroup(impl);
                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 {
                SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(getTypeSystem());
                impl.setName(readQName());
                impl.setConstraintCategory(readShort());
                impl.setSelector(readString());

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

                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()
        {
            SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(getTypeSystem());

            try
            {
                loadAttributeGroup(impl);
                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
            {
                SchemaTypeImpl impl = new SchemaTypeImpl(getTypeSystem(), true);
                impl.setName(readQName());
                impl.setOuterSchemaTypeRef(readTypeRef());
                impl.setBaseDepth(readShort());
                impl.setBaseTypeRef(readTypeRef());
                impl.setDerivationType(readShort());

                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;
                }
                impl.setFullJavaName(readString());
                impl.setFullJavaImplName(readString());

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

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

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

                    short 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();
                    short 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;
                    short 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();
                        short 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)
                {
                    short 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];
                    short facetCount = readShort();
                    for (int i = 0; i < facetCount; i++)
                    {
                        short facetCode = readShort();
                        facets[facetCode] = readXmlValueObject();
                        fixedFacets[facetCode] = (readShort() == 1);
                    }
                    impl.setBasicFacets(facets, fixedFacets);

                    impl.setWhiteSpaceRule(readShort());

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

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

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

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

                // 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 (int i = 0; i < entries.length; i++)
                    {
                        writeString(entries[i].getString());
                        writeShort(entries[i].getIntValue());
                        writeString(entries[i].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);
            return result;
        }

        void loadModelGroup(SchemaModelGroupImpl result)
        {
            try
            {
                result.init(readQName(), readString(), readShort() == 1, atLeast(2, 15, 0) ? readShort() == 1 : false, GroupDocument.Factory.parse( readString() ).getGroup());
            }
            catch ( XmlException e )
            {
                throw new RuntimeException( e.getMessage(), e );
            }
        }

        void loadAttributeGroup(SchemaAttributeGroupImpl result)
        {
            try
            {
                result.init( readQName(), readString(), readShort() == 1, atLeast(2, 15, 0) ? readShort() == 1 : false, AttributeGroupDocument.Factory.parse( readString() ).getAttributeGroup());
            }
            catch ( XmlException e )
            {
                throw new RuntimeException( e.getMessage(), e );
            }
        }

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

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

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

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

        }

        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()
        {
            short particleType = readShort();
            SchemaParticleImpl result;
            if (particleType != SchemaParticle.ELEMENT)
                result = new SchemaParticleImpl();
            else
                result = new SchemaLocalElementImpl();
            loadParticle(result, particleType, false);
            return result;
        }

        void loadParticle(SchemaParticleImpl result, int particleType, boolean global)
        {
            short 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);
                    if (global)
                    {
                        SchemaGlobalElementImpl gresult = (SchemaGlobalElementImpl)lresult;
                        gresult.setFinal(
                                     (particleFlags & FLAG_PART_FINALEXT) != 0,
                                     (particleFlags & FLAG_PART_FINALREST) != 0);

                        if (atLeast(2, 17, 0))
                            gresult.setSubstitutionGroup((SchemaGlobalElement.Ref)readHandle());

                        short substGroupCount = readShort();
                        for (int i = 0; i < substGroupCount; i++)
                        {
                            gresult.addSubstitutionGroupMember(readQName());
                        }
                    }

                    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());
                    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());
            short 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);
            prop.setJavaSetterDelimiter(readQNameSet());
            if (atLeast(2, 16, 0))
                prop.setDefaultValue(readXmlValueObject());

            if (!prop.isAttribute() && atLeast(2, 17, 0))
            {
                short 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());
            writeQNameSet(prop.getJavaSetterDelimiter());
            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);
            writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
            writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
        }

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

        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 -1:
                    {
                        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);
            }
        }

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

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

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

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

            Set qnameSet2 = new HashSet();
            short 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
            {
                short 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);
            }
        }

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

        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, -1);
            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.isEmpty())
            return EMPTY_ST_ARRAY;

        SchemaType[] result = new SchemaType[_redefinedGlobalTypes.size()];
        int j = 0;
        for (Iterator i = _redefinedGlobalTypes.values().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("schema/src" + sourceName);
    }

    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.isEmpty())
            return EMPTY_MG_ARRAY;

        SchemaModelGroup[] result = new SchemaModelGroup[_redefinedModelGroups.size()];
        int j = 0;
        for (Iterator i = _redefinedModelGroups.values().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.isEmpty())
            return EMPTY_AG_ARRAY;

        SchemaAttributeGroup[] result = new SchemaAttributeGroup[_redefinedAttributeGroups.size()];
        int j = 0;
        for (Iterator i = _redefinedAttributeGroups.values().iterator(); i.hasNext(); j++)
            result[j] = ((SchemaAttributeGroup.Ref)i.next()).get();
        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 generator 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;
    }
}

