diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java
new file mode 100644
index 0000000..0f58fdb
--- /dev/null
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypePool.java
@@ -0,0 +1,271 @@
+/*   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.schema;
+
+import org.apache.xmlbeans.*;
+import org.apache.xmlbeans.impl.common.NameUtil;
+
+import javax.xml.namespace.QName;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.*;
+
+class SchemaTypePool {
+    private final SchemaTypeSystemImpl typeSystem;
+    private final Map<String, SchemaComponent.Ref> _handlesToRefs = new LinkedHashMap<>();
+    // populated on write
+    private final Map<SchemaComponent, String> _componentsToHandles = new LinkedHashMap<>();
+    private boolean _started;
+
+
+    /**
+     * Constructs an empty HandlePool to be populated.
+     */
+    SchemaTypePool(SchemaTypeSystemImpl typeSystem) {
+        this.typeSystem = typeSystem;
+    }
+
+    private String addUniqueHandle(SchemaComponent obj, String base) {
+        // we lowercase handles because of case-insensitive Windows filenames!!!
+        base = base.toLowerCase(Locale.ROOT);
+        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() != typeSystem) {
+            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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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() != typeSystem) {
+            throw new IllegalArgumentException("Cannot supply handles for types from another type system");
+        }
+        String handle = _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(Locale.ROOT);
+            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 _handlesToRefs.get(handle);
+    }
+
+    void startWriteMode() {
+        _started = true;
+        _componentsToHandles.clear();
+        for (String handle : _handlesToRefs.keySet()) {
+            SchemaComponent comp = _handlesToRefs.get(handle).getComponent();
+            _componentsToHandles.put(comp, handle);
+        }
+    }
+
+    void writeHandlePool(XsbReader reader) {
+        reader.writeShort(_componentsToHandles.size());
+        _componentsToHandles.forEach((comp, handle) -> {
+            reader.writeString(handle);
+            reader.writeShort(fileTypeFromComponentType(comp.getComponentType()));
+        });
+    }
+
+    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 readHandlePool(XsbReader reader) {
+        if (_handlesToRefs.size() != 0 || _started) {
+            throw new IllegalStateException("Nonempty handle set before read");
+        }
+
+        int size = reader.readShort();
+        for (int i = 0; i < size; i++) {
+            String handle = reader.readString();
+            int code = reader.readShort();
+            SchemaComponent.Ref result;
+            switch (code) {
+                case FILETYPE_SCHEMATYPE:
+                    result = new SchemaType.Ref(typeSystem, handle);
+                    break;
+                case FILETYPE_SCHEMAELEMENT:
+                    result = new SchemaGlobalElement.Ref(typeSystem, handle);
+                    break;
+                case FILETYPE_SCHEMAATTRIBUTE:
+                    result = new SchemaGlobalAttribute.Ref(typeSystem, handle);
+                    break;
+                case FILETYPE_SCHEMAMODELGROUP:
+                    result = new SchemaModelGroup.Ref(typeSystem, handle);
+                    break;
+                case FILETYPE_SCHEMAATTRIBUTEGROUP:
+                    result = new SchemaAttributeGroup.Ref(typeSystem, handle);
+                    break;
+                case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
+                    result = new SchemaIdentityConstraint.Ref(typeSystem, handle);
+                    break;
+                default:
+                    throw new SchemaTypeLoaderException("Schema index has an unrecognized entry of type " + code, typeSystem.getName(), handle, SchemaTypeLoaderException.UNRECOGNIZED_INDEX_ENTRY);
+            }
+            _handlesToRefs.put(handle, result);
+        }
+    }
+}
+
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java
index b822f72..b83bf1f 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java
@@ -16,22 +16,15 @@
 package org.apache.xmlbeans.impl.schema;
 
 import org.apache.xmlbeans.*;
-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.util.FilerImpl;
 import org.apache.xmlbeans.impl.util.HexBin;
 import org.apache.xmlbeans.impl.util.LongUTFDataInputStream;
 import org.apache.xmlbeans.impl.util.LongUTFDataOutputStream;
-import org.apache.xmlbeans.impl.values.XmlObjectBase;
-import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroupDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.GroupDocument;
-import org.apache.xmlbeans.soap.SOAPArrayType;
-import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
 
 import javax.xml.namespace.QName;
 import java.io.*;
-import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.function.BiConsumer;
@@ -119,7 +112,59 @@
      */
     public static String METADATA_PACKAGE_GEN = "org/apache/xmlbeans/metadata";
 
-    private static String nameToPathString(String nameForSystem) {
+
+    private static final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];
+    private static final SchemaGlobalElement[] EMPTY_GE_ARRAY = new SchemaGlobalElement[0];
+    private static final SchemaGlobalAttribute[] EMPTY_GA_ARRAY = new SchemaGlobalAttribute[0];
+    private static final SchemaModelGroup[] EMPTY_MG_ARRAY = new SchemaModelGroup[0];
+    private static final SchemaAttributeGroup[] EMPTY_AG_ARRAY = new SchemaAttributeGroup[0];
+    private static final SchemaIdentityConstraint[] EMPTY_IC_ARRAY = new SchemaIdentityConstraint[0];
+    private static final SchemaAnnotation[] EMPTY_ANN_ARRAY = new SchemaAnnotation[0];
+
+    private final String _name;
+
+    // EXPERIMENTAL: recovery from compilation errors and partial type systems
+    private boolean _incomplete = false;
+
+    // classloader is available for sts's that were compiled and loaded, not dynamic ones
+    private ClassLoader _classloader;
+
+    // the loader for loading .xsb resources
+    private ResourceLoader _resourceLoader;
+
+    // the following is used to link references during load
+    SchemaTypeLoader _linker;
+
+    private SchemaTypePool _localHandles;
+    private Filer _filer;
+
+    // top-level annotations
+    private List<SchemaAnnotation> _annotations;
+
+    // container
+    private Map<String, SchemaContainer> _containers = new HashMap<>();
+    // dependencies
+    private SchemaDependencies _deps;
+
+    private List<SchemaComponent.Ref> _redefinedModelGroups;
+    private List<SchemaComponent.Ref> _redefinedAttributeGroups;
+    private List<SchemaComponent.Ref> _redefinedGlobalTypes;
+
+    // actual type system data, map QNames -> SchemaComponent.Ref
+    private Map<QName, SchemaComponent.Ref> _globalElements;
+    private Map<QName, SchemaComponent.Ref> _globalAttributes;
+    private Map<QName, SchemaComponent.Ref> _modelGroups;
+    private Map<QName, SchemaComponent.Ref> _attributeGroups;
+    private Map<QName, SchemaComponent.Ref> _globalTypes;
+    private Map<QName, SchemaComponent.Ref> _documentTypes;
+    private Map<QName, SchemaComponent.Ref> _attributeTypes;
+    private Map<QName, SchemaComponent.Ref> _identityConstraints = Collections.emptyMap();
+    private Map<String, SchemaComponent.Ref> _typeRefsByClassname = new HashMap<>();
+    private Set<String> _namespaces;
+
+
+
+    static String nameToPathString(String nameForSystem) {
         nameForSystem = nameForSystem.replace('.', '/');
 
         if (!nameForSystem.endsWith("/") && nameForSystem.length() > 0) {
@@ -133,7 +178,6 @@
         String fullname = getClass().getName();
         _name = fullname.substring(0, fullname.lastIndexOf('.'));
         XBeanDebug.LOG.atTrace().log("Loading type system {}", _name);
-        _basePackage = nameToPathString(_name);
         _classloader = getClass().getClassLoader();
         _linker = this;
         _resourceLoader = new ClassLoaderResourceLoader(_classloader);
@@ -150,7 +194,6 @@
         String fullname = indexclass.getName();
         _name = fullname.substring(0, fullname.lastIndexOf('.'));
         XBeanDebug.LOG.atTrace().log("Loading type system {}", _name);
-        _basePackage = nameToPathString(_name);
         _classloader = indexclass.getClassLoader();
         _linker = SchemaTypeLoaderImpl.build(null, null, _classloader, getMetadataPath());
         _resourceLoader = new ClassLoaderResourceLoader(_classloader);
@@ -174,7 +217,6 @@
 
     public SchemaTypeSystemImpl(ResourceLoader resourceLoader, String name, SchemaTypeLoader linker) {
         _name = name;
-        _basePackage = nameToPathString(_name);
         _linker = linker;
         _resourceLoader = resourceLoader;
         try {
@@ -190,11 +232,11 @@
         XsbReader reader = null;
         try {
             // Read the index file, which starts with a header.
-            reader = new XsbReader("index", FILETYPE_SCHEMAINDEX);
+            reader = new XsbReader(getTypeSystem(), "index", FILETYPE_SCHEMAINDEX);
 
             // has a handle pool (count, handle/type, handle/type...)
-            _localHandles = new HandlePool();
-            reader.readHandlePool(_localHandles);
+            _localHandles = new SchemaTypePool(getTypeSystem());
+            _localHandles.readHandlePool(reader);
 
             // then a qname map of global elements (count, qname/handle, qname/handle...)
             _globalElements = reader.readQNameRefMap();
@@ -247,7 +289,7 @@
 
     void saveIndex() {
         String handle = "index";
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeIndexData();
         saver.writeRealHeader(handle, FILETYPE_SCHEMAINDEX);
         saver.writeIndexData();
@@ -287,16 +329,13 @@
     }
 
     void savePointerFile(String filename, String name) {
-        XsbReader saver = new XsbReader(filename);
+        XsbReader saver = new XsbReader(getTypeSystem(), filename);
         saver.writeString(name);
         saver.writeRealHeader(filename, FILETYPE_SCHEMAPOINTER);
         saver.writeString(name);
         saver.writeEnd();
     }
 
-    // MAX_UNSIGNED_SHORT
-    private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1;
-
     private Map<String, SchemaComponent.Ref> buildTypeRefsByClassname(Map<String, SchemaType> typesByClassname) {
         Map<String, SchemaComponent.Ref> result = new LinkedHashMap<>();
         for (String className : typesByClassname.keySet()) {
@@ -353,7 +392,7 @@
     }
 
     // Container operation
-    private SchemaContainer getContainer(String namespace) {
+    SchemaContainer getContainer(String namespace) {
         return _containers.get(namespace);
     }
 
@@ -363,7 +402,7 @@
         _containers.put(namespace, c);
     }
 
-    private SchemaContainer getContainerNonNull(String namespace) {
+    SchemaContainer getContainerNonNull(String namespace) {
         SchemaContainer result = getContainer(namespace);
         if (result == null) {
             addContainer(namespace);
@@ -557,13 +596,12 @@
         }
 
         _name = SchemaTypeSystemImpl.METADATA_PACKAGE_GEN.replace('/', '.') + ".system." + nameForSystem;
-        _basePackage = nameToPathString(_name);
         _classloader = null;
     }
 
     public void loadFromStscState(StscState state) {
         assert (_classloader == null);
-        _localHandles = new HandlePool();
+        _localHandles = new SchemaTypePool(getTypeSystem());
         _globalElements = buildComponentRefMap(state.globalElements());
         _globalAttributes = buildComponentRefMap(state.globalAttributes());
         _modelGroups = buildComponentRefMap(state.modelGroups());
@@ -675,235 +713,6 @@
         }
     }
 
-    class HandlePool {
-        private final Map<String, SchemaComponent.Ref> _handlesToRefs = new LinkedHashMap<>();
-        // populated on write
-        private final Map<SchemaComponent, String> _componentsToHandles = new LinkedHashMap<>();
-        private boolean _started;
-
-        /**
-         * Constructs an empty HandlePool to be populated.
-         */
-        HandlePool() {
-        }
-
-        private String addUniqueHandle(SchemaComponent obj, String base) {
-            // we lowercase handles because of case-insensitive Windows filenames!!!
-            base = base.toLowerCase(Locale.ROOT);
-            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 = _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 = _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 = _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 = _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 = _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 = _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(Locale.ROOT);
-                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 _handlesToRefs.get(handle);
-        }
-
-        void startWriteMode() {
-            _started = true;
-            _componentsToHandles.clear();
-            for (String handle : _handlesToRefs.keySet()) {
-                SchemaComponent comp = _handlesToRefs.get(handle).getComponent();
-                _componentsToHandles.put(comp, handle);
-            }
-        }
-
-    }
-
-    private final String _name;
-    private final String _basePackage;
-
-    // EXPERIMENTAL: recovery from compilation errors and partial type systems
-    private boolean _incomplete = false;
-
-    // classloader is available for sts's that were compiled and loaded, not dynamic ones
-    private ClassLoader _classloader;
-
-    // the loader for loading .xsb resources
-    private ResourceLoader _resourceLoader;
-
-    // the following is used to link references during load
-    SchemaTypeLoader _linker;
-
-    private HandlePool _localHandles;
-    private Filer _filer;
-
-    // top-level annotations
-    private List<SchemaAnnotation> _annotations;
-
-    // container
-    private Map<String, SchemaContainer> _containers = new HashMap<>();
-    // dependencies
-    private SchemaDependencies _deps;
-
-    private List<SchemaComponent.Ref> _redefinedModelGroups;
-    private List<SchemaComponent.Ref> _redefinedAttributeGroups;
-    private List<SchemaComponent.Ref> _redefinedGlobalTypes;
-
-    // actual type system data, map QNames -> SchemaComponent.Ref
-    private Map<QName, SchemaComponent.Ref> _globalElements;
-    private Map<QName, SchemaComponent.Ref> _globalAttributes;
-    private Map<QName, SchemaComponent.Ref> _modelGroups;
-    private Map<QName, SchemaComponent.Ref> _attributeGroups;
-    private Map<QName, SchemaComponent.Ref> _globalTypes;
-    private Map<QName, SchemaComponent.Ref> _documentTypes;
-    private Map<QName, SchemaComponent.Ref> _attributeTypes;
-    private Map<QName, SchemaComponent.Ref> _identityConstraints = Collections.emptyMap();
-    private Map<String, SchemaComponent.Ref> _typeRefsByClassname = new HashMap<>();
-    private Set<String> _namespaces;
-
-    static private final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];
-    static private final SchemaGlobalElement[] EMPTY_GE_ARRAY = new SchemaGlobalElement[0];
-    static private final SchemaGlobalAttribute[] EMPTY_GA_ARRAY = new SchemaGlobalAttribute[0];
-    static private final SchemaModelGroup[] EMPTY_MG_ARRAY = new SchemaModelGroup[0];
-    static private final SchemaAttributeGroup[] EMPTY_AG_ARRAY = new SchemaAttributeGroup[0];
-    static private final SchemaIdentityConstraint[] EMPTY_IC_ARRAY = new SchemaIdentityConstraint[0];
-    static private final SchemaAnnotation[] EMPTY_ANN_ARRAY = new SchemaAnnotation[0];
-
     public void saveToDirectory(File classDir) {
         save(new FilerImpl(classDir, null, null, false, false));
     }
@@ -996,7 +805,7 @@
             throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
         }
         String handle = _localHandles.handleForElement(elt);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeParticleData((SchemaParticle) elt);
         saver.writeString(elt.getSourceName());
         saver.writeRealHeader(handle, FILETYPE_SCHEMAELEMENT);
@@ -1010,7 +819,7 @@
             throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
         }
         String handle = _localHandles.handleForAttribute(attr);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeAttributeData(attr);
         saver.writeString(attr.getSourceName());
         saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTE);
@@ -1024,7 +833,7 @@
             throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
         }
         String handle = _localHandles.handleForModelGroup(grp);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeModelGroupData(grp);
         saver.writeRealHeader(handle, FILETYPE_SCHEMAMODELGROUP);
         saver.writeModelGroupData(grp);
@@ -1036,7 +845,7 @@
             throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
         }
         String handle = _localHandles.handleForAttributeGroup(grp);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeAttributeGroupData(grp);
         saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTEGROUP);
         saver.writeAttributeGroupData(grp);
@@ -1048,7 +857,7 @@
             throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
         }
         String handle = _localHandles.handleForIdentityConstraint(idc);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeIdConstraintData(idc);
         saver.writeRealHeader(handle, FILETYPE_SCHEMAIDENTITYCONSTRAINT);
         saver.writeIdConstraintData(idc);
@@ -1057,7 +866,7 @@
 
     void saveType(SchemaType type) {
         String handle = _localHandles.handleForType(type);
-        XsbReader saver = new XsbReader(handle);
+        XsbReader saver = new XsbReader(getTypeSystem(), handle);
         saver.writeTypeData(type);
         saver.writeRealHeader(handle, FILETYPE_SCHEMATYPE);
         saver.writeTypeData(type);
@@ -1101,1841 +910,6 @@
         }
     }
 
-    private class XsbReader {
-        LongUTFDataInputStream _input;
-        LongUTFDataOutputStream _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 LongUTFDataInputStream(rawinput);
-            _handle = handle;
-
-            int magic = readInt();
-            if (magic != DATA_BABE) {
-                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", _name, handle, SchemaTypeLoaderException.WRONG_MAGIC_COOKIE);
-            }
-
-            _majorver = readShort();
-            _minorver = readShort();
-
-            if (_majorver != MAJOR_VERSION) {
-                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong major version - expecting " + MAJOR_VERSION + ", got " + _majorver, _name, handle, SchemaTypeLoaderException.WRONG_MAJOR_VERSION);
-            }
-
-            if (_minorver > MINOR_VERSION) {
-                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting up to " + MINOR_VERSION + ", got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
-            }
-
-            // Clip to 14 because we're not backward compatible with earlier
-            // minor versions.  Remove this when upgrading to a new major
-            // version
-
-            if (_minorver < 14) {
-                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting at least 14, got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
-            }
-
-            if (atLeast(2, 18, 0)) {
-                _releaseno = readShort();
-            }
-
-            int actualfiletype = readShort();
-            if (actualfiletype != filetype && filetype != 0xFFFF) {
-                throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, _name, handle, SchemaTypeLoaderException.WRONG_FILE_TYPE);
-            }
-
-            _stringPool = new StringPool(_handle, _name);
-            _stringPool.readFrom(_input);
-
-            _actualfiletype = actualfiletype;
-        }
-
-        protected boolean atLeast(int majorver, int minorver, int releaseno) {
-            if (_majorver > majorver) {
-                return true;
-            }
-            if (_majorver < majorver) {
-                return false;
-            }
-            if (_minorver > minorver) {
-                return true;
-            }
-            if (_minorver < minorver) {
-                return false;
-            }
-            return (_releaseno >= releaseno);
-        }
-
-        protected boolean atMost(int majorver, int minorver, int releaseno) {
-            if (_majorver > majorver) {
-                return false;
-            }
-            if (_majorver < majorver) {
-                return true;
-            }
-            if (_minorver > minorver) {
-                return false;
-            }
-            if (_minorver < minorver) {
-                return true;
-            }
-            return (_releaseno <= releaseno);
-        }
-
-        int getActualFiletype() {
-            return _actualfiletype;
-        }
-
-        XsbReader(String handle) {
-            _handle = handle;
-            _stringPool = new StringPool(_handle, _name);
-        }
-
-        void writeRealHeader(String handle, int filetype) {
-            // hackeroo: if handle contains a "/" it's not relative.
-            String resourcename;
-
-            if (handle.indexOf('/') >= 0) {
-                resourcename = handle + ".xsb";
-            } else {
-                resourcename = _basePackage + handle + ".xsb";
-            }
-
-            OutputStream rawoutput = getSaverStream(resourcename);
-            if (rawoutput == null) {
-                throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NOT_WRITEABLE);
-            }
-
-            _output = new LongUTFDataOutputStream(rawoutput);
-            _handle = handle;
-
-            writeInt(DATA_BABE);
-            writeShort(MAJOR_VERSION);
-            writeShort(MINOR_VERSION);
-            writeShort(RELEASE_NUMBER);
-            writeShort(filetype);
-
-            _stringPool.writeTo(_output);
-        }
-
-        void readEnd() {
-            try {
-                if (_input != null) {
-                    _input.close();
-                }
-            } catch (IOException e) {
-                // oh, well.
-            }
-            _input = null;
-            _stringPool = null;
-            _handle = null;
-        }
-
-        void writeEnd() {
-            try {
-                if (_output != null) {
-                    _output.flush();
-                    _output.close();
-                }
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-            _output = null;
-            _stringPool = null;
-            _handle = null;
-        }
-
-        int fileTypeFromComponentType(int componentType) {
-            switch (componentType) {
-                case SchemaComponent.TYPE:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMATYPE;
-                case SchemaComponent.ELEMENT:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAELEMENT;
-                case SchemaComponent.ATTRIBUTE:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTE;
-                case SchemaComponent.MODEL_GROUP:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAMODELGROUP;
-                case SchemaComponent.ATTRIBUTE_GROUP:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTEGROUP;
-                case SchemaComponent.IDENTITY_CONSTRAINT:
-                    return SchemaTypeSystemImpl.FILETYPE_SCHEMAIDENTITYCONSTRAINT;
-                default:
-                    throw new IllegalStateException("Unexpected component type");
-            }
-        }
-
-        void writeIndexData() {
-            // has a handle pool (count, handle/type, handle/type...)
-            writeHandlePool(_localHandles);
-
-            // then a qname map of global elements (count, qname/handle, qname/handle...)
-            writeQNameMap(globalElements());
-
-            // qname map of global attributes
-            writeQNameMap(globalAttributes());
-
-            // qname map of model groups
-            writeQNameMap(modelGroups());
-
-            // qname map of attribute groups
-            writeQNameMap(attributeGroups());
-
-            // qname map of identity constraints
-            writeQNameMap(identityConstraints());
-
-            // qname map of global types
-            writeQNameMap(globalTypes());
-
-            // qname map of document types, by the qname of the contained element
-            writeDocumentTypeMap(documentTypes());
-
-            // qname map of attribute types, by the qname of the contained attribute
-            writeAttributeTypeMap(attributeTypes());
-
-            // all the types by classname
-            writeClassnameMap(_typeRefsByClassname);
-
-            // all the namespaces
-            writeNamespaces(_namespaces);
-
-            // VERSION 2.15 and newer below
-            writeQNameMap(redefinedGlobalTypes());
-            writeQNameMap(redefinedModelGroups());
-            writeQNameMap(redefinedAttributeGroups());
-            writeAnnotations(annotations());
-        }
-
-        void writeHandlePool(HandlePool pool) {
-            writeShort(pool._componentsToHandles.size());
-            pool._componentsToHandles.forEach((comp, handle) -> {
-                writeString(handle);
-                writeShort(fileTypeFromComponentType(comp.getComponentType()));
-            });
-        }
-
-        void readHandlePool(HandlePool pool) {
-            if (pool._handlesToRefs.size() != 0 || pool._started) {
-                throw new IllegalStateException("Nonempty handle set before read");
-            }
-
-            int size = readShort();
-            for (int i = 0; i < size; i++) {
-                String handle = readString();
-                int code = readShort();
-                SchemaComponent.Ref result;
-                switch (code) {
-                    case FILETYPE_SCHEMATYPE:
-                        result = new SchemaType.Ref(getTypeSystem(), handle);
-                        break;
-                    case FILETYPE_SCHEMAELEMENT:
-                        result = new SchemaGlobalElement.Ref(getTypeSystem(), handle);
-                        break;
-                    case FILETYPE_SCHEMAATTRIBUTE:
-                        result = new SchemaGlobalAttribute.Ref(getTypeSystem(), handle);
-                        break;
-                    case FILETYPE_SCHEMAMODELGROUP:
-                        result = new SchemaModelGroup.Ref(getTypeSystem(), handle);
-                        break;
-                    case FILETYPE_SCHEMAATTRIBUTEGROUP:
-                        result = new SchemaAttributeGroup.Ref(getTypeSystem(), handle);
-                        break;
-                    case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
-                        result = new SchemaIdentityConstraint.Ref(getTypeSystem(), handle);
-                        break;
-                    default:
-                        throw new SchemaTypeLoaderException("Schema index has an unrecognized entry of type " + code, _name, handle, SchemaTypeLoaderException.UNRECOGNIZED_INDEX_ENTRY);
-                }
-                pool._handlesToRefs.put(handle, result);
-            }
-        }
-
-        int readShort() {
-            try {
-                return _input.readUnsignedShort();
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        void writeShort(int s) {
-            if (s >= MAX_UNSIGNED_SHORT || s < -1) {
-                throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit unsigned short.", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
-            }
-            if (_output != null) {
-                try {
-                    _output.writeShort(s);
-                } catch (IOException e) {
-                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-                }
-            }
-        }
-
-        int readUnsignedShortOrInt() {
-            try {
-                return _input.readUnsignedShortOrInt();
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        void writeShortOrInt(int s) {
-            if (_output != null) {
-                try {
-                    _output.writeShortOrInt(s);
-                } catch (IOException e) {
-                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-                }
-            }
-        }
-
-        int readInt() {
-            try {
-                return _input.readInt();
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        void writeInt(int i) {
-            if (_output != null) {
-                try {
-                    _output.writeInt(i);
-                } catch (IOException e) {
-                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-                }
-            }
-        }
-
-        String readString() {
-            int code = readUnsignedShortOrInt();
-            return _stringPool.stringForCode(code);
-        }
-
-        void writeString(String str) {
-            int code = _stringPool.codeForString(str);
-            writeShortOrInt(code);
-        }
-
-        QName readQName() {
-            String namespace = readString();
-            String localname = readString();
-            if (localname == null) {
-                return null;
-            }
-            return new QName(namespace, localname);
-        }
-
-        void writeQName(QName qname) {
-            if (qname == null) {
-                writeString(null);
-                writeString(null);
-                return;
-            }
-            writeString(qname.getNamespaceURI());
-            writeString(qname.getLocalPart());
-        }
-
-        SOAPArrayType readSOAPArrayType() {
-            QName qName = readQName();
-            String dimensions = readString();
-            if (qName == null) {
-                return null;
-            }
-            return new SOAPArrayType(qName, dimensions);
-        }
-
-        void writeSOAPArrayType(SOAPArrayType arrayType) {
-            if (arrayType == null) {
-                writeQName(null);
-                writeString(null);
-            } else {
-                writeQName(arrayType.getQName());
-                writeString(arrayType.soap11DimensionString());
-            }
-        }
-
-        void writeAnnotation(SchemaAnnotation a) {
-            // Write attributes
-            if (a == null) {
-                writeInt(-1);
-                return;
-            }
-            SchemaAnnotation.Attribute[] attributes = a.getAttributes();
-            writeInt(attributes.length);
-            for (SchemaAnnotation.Attribute attribute : attributes) {
-                QName name = attribute.getName();
-                String value = attribute.getValue();
-                String valueURI = attribute.getValueUri();
-                writeQName(name);
-                writeString(value);
-                writeString(valueURI);
-            }
-
-            // Write documentation items
-            XmlObject[] documentationItems = a.getUserInformation();
-            writeInt(documentationItems.length);
-            XmlOptions opt = new XmlOptions().setSaveOuter().setSaveAggressiveNamespaces();
-            for (XmlObject doc : documentationItems) {
-                writeString(doc.xmlText(opt));
-            }
-
-            // Write application info items
-            XmlObject[] appInfoItems = a.getApplicationInformation();
-            writeInt(appInfoItems.length);
-            for (XmlObject doc : appInfoItems) {
-                writeString(doc.xmlText(opt));
-            }
-        }
-
-        SchemaAnnotation readAnnotation(SchemaContainer c) {
-            if (!atLeast(2, 19, 0)) {
-                return null; // no annotations for this version of the file
-            }
-            // Read attributes
-            int n = readInt();
-            if (n == -1) {
-                return null;
-            }
-            SchemaAnnotation.Attribute[] attributes =
-                new SchemaAnnotation.Attribute[n];
-            for (int i = 0; i < n; i++) {
-                QName name = readQName();
-                String value = readString();
-                String valueUri = null;
-                if (atLeast(2, 24, 0)) {
-                    valueUri = readString();
-                }
-                attributes[i] = new SchemaAnnotationImpl.AttributeImpl(name, value, valueUri);
-            }
-
-            // Read documentation items
-            n = readInt();
-            String[] docStrings = new String[n];
-            for (int i = 0; i < n; i++) {
-                docStrings[i] = readString();
-            }
-
-            // Read application info items
-            n = readInt();
-            String[] appInfoStrings = new String[n];
-            for (int i = 0; i < n; i++) {
-                appInfoStrings[i] = readString();
-            }
-
-            return new SchemaAnnotationImpl(c, appInfoStrings,
-                docStrings, attributes);
-        }
-
-        void writeAnnotations(SchemaAnnotation[] anns) {
-            writeInt(anns.length);
-            for (SchemaAnnotation ann : anns) {
-                writeAnnotation(ann);
-            }
-        }
-
-        List<SchemaAnnotation> readAnnotations() {
-            int n = readInt();
-            List<SchemaAnnotation> result = new ArrayList<>(n);
-            // BUGBUG(radup)
-            SchemaContainer container = getContainerNonNull("");
-            for (int i = 0; i < n; i++) {
-                result.add(readAnnotation(container));
-            }
-            return result;
-        }
-
-        SchemaComponent.Ref readHandle() {
-            String handle = readString();
-            if (handle == null) {
-                return null;
-            }
-
-            if (handle.charAt(0) != '_') {
-                return _localHandles.refForHandle(handle);
-            }
-
-            switch (handle.charAt(2)) {
-                case 'I': // _BI_ - built-in schema type system
-                    SchemaType st = (SchemaType) BuiltinSchemaTypeSystem.get().resolveHandle(handle);
-                    if (st != null) {
-                        return st.getRef();
-                    }
-                    st = (SchemaType) XQuerySchemaTypeSystem.get().resolveHandle(handle);
-                    return st.getRef();
-                case 'T': // _XT_ - external type
-                    return _linker.findTypeRef(QNameHelper.forPretty(handle, 4));
-                case 'E': // _XE_ - external element
-                    return _linker.findElementRef(QNameHelper.forPretty(handle, 4));
-                case 'A': // _XA_ - external attribute
-                    return _linker.findAttributeRef(QNameHelper.forPretty(handle, 4));
-                case 'M': // _XM_ - external model group
-                    return _linker.findModelGroupRef(QNameHelper.forPretty(handle, 4));
-                case 'N': // _XN_ - external attribute group
-                    return _linker.findAttributeGroupRef(QNameHelper.forPretty(handle, 4));
-                case 'D': // _XD_ - external identity constraint
-                    return _linker.findIdentityConstraintRef(QNameHelper.forPretty(handle, 4));
-                case 'R': // _XR_ - external ref to attribute's type
-                    // deprecated: replaced by _XY_
-                    SchemaGlobalAttribute attr = _linker.findAttribute(QNameHelper.forPretty(handle, 4));
-                    if (attr == null) {
-                        throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
-                    }
-                    return attr.getType().getRef();
-                case 'S': // _XS_ - external ref to element's type
-                    // deprecated: replaced by _XY_
-                    SchemaGlobalElement elem = _linker.findElement(QNameHelper.forPretty(handle, 4));
-                    if (elem == null) {
-                        throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
-                    }
-                    return elem.getType().getRef();
-                case 'O': // _XO_ - external ref to document type
-                    return _linker.findDocumentTypeRef(QNameHelper.forPretty(handle, 4));
-                case 'Y': // _XY_ - external ref to any possible type
-                    SchemaType type = _linker.typeForSignature(handle.substring(4));
-                    if (type == null) {
-                        throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
-                    }
-                    return type.getRef();
-                default:
-                    throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
-            }
-        }
-
-        void writeHandle(SchemaComponent comp) {
-            if (comp == null || comp.getTypeSystem() == getTypeSystem()) {
-                writeString(_localHandles.handleForComponent(comp));
-                return;
-            }
-
-            switch (comp.getComponentType()) {
-                case SchemaComponent.ATTRIBUTE:
-                    writeString("_XA_" + QNameHelper.pretty(comp.getName()));
-                    return;
-                case SchemaComponent.MODEL_GROUP:
-                    writeString("_XM_" + QNameHelper.pretty(comp.getName()));
-                    return;
-                case SchemaComponent.ATTRIBUTE_GROUP:
-                    writeString("_XN_" + QNameHelper.pretty(comp.getName()));
-                    return;
-                case SchemaComponent.ELEMENT:
-                    writeString("_XE_" + QNameHelper.pretty(comp.getName()));
-                    return;
-                case SchemaComponent.IDENTITY_CONSTRAINT:
-                    writeString("_XD_" + QNameHelper.pretty(comp.getName()));
-                    return;
-                case SchemaComponent.TYPE:
-                    SchemaType type = (SchemaType) comp;
-                    if (type.isBuiltinType()) {
-                        writeString("_BI_" + type.getName().getLocalPart());
-                        return;
-                    }
-
-                    // fix for CR120759 - added output of types _XR_ & _XS_
-                    // when an attribute (_XR_) or element (_XS_) declaration
-                    // uses ref to refer to an attribute or element in another
-                    // schema and the type of that attribute or element
-                    // is an anonymous (local) type
-                    // kkrouse 02/1/2005: _XR_ and _XS_ refs are replaced by _XY_
-                    if (type.getName() != null) {
-                        writeString("_XT_" + QNameHelper.pretty(type.getName()));
-                    } else if (type.isDocumentType()) {
-                        // Substitution groups will create document types that
-                        // extend from other document types, possibly in
-                        // different jars
-                        writeString("_XO_" + QNameHelper.pretty(type.getDocumentElementName()));
-                    } else {
-                        // fix for XMLBEANS-105:
-                        // save out the external type reference using the type's signature.
-                        writeString("_XY_" + type.toString());
-                    }
-
-                    return;
-
-                default:
-                    assert (false);
-                    throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
-            }
-        }
-
-        SchemaType.Ref readTypeRef() {
-            return (SchemaType.Ref) readHandle();
-        }
-
-        void writeType(SchemaType type) {
-            writeHandle(type);
-        }
-
-        Map<QName, SchemaComponent.Ref> readQNameRefMap() {
-            Map<QName, SchemaComponent.Ref> result = new HashMap<>();
-            int size = readShort();
-            for (int i = 0; i < size; i++) {
-                QName name = readQName();
-                SchemaComponent.Ref obj = readHandle();
-                result.put(name, obj);
-            }
-            return result;
-        }
-
-        List<SchemaComponent.Ref> readQNameRefMapAsList(List<QName> names) {
-            int size = readShort();
-            List<SchemaComponent.Ref> result = new ArrayList<>(size);
-            for (int i = 0; i < size; i++) {
-                QName name = readQName();
-                SchemaComponent.Ref obj = readHandle();
-                result.add(obj);
-                names.add(name);
-            }
-            return result;
-        }
-
-        void writeQNameMap(SchemaComponent[] components) {
-            writeShort(components.length);
-            for (SchemaComponent component : components) {
-                writeQName(component.getName());
-                writeHandle(component);
-            }
-        }
-
-        void writeDocumentTypeMap(SchemaType[] doctypes) {
-            writeShort(doctypes.length);
-            for (SchemaType doctype : doctypes) {
-                writeQName(doctype.getDocumentElementName());
-                writeHandle(doctype);
-            }
-        }
-
-        void writeAttributeTypeMap(SchemaType[] attrtypes) {
-            writeShort(attrtypes.length);
-            for (SchemaType attrtype : attrtypes) {
-                writeQName(attrtype.getAttributeTypeAttributeName());
-                writeHandle(attrtype);
-            }
-        }
-
-        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 (SchemaType schemaType : array) {
-                writeHandle(schemaType);
-            }
-        }
-
-        Map<String, SchemaComponent.Ref> readClassnameRefMap() {
-            Map<String, SchemaComponent.Ref> 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<String, SchemaComponent.Ref> typesByClass) {
-            writeShort(typesByClass.size());
-            typesByClass.forEach((className, ref) -> {
-                writeString(className);
-                writeHandle(((SchemaType.Ref) ref).get());
-            });
-        }
-
-        Set<String> readNamespaces() {
-            Set<String> result = new HashSet<>();
-            int size = readShort();
-            for (int i = 0; i < size; i++) {
-                String ns = readString();
-                result.add(ns);
-            }
-            return result;
-        }
-
-        void writeNamespaces(Set<String> namespaces) {
-            writeShort(namespaces.size());
-            namespaces.forEach(this::writeString);
-        }
-
-        OutputStream getSaverStream(String name) {
-            try {
-                return _filer.createBinaryFile(name);
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        InputStream getLoaderStream(String resourcename) {
-            return _resourceLoader.getResourceAsStream(resourcename);
-        }
-
-        void checkContainerNotNull(SchemaContainer container, QName name) {
-            if (container == null) {
-                throw new LinkageError("Loading of resource " + name + '.' + _handle +
-                                       "failed, information from " + name + ".index.xsb is " +
-                                       " out of sync (or conflicting index files found)");
-            }
-        }
-
-        /**
-         * Finishes loading an element after the header has already been loaded.
-         */
-        public SchemaGlobalElement finishLoadingElement() {
-            try {
-                int particleType = readShort();
-                if (particleType != SchemaParticle.ELEMENT) {
-                    throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
-                }
-                int particleFlags = readShort();
-                BigInteger minOccurs = readBigInteger();
-                BigInteger maxOccurs = readBigInteger();
-                QNameSet transitionRules = readQNameSet();
-                QName name = readQName();
-                SchemaContainer container = getContainer(name.getNamespaceURI());
-                checkContainerNotNull(container, name);
-                SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(container);
-                impl.setParticleType(particleType);
-                impl.setMinOccurs(minOccurs);
-                impl.setMaxOccurs(maxOccurs);
-                impl.setTransitionRules(transitionRules,
-                    (particleFlags & FLAG_PART_SKIPPABLE) != 0);
-                impl.setNameAndTypeRef(name, readTypeRef());
-                impl.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
-                if (atLeast(2, 16, 0)) {
-                    impl.setDefaultValue(readXmlValueObject());
-                }
-                impl.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
-                impl.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
-                    (particleFlags & FLAG_PART_BLOCKREST) != 0,
-                    (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
-                impl.setWsdlArrayType(readSOAPArrayType());
-                impl.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
-                impl.setAnnotation(readAnnotation(container));
-                impl.setFinal(
-                    (particleFlags & FLAG_PART_FINALEXT) != 0,
-                    (particleFlags & FLAG_PART_FINALREST) != 0);
-
-                if (atLeast(2, 17, 0)) {
-                    impl.setSubstitutionGroup((SchemaGlobalElement.Ref) readHandle());
-                }
-
-                int substGroupCount = readShort();
-                for (int i = 0; i < substGroupCount; i++) {
-                    impl.addSubstitutionGroupMember(readQName());
-                }
-                SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
-
-                for (int i = 0; i < idcs.length; i++) {
-                    idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
-                }
-
-                impl.setIdentityConstraints(idcs);
-                impl.setFilename(readString());
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, null, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        public SchemaGlobalAttribute finishLoadingAttribute() {
-            try {
-                QName name = readQName();
-                SchemaContainer container = getContainer(name.getNamespaceURI());
-                checkContainerNotNull(container, name);
-                SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(container);
-                loadAttribute(impl, name, container);
-                impl.setFilename(readString());
-
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        SchemaModelGroup finishLoadingModelGroup() {
-            QName name = readQName();
-            SchemaContainer container = getContainer(name.getNamespaceURI());
-            checkContainerNotNull(container, name);
-            SchemaModelGroupImpl impl = new SchemaModelGroupImpl(container);
-
-            try {
-                impl.init(name, readString(), readShort() == 1,
-                    atLeast(2, 22, 0) ? readString() : null,
-                    atLeast(2, 22, 0) ? readString() : null,
-                    atLeast(2, 15, 0) && readShort() == 1,
-                    GroupDocument.Factory.parse(readString()).getGroup(), readAnnotation(container), null);
-                if (atLeast(2, 21, 0)) {
-                    impl.setFilename(readString());
-                }
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        SchemaIdentityConstraint finishLoadingIdentityConstraint() {
-            try {
-                QName name = readQName();
-                SchemaContainer container = getContainer(name.getNamespaceURI());
-                checkContainerNotNull(container, name);
-                SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(container);
-                impl.setName(name);
-                impl.setConstraintCategory(readShort());
-                impl.setSelector(readString());
-                impl.setAnnotation(readAnnotation(container));
-
-                String[] fields = new String[readShort()];
-                for (int i = 0; i < fields.length; i++) {
-                    fields[i] = readString();
-                }
-                impl.setFields(fields);
-
-                if (impl.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
-                    impl.setReferencedKey((SchemaIdentityConstraint.Ref) readHandle());
-                }
-
-                int mapCount = readShort();
-                Map<String, String> nsMappings = new HashMap<>();
-                for (int i = 0; i < mapCount; i++) {
-                    String prefix = readString();
-                    String uri = readString();
-                    nsMappings.put(prefix, uri);
-                }
-                impl.setNSMap(nsMappings);
-
-                if (atLeast(2, 21, 0)) {
-                    impl.setFilename(readString());
-                }
-
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        SchemaAttributeGroup finishLoadingAttributeGroup() {
-            QName name = readQName();
-            SchemaContainer container = getContainer(name.getNamespaceURI());
-            checkContainerNotNull(container, name);
-            SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(container);
-
-            try {
-                impl.init(name, readString(), readShort() == 1,
-                    atLeast(2, 22, 0) ? readString() : null,
-                    atLeast(2, 15, 0) && readShort() == 1,
-                    AttributeGroupDocument.Factory.parse(readString()).getAttributeGroup(),
-                    readAnnotation(container), null);
-                if (atLeast(2, 21, 0)) {
-                    impl.setFilename(readString());
-                }
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        public SchemaType finishLoadingType() {
-            try {
-                SchemaContainer cNonNull = getContainerNonNull(""); //HACKHACK
-                SchemaTypeImpl impl = new SchemaTypeImpl(cNonNull, true);
-                impl.setName(readQName());
-                impl.setOuterSchemaTypeRef(readTypeRef());
-                impl.setBaseDepth(readShort());
-                impl.setBaseTypeRef(readTypeRef());
-                impl.setDerivationType(readShort());
-                impl.setAnnotation(readAnnotation(null));
-
-                switch (readShort()) {
-                    case FIELD_GLOBAL:
-                        impl.setContainerFieldRef(readHandle());
-                        break;
-                    case FIELD_LOCALATTR:
-                        impl.setContainerFieldIndex((short) 1, readShort());
-                        break;
-                    case FIELD_LOCALELT:
-                        impl.setContainerFieldIndex((short) 2, readShort());
-                        break;
-                }
-                // TODO (radup) find the right solution here
-                String jn = readString();
-                impl.setFullJavaName(jn == null ? "" : jn);
-                jn = readString();
-                impl.setFullJavaImplName(jn == null ? "" : jn);
-
-                impl.setAnonymousTypeRefs(readTypeRefArray());
-
-                impl.setAnonymousUnionMemberOrdinal(readShort());
-
-                int flags;
-                flags = readInt();
-
-
-                boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0);
-                impl.setCompiled((flags & FLAG_COMPILED) != 0);
-                impl.setDocumentType((flags & FLAG_DOCUMENT_TYPE) != 0);
-                impl.setAttributeType((flags & FLAG_ATTRIBUTE_TYPE) != 0);
-                impl.setSimpleType(!isComplexType);
-
-                int complexVariety = SchemaType.NOT_COMPLEX_TYPE;
-                if (isComplexType) {
-                    impl.setAbstractFinal((flags & FLAG_ABSTRACT) != 0,
-                        (flags & FLAG_FINAL_EXT) != 0,
-                        (flags & FLAG_FINAL_REST) != 0,
-                        (flags & FLAG_FINAL_LIST) != 0,
-                        (flags & FLAG_FINAL_UNION) != 0);
-                    impl.setBlock((flags & FLAG_BLOCK_EXT) != 0,
-                        (flags & FLAG_BLOCK_REST) != 0);
-
-                    impl.setOrderSensitive((flags & FLAG_ORDER_SENSITIVE) != 0);
-                    complexVariety = readShort();
-                    impl.setComplexTypeVariety(complexVariety);
-
-                    if (atLeast(2, 23, 0)) {
-                        impl.setContentBasedOnTypeRef(readTypeRef());
-                    }
-
-                    // Attribute Model Table
-                    SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl();
-
-                    int attrCount = readShort();
-                    for (int i = 0; i < attrCount; i++) {
-                        attrModel.addAttribute(readAttributeData());
-                    }
-
-                    attrModel.setWildcardSet(readQNameSet());
-                    attrModel.setWildcardProcess(readShort());
-
-                    // Attribute Property Table
-                    Map<QName, SchemaProperty> attrProperties = new LinkedHashMap<>();
-                    int attrPropCount = readShort();
-                    for (int i = 0; i < attrPropCount; i++) {
-                        SchemaProperty prop = readPropertyData();
-                        if (!prop.isAttribute()) {
-                            throw new SchemaTypeLoaderException("Attribute property " + i + " is not an attribute", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
-                        }
-                        attrProperties.put(prop.getName(), prop);
-                    }
-
-                    SchemaParticle contentModel = null;
-                    Map<QName, SchemaProperty> elemProperties = null;
-                    int isAll = 0;
-
-                    if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT) {
-                        // Content Model Tree
-                        isAll = readShort();
-                        SchemaParticle[] parts = readParticleArray();
-                        if (parts.length == 1) {
-                            contentModel = parts[0];
-                        } else if (parts.length == 0) {
-                            contentModel = null;
-                        } else {
-                            throw new SchemaTypeLoaderException("Content model not well-formed", _name, _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL);
-                        }
-
-                        // Element Property Table
-
-                        elemProperties = new LinkedHashMap<>();
-                        int elemPropCount = readShort();
-                        for (int i = 0; i < elemPropCount; i++) {
-                            SchemaProperty prop = readPropertyData();
-                            if (prop.isAttribute()) {
-                                throw new SchemaTypeLoaderException("Element property " + i + " is not an element", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
-                            }
-                            elemProperties.put(prop.getName(), prop);
-                        }
-                    }
-
-                    impl.setContentModel(contentModel, attrModel, elemProperties, attrProperties, isAll == 1);
-                    StscComplexTypeResolver.WildcardResult wcElt = StscComplexTypeResolver.summarizeEltWildcards(contentModel);
-                    StscComplexTypeResolver.WildcardResult wcAttr = StscComplexTypeResolver.summarizeAttrWildcards(attrModel);
-                    impl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards);
-                }
-
-                if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT) {
-                    int simpleVariety = readShort();
-                    impl.setSimpleTypeVariety(simpleVariety);
-
-                    boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0);
-
-                    impl.setOrdered((flags & FLAG_ORDERED) != 0 ? SchemaType.UNORDERED : ((flags & FLAG_TOTAL_ORDER) != 0 ? SchemaType.TOTAL_ORDER : SchemaType.PARTIAL_ORDER));
-                    impl.setBounded((flags & FLAG_BOUNDED) != 0);
-                    impl.setFinite((flags & FLAG_FINITE) != 0);
-                    impl.setNumeric((flags & FLAG_NUMERIC) != 0);
-                    impl.setUnionOfLists((flags & FLAG_UNION_OF_LISTS) != 0);
-                    impl.setSimpleFinal((flags & FLAG_FINAL_REST) != 0,
-                        (flags & FLAG_FINAL_LIST) != 0,
-                        (flags & FLAG_FINAL_UNION) != 0);
-
-                    XmlValueRef[] facets = new XmlValueRef[SchemaType.LAST_FACET + 1];
-                    boolean[] fixedFacets = new boolean[SchemaType.LAST_FACET + 1];
-                    int facetCount = readShort();
-                    for (int i = 0; i < facetCount; i++) {
-                        int facetCode = readShort();
-                        facets[facetCode] = readXmlValueObject();
-                        fixedFacets[facetCode] = (readShort() == 1);
-                    }
-                    impl.setBasicFacets(facets, fixedFacets);
-
-                    impl.setWhiteSpaceRule(readShort());
-
-                    impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0);
-
-                    int patternCount = readShort();
-                    org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = new org.apache.xmlbeans.impl.regex.RegularExpression[patternCount];
-                    for (int i = 0; i < patternCount; i++) {
-                        patterns[i] = new org.apache.xmlbeans.impl.regex.RegularExpression(readString(), "X");
-                    }
-                    impl.setPatterns(patterns);
-
-                    int enumCount = readShort();
-                    XmlValueRef[] enumValues = new XmlValueRef[enumCount];
-                    for (int i = 0; i < enumCount; i++) {
-                        enumValues[i] = readXmlValueObject();
-                    }
-                    impl.setEnumerationValues(enumCount == 0 ? null : enumValues);
-
-                    impl.setBaseEnumTypeRef(readTypeRef());
-                    if (isStringEnum) {
-                        int seCount = readUnsignedShortOrInt();
-                        SchemaStringEnumEntry[] entries = new SchemaStringEnumEntry[seCount];
-                        for (int i = 0; i < seCount; i++) {
-                            entries[i] = new SchemaStringEnumEntryImpl(readString(), readShort(), readString());
-                        }
-                        impl.setStringEnumEntries(entries);
-                    }
-
-                    switch (simpleVariety) {
-                        case SchemaType.ATOMIC:
-                            impl.setPrimitiveTypeRef(readTypeRef());
-                            impl.setDecimalSize(readInt());
-                            break;
-
-                        case SchemaType.LIST:
-                            impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
-                            impl.setListItemTypeRef(readTypeRef());
-                            break;
-
-                        case SchemaType.UNION:
-                            impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
-                            impl.setUnionMemberTypeRefs(readTypeRefArray());
-                            break;
-
-                        default:
-                            throw new SchemaTypeLoaderException("Simple type does not have a recognized variety", _name, _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY);
-                    }
-                }
-
-                impl.setFilename(readString());
-                // Set the container for global, attribute or document types
-                if (impl.getName() != null) {
-                    SchemaContainer container = getContainer(impl.getName().getNamespaceURI());
-                    checkContainerNotNull(container, impl.getName());
-                    impl.setContainer(container);
-                } else if (impl.isDocumentType()) {
-                    QName name = impl.getDocumentElementName();
-                    if (name != null) {
-                        SchemaContainer container = getContainer(name.getNamespaceURI());
-                        checkContainerNotNull(container, name);
-                        impl.setContainer(container);
-                    }
-                } else if (impl.isAttributeType()) {
-                    QName name = impl.getAttributeTypeAttributeName();
-                    if (name != null) {
-                        SchemaContainer container = getContainer(name.getNamespaceURI());
-                        checkContainerNotNull(container, name);
-                        impl.setContainer(container);
-                    }
-                }
-
-                return impl;
-            } catch (SchemaTypeLoaderException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
-            } finally {
-                readEnd();
-            }
-        }
-
-        void writeTypeData(SchemaType type) {
-            writeQName(type.getName());
-            writeType(type.getOuterType());
-            writeShort(((SchemaTypeImpl) type).getBaseDepth());
-            writeType(type.getBaseType());
-            writeShort(type.getDerivationType());
-            writeAnnotation(type.getAnnotation());
-            if (type.getContainerField() == null) {
-                writeShort(FIELD_NONE);
-            } else if (type.getOuterType().isAttributeType() || type.getOuterType().isDocumentType()) {
-                writeShort(FIELD_GLOBAL);
-                writeHandle((SchemaComponent) type.getContainerField());
-            } else if (type.getContainerField().isAttribute()) {
-                writeShort(FIELD_LOCALATTR);
-                writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalAttribute((SchemaLocalAttribute) type.getContainerField()));
-            } else {
-                writeShort(FIELD_LOCALELT);
-                writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalElement((SchemaLocalElement) type.getContainerField()));
-            }
-            writeString(type.getFullJavaName());
-            writeString(type.getFullJavaImplName());
-            writeTypeArray(type.getAnonymousTypes());
-            writeShort(type.getAnonymousUnionMemberOrdinal());
-
-            int flags = 0;
-            if (type.isSimpleType()) {
-                flags |= FLAG_SIMPLE_TYPE;
-            }
-            if (type.isDocumentType()) {
-                flags |= FLAG_DOCUMENT_TYPE;
-            }
-            if (type.isAttributeType()) {
-                flags |= FLAG_ATTRIBUTE_TYPE;
-            }
-            if (type.ordered() != SchemaType.UNORDERED) {
-                flags |= FLAG_ORDERED;
-            }
-            if (type.ordered() == SchemaType.TOTAL_ORDER) {
-                flags |= FLAG_TOTAL_ORDER;
-            }
-            if (type.isBounded()) {
-                flags |= FLAG_BOUNDED;
-            }
-            if (type.isFinite()) {
-                flags |= FLAG_FINITE;
-            }
-            if (type.isNumeric()) {
-                flags |= FLAG_NUMERIC;
-            }
-            if (type.hasStringEnumValues()) {
-                flags |= FLAG_STRINGENUM;
-            }
-            if (((SchemaTypeImpl) type).isUnionOfLists()) {
-                flags |= FLAG_UNION_OF_LISTS;
-            }
-            if (type.hasPatternFacet()) {
-                flags |= FLAG_HAS_PATTERN;
-            }
-            if (type.isOrderSensitive()) {
-                flags |= FLAG_ORDER_SENSITIVE;
-            }
-
-            if (type.blockExtension()) {
-                flags |= FLAG_BLOCK_EXT;
-            }
-            if (type.blockRestriction()) {
-                flags |= FLAG_BLOCK_REST;
-            }
-            if (type.finalExtension()) {
-                flags |= FLAG_FINAL_EXT;
-            }
-            if (type.finalRestriction()) {
-                flags |= FLAG_FINAL_EXT;
-            }
-            if (type.finalList()) {
-                flags |= FLAG_FINAL_LIST;
-            }
-            if (type.finalUnion()) {
-                flags |= FLAG_FINAL_UNION;
-            }
-            if (type.isAbstract()) {
-                flags |= FLAG_ABSTRACT;
-            }
-
-            writeInt(flags);
-
-            if (!type.isSimpleType()) {
-                writeShort(type.getContentType());
-
-                writeType(type.getContentBasedOnType());
-
-                // Attribute Model Table
-                SchemaAttributeModel attrModel = type.getAttributeModel();
-                SchemaLocalAttribute[] attrs = attrModel.getAttributes();
-
-                writeShort(attrs.length);
-                for (SchemaLocalAttribute attr : attrs) {
-                    writeAttributeData(attr);
-                }
-
-                writeQNameSet(attrModel.getWildcardSet());
-                writeShort(attrModel.getWildcardProcess());
-
-                // Attribute Property Table
-                SchemaProperty[] attrProperties = type.getAttributeProperties();
-                writeShort(attrProperties.length);
-                for (SchemaProperty attrProperty : attrProperties) {
-                    writePropertyData(attrProperty);
-                }
-
-                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 (SchemaProperty eltProperty : eltProperties) {
-                        writePropertyData(eltProperty);
-                    }
-                }
-            }
-
-            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 (org.apache.xmlbeans.impl.regex.RegularExpression pattern : patterns) {
-                    writeString(pattern.getPattern());
-                }
-
-                XmlAnySimpleType[] enumValues = type.getEnumerationValues();
-                if (enumValues == null) {
-                    writeShort(0);
-                } else {
-                    writeShortOrInt(enumValues.length);
-                    for (XmlAnySimpleType enumValue : enumValues) {
-                        writeXmlValueObject(enumValue);
-                    }
-                }
-
-                // new for version 2.3
-                writeType(type.getBaseEnumType());
-                if (type.hasStringEnumValues()) {
-                    SchemaStringEnumEntry[] entries = type.getStringEnumEntries();
-                    writeShort(entries.length);
-                    for (SchemaStringEnumEntry entry : entries) {
-                        writeString(entry.getString());
-                        writeShort(entry.getIntValue());
-                        writeString(entry.getEnumName());
-                    }
-                }
-
-                switch (type.getSimpleVariety()) {
-                    case SchemaType.ATOMIC:
-                        writeType(type.getPrimitiveType());
-                        writeInt(type.getDecimalSize());
-                        break;
-
-                    case SchemaType.LIST:
-                        writeType(type.getListItemType());
-                        break;
-
-                    case SchemaType.UNION:
-                        writeTypeArray(type.getUnionMemberTypes());
-                        break;
-                }
-            }
-
-            writeString(type.getSourceName());
-        }
-
-        /*
-        void readExtensionsList() {
-            int count = readShort();
-            assert count == 0;
-
-            for (int i = 0; i < count; i++) {
-                readString();
-                readString();
-                readString();
-            }
-        }
-         */
-
-        SchemaLocalAttribute readAttributeData() {
-            SchemaLocalAttributeImpl result = new SchemaLocalAttributeImpl();
-            loadAttribute(result, readQName(), null);
-            return result;
-        }
-
-
-        void loadAttribute(SchemaLocalAttributeImpl result, QName name, SchemaContainer container) {
-            // name, type, use, deftext, defval, fixed, soaparraytype, annotation
-            result.init(name, readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType(), readAnnotation(container), null);
-        }
-
-        void writeAttributeData(SchemaLocalAttribute attr) {
-            writeQName(attr.getName());
-            writeType(attr.getType());
-            writeShort(attr.getUse());
-            writeString(attr.getDefaultText());
-            writeXmlValueObject(attr.getDefaultValue());
-            writeShort(attr.isFixed() ? 1 : 0);
-            writeSOAPArrayType(((SchemaWSDLArrayType) attr).getWSDLArrayType());
-            writeAnnotation(attr.getAnnotation());
-        }
-
-        void writeIdConstraintData(SchemaIdentityConstraint idc) {
-            writeQName(idc.getName());
-            writeShort(idc.getConstraintCategory());
-            writeString(idc.getSelector());
-            writeAnnotation(idc.getAnnotation());
-
-            String[] fields = idc.getFields();
-            writeShort(fields.length);
-            for (String field : fields) {
-                writeString(field);
-            }
-
-
-            if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
-                writeHandle(idc.getReferencedKey());
-            }
-
-            Map<String, String> mappings = idc.getNSMap();
-            writeShort(mappings.size());
-            mappings.forEach((prefix, uri) -> {
-                writeString(prefix);
-                writeString(uri);
-            });
-            writeString(idc.getSourceName());
-        }
-
-        SchemaParticle[] readParticleArray() {
-            SchemaParticle[] result = new SchemaParticle[readShort()];
-            for (int i = 0; i < result.length; i++) {
-                result[i] = readParticleData();
-            }
-            return result;
-        }
-
-        void writeParticleArray(SchemaParticle[] spa) {
-            writeShort(spa.length);
-            for (SchemaParticle schemaParticle : spa) {
-                writeParticleData(schemaParticle);
-            }
-        }
-
-        SchemaParticle readParticleData() {
-            int particleType = readShort();
-            SchemaParticleImpl result;
-            if (particleType != SchemaParticle.ELEMENT) {
-                result = new SchemaParticleImpl();
-            } else {
-                result = new SchemaLocalElementImpl();
-            }
-            loadParticle(result, particleType);
-            return result;
-        }
-
-        void loadParticle(SchemaParticleImpl result, int particleType) {
-            int particleFlags = readShort();
-
-            result.setParticleType(particleType);
-            result.setMinOccurs(readBigInteger());
-            result.setMaxOccurs(readBigInteger());
-
-            result.setTransitionRules(readQNameSet(),
-                (particleFlags & FLAG_PART_SKIPPABLE) != 0);
-
-            switch (particleType) {
-                case SchemaParticle.WILDCARD:
-                    result.setWildcardSet(readQNameSet());
-                    result.setWildcardProcess(readShort());
-                    break;
-
-                case SchemaParticle.ELEMENT:
-                    SchemaLocalElementImpl lresult = (SchemaLocalElementImpl) result;
-                    lresult.setNameAndTypeRef(readQName(), readTypeRef());
-                    lresult.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
-                    if (atLeast(2, 16, 0)) {
-                        lresult.setDefaultValue(readXmlValueObject());
-                    }
-                    lresult.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
-                    lresult.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
-                        (particleFlags & FLAG_PART_BLOCKREST) != 0,
-                        (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
-                    lresult.setWsdlArrayType(readSOAPArrayType());
-                    lresult.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
-                    lresult.setAnnotation(readAnnotation(null));
-
-                    SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
-
-                    for (int i = 0; i < idcs.length; i++) {
-                        idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
-                    }
-
-                    lresult.setIdentityConstraints(idcs);
-
-                    break;
-
-                case SchemaParticle.ALL:
-                case SchemaParticle.SEQUENCE:
-                case SchemaParticle.CHOICE:
-                    result.setParticleChildren(readParticleArray());
-                    break;
-
-                default:
-                    throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
-            }
-        }
-
-        void writeParticleData(SchemaParticle part) {
-            writeShort(part.getParticleType());
-            short flags = 0;
-            if (part.isSkippable()) {
-                flags |= FLAG_PART_SKIPPABLE;
-            }
-            if (part.getParticleType() == SchemaParticle.ELEMENT) {
-                SchemaLocalElement lpart = (SchemaLocalElement) part;
-                if (lpart.isFixed()) {
-                    flags |= FLAG_PART_FIXED;
-                }
-                if (lpart.isNillable()) {
-                    flags |= FLAG_PART_NILLABLE;
-                }
-                if (lpart.blockExtension()) {
-                    flags |= FLAG_PART_BLOCKEXT;
-                }
-                if (lpart.blockRestriction()) {
-                    flags |= FLAG_PART_BLOCKREST;
-                }
-                if (lpart.blockSubstitution()) {
-                    flags |= FLAG_PART_BLOCKSUBST;
-                }
-                if (lpart.isAbstract()) {
-                    flags |= FLAG_PART_ABSTRACT;
-                }
-
-                if (lpart instanceof SchemaGlobalElement) {
-                    SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;
-                    if (gpart.finalExtension()) {
-                        flags |= FLAG_PART_FINALEXT;
-                    }
-                    if (gpart.finalRestriction()) {
-                        flags |= FLAG_PART_FINALREST;
-                    }
-                }
-            }
-            writeShort(flags);
-            writeBigInteger(part.getMinOccurs());
-            writeBigInteger(part.getMaxOccurs());
-            writeQNameSet(part.acceptedStartNames());
-
-            switch (part.getParticleType()) {
-                case SchemaParticle.WILDCARD:
-                    writeQNameSet(part.getWildcardSet());
-                    writeShort(part.getWildcardProcess());
-                    break;
-
-                case SchemaParticle.ELEMENT:
-                    SchemaLocalElement lpart = (SchemaLocalElement) part;
-                    writeQName(lpart.getName());
-                    writeType(lpart.getType());
-                    writeString(lpart.getDefaultText());
-                    writeXmlValueObject(lpart.getDefaultValue());
-                    writeSOAPArrayType(((SchemaWSDLArrayType) lpart).getWSDLArrayType());
-                    writeAnnotation(lpart.getAnnotation());
-                    if (lpart instanceof SchemaGlobalElement) {
-                        SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;
-
-                        writeHandle(gpart.substitutionGroup());
-
-                        QName[] substGroupMembers = gpart.substitutionGroupMembers();
-                        writeShort(substGroupMembers.length);
-                        for (QName substGroupMember : substGroupMembers) {
-                            writeQName(substGroupMember);
-                        }
-                    }
-
-                    SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints();
-
-                    writeShort(idcs.length);
-                    for (SchemaIdentityConstraint idc : idcs) {
-                        writeHandle(idc);
-                    }
-
-                    break;
-
-                case SchemaParticle.ALL:
-                case SchemaParticle.SEQUENCE:
-                case SchemaParticle.CHOICE:
-                    writeParticleArray(part.getParticleChildren());
-                    break;
-
-                default:
-                    throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
-            }
-        }
-
-        SchemaProperty readPropertyData() {
-            SchemaPropertyImpl prop = new SchemaPropertyImpl();
-            prop.setName(readQName());
-            prop.setTypeRef(readTypeRef());
-            int propflags = readShort();
-            prop.setAttribute((propflags & FLAG_PROP_ISATTR) != 0);
-            prop.setContainerTypeRef(readTypeRef());
-            prop.setMinOccurs(readBigInteger());
-            prop.setMaxOccurs(readBigInteger());
-            prop.setNillable(readShort());
-            prop.setDefault(readShort());
-            prop.setFixed(readShort());
-            prop.setDefaultText(readString());
-
-            prop.setJavaPropertyName(readString());
-            prop.setJavaTypeCode(readShort());
-            prop.setExtendsJava(readTypeRef(),
-                (propflags & FLAG_PROP_JAVASINGLETON) != 0,
-                (propflags & FLAG_PROP_JAVAOPTIONAL) != 0,
-                (propflags & FLAG_PROP_JAVAARRAY) != 0);
-            if (atMost(2, 19, 0)) {
-                prop.setJavaSetterDelimiter(readQNameSet());
-            }
-            if (atLeast(2, 16, 0)) {
-                prop.setDefaultValue(readXmlValueObject());
-            }
-
-            if (!prop.isAttribute() && atLeast(2, 17, 0)) {
-                int size = readShort();
-                Set<QName> qnames = new LinkedHashSet<>(size);
-                for (int i = 0; i < size; i++) {
-                    qnames.add(readQName());
-                }
-                prop.setAcceptedNames(qnames);
-            }
-            prop.setImmutable();
-            return prop;
-        }
-
-        void writePropertyData(SchemaProperty prop) {
-            writeQName(prop.getName());
-            writeType(prop.getType());
-            writeShort((prop.isAttribute() ? FLAG_PROP_ISATTR : 0) |
-                       (prop.extendsJavaSingleton() ? FLAG_PROP_JAVASINGLETON : 0) |
-                       (prop.extendsJavaOption() ? FLAG_PROP_JAVAOPTIONAL : 0) |
-                       (prop.extendsJavaArray() ? FLAG_PROP_JAVAARRAY : 0));
-            writeType(prop.getContainerType());
-            writeBigInteger(prop.getMinOccurs());
-            writeBigInteger(prop.getMaxOccurs());
-            writeShort(prop.hasNillable());
-            writeShort(prop.hasDefault());
-            writeShort(prop.hasFixed());
-            writeString(prop.getDefaultText());
-
-            writeString(prop.getJavaPropertyName());
-            writeShort(prop.getJavaTypeCode());
-            writeType(prop.javaBasedOnType());
-            writeXmlValueObject(prop.getDefaultValue());
-
-            if (!prop.isAttribute()) {
-                QName[] names = prop.acceptedNames();
-                writeShort(names.length);
-                for (QName name : names) {
-                    writeQName(name);
-                }
-            }
-        }
-
-        void writeModelGroupData(SchemaModelGroup grp) {
-            SchemaModelGroupImpl impl = (SchemaModelGroupImpl) grp;
-            writeQName(impl.getName());
-            writeString(impl.getTargetNamespace());
-            writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
-            writeString(impl.getElemFormDefault()); // new for version 2.22
-            writeString(impl.getAttFormDefault()); // new for version 2.22
-            writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
-            writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
-            writeAnnotation(impl.getAnnotation());
-            writeString(impl.getSourceName());
-        }
-
-        void writeAttributeGroupData(SchemaAttributeGroup grp) {
-            SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl) grp;
-            writeQName(impl.getName());
-            writeString(impl.getTargetNamespace());
-            writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
-            writeString(impl.getFormDefault()); // new for version 2.22
-            writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
-            writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
-            writeAnnotation(impl.getAnnotation());
-            writeString(impl.getSourceName());
-        }
-
-        XmlValueRef readXmlValueObject() {
-            SchemaType.Ref typeref = readTypeRef();
-            if (typeref == null) {
-                return null;
-            }
-            int btc = readShort();
-            switch (btc) {
-                default:
-                    assert (false);
-                case 0:
-                    return new XmlValueRef(typeref, null);
-                case 0xFFFF: {
-                    int size = readShort();
-                    List<XmlValueRef> values = new ArrayList<>();
-                    // BUGBUG: this was: writeShort(values.size());
-                    writeShort(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, 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<? extends XmlAnySimpleType> values = ((XmlObjectBase) value).xgetListValue();
-                writeShort(values.size());
-                values.forEach(this::writeXmlValueObject);
-            } else {
-                int btc = iType.getPrimitiveType().getBuiltinTypeCode();
-                writeShort(btc);
-                switch (btc) {
-                    case SchemaType.BTC_ANY_SIMPLE:
-                    case SchemaType.BTC_ANY_URI:
-                    case SchemaType.BTC_STRING:
-                    case SchemaType.BTC_DURATION:
-                    case SchemaType.BTC_DATE_TIME:
-                    case SchemaType.BTC_TIME:
-                    case SchemaType.BTC_DATE:
-                    case SchemaType.BTC_G_YEAR_MONTH:
-                    case SchemaType.BTC_G_YEAR:
-                    case SchemaType.BTC_G_MONTH_DAY:
-                    case SchemaType.BTC_G_DAY:
-                    case SchemaType.BTC_G_MONTH:
-                    case SchemaType.BTC_DECIMAL:
-                    case SchemaType.BTC_BOOLEAN:
-                        writeString(value.getStringValue());
-                        break;
-
-                    case SchemaType.BTC_BASE_64_BINARY:
-                    case SchemaType.BTC_HEX_BINARY:
-                        writeByteArray(((SimpleValue) value).getByteArrayValue());
-                        break;
-
-                    case SchemaType.BTC_QNAME:
-                    case SchemaType.BTC_NOTATION:
-                        writeQName(((SimpleValue) value).getQNameValue());
-                        break;
-
-                    case SchemaType.BTC_FLOAT:
-                        writeDouble(((SimpleValue) value).getFloatValue());
-                        break;
-
-                    case SchemaType.BTC_DOUBLE:
-                        writeDouble(((SimpleValue) value).getDoubleValue());
-                        break;
-                }
-            }
-        }
-
-        double readDouble() {
-            try {
-                return _input.readDouble();
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        void writeDouble(double d) {
-            if (_output != null) {
-                try {
-                    _output.writeDouble(d);
-                } catch (IOException e) {
-                    throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-                }
-            }
-        }
-
-        QNameSet readQNameSet() {
-            int flag = readShort();
-
-            Set<String> uriSet = new HashSet<>();
-            int uriCount = readShort();
-            for (int i = 0; i < uriCount; i++) {
-                uriSet.add(readString());
-            }
-
-            Set<QName> qnameSet1 = new HashSet<>();
-            int qncount1 = readShort();
-            for (int i = 0; i < qncount1; i++) {
-                qnameSet1.add(readQName());
-            }
-
-            Set<QName> qnameSet2 = new HashSet<>();
-            int qncount2 = readShort();
-            for (int i = 0; i < qncount2; i++) {
-                qnameSet2.add(readQName());
-            }
-
-            if (flag == 1) {
-                return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2);
-            } else {
-                return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1);
-            }
-        }
-
-        void writeQNameSet(QNameSet set) {
-            boolean invert = (set.excludedURIs() != null);
-            writeShort(invert ? 1 : 0);
-
-            Set<String> uriSet = invert ? set.excludedURIs() : set.includedURIs();
-            assert (uriSet != null);
-            writeShort(uriSet.size());
-            uriSet.forEach(this::writeString);
-
-            Set<QName> qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs();
-            writeShort(qnameSet1.size());
-            qnameSet1.forEach(this::writeQName);
-
-            Set<QName> qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs();
-            writeShort(qnameSet2.size());
-            qnameSet2.forEach(this::writeQName);
-        }
-
-        byte[] readByteArray() {
-            try {
-                int len = _input.readShort();
-                byte[] result = new byte[len];
-                _input.readFully(result);
-                return result;
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        void writeByteArray(byte[] ba) {
-            try {
-                writeShort(ba.length);
-                if (_output != null) {
-                    _output.write(ba);
-                }
-            } catch (IOException e) {
-                throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
-            }
-        }
-
-        BigInteger readBigInteger() {
-            byte[] result = readByteArray();
-            if (result.length == 0) {
-                return null;
-            }
-            if (result.length == 1 && result[0] == 0) {
-                return BigInteger.ZERO;
-            }
-            if (result.length == 1 && result[0] == 1) {
-                return BigInteger.ONE;
-            }
-            return new BigInteger(result);
-        }
-
-        void writeBigInteger(BigInteger bi) {
-            if (bi == null) {
-                writeShort(0);
-            } else if (bi.signum() == 0) {
-                writeByteArray(SINGLE_ZERO_BYTE);
-            } else {
-                writeByteArray(bi.toByteArray());
-            }
-        }
-
-    }
-
     static final byte[] SINGLE_ZERO_BYTE = {0};
 
     public SchemaType typeForHandle(String handle) {
@@ -2956,7 +930,7 @@
             result = _resolvedHandles.get(handle);
         }
         if (result == null) {
-            XsbReader reader = new XsbReader(handle, 0xFFFF);
+            XsbReader reader = new XsbReader(getTypeSystem(), handle, 0xFFFF);
             int filetype = reader.getActualFiletype();
             switch (filetype) {
                 case FILETYPE_SCHEMATYPE:
@@ -3159,4 +1133,36 @@
         String n = m.find() ? m.group(1) : _name;
         return n.replace('.', '/');
     }
+
+    String getBasePackage() {
+        return nameToPathString(_name);
+    }
+
+    SchemaTypeLoader getLinker() {
+        return _linker;
+    }
+
+    SchemaTypePool getTypePool() {
+        return _localHandles;
+    }
+
+    Set<String> getNamespaces() {
+        return _namespaces;
+    }
+
+    Map<String, SchemaComponent.Ref> getTypeRefsByClassname() {
+        return _typeRefsByClassname;
+    }
+
+    OutputStream getSaverStream(String name, String handle) {
+        try {
+            return _filer.createBinaryFile(name);
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), getName(), handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    InputStream getLoaderStream(String resourcename) {
+        return _resourceLoader.getResourceAsStream(resourcename);
+    }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java b/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
new file mode 100644
index 0000000..1c62bef
--- /dev/null
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/XsbReader.java
@@ -0,0 +1,1803 @@
+/*   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.schema;
+
+import org.apache.xmlbeans.*;
+import org.apache.xmlbeans.impl.common.QNameHelper;
+import org.apache.xmlbeans.impl.util.LongUTFDataInputStream;
+import org.apache.xmlbeans.impl.util.LongUTFDataOutputStream;
+import org.apache.xmlbeans.impl.values.XmlObjectBase;
+import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroupDocument;
+import org.apache.xmlbeans.impl.xb.xsdschema.GroupDocument;
+import org.apache.xmlbeans.soap.SOAPArrayType;
+import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
+
+import javax.xml.namespace.QName;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.*;
+
+import static org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.*;
+
+class XsbReader {
+
+    // MAX_UNSIGNED_SHORT
+    private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1;
+
+    private final SchemaTypeSystemImpl typeSystem;
+    private LongUTFDataInputStream _input;
+    private LongUTFDataOutputStream _output;
+    private SchemaTypeSystemImpl.StringPool _stringPool;
+    private String _handle;
+    private int _majorver;
+    private int _minorver;
+    private int _releaseno;
+    int _actualfiletype;
+
+    XsbReader(SchemaTypeSystemImpl typeSystem, String handle) {
+        this.typeSystem = typeSystem;
+        _handle = handle;
+        _stringPool = new SchemaTypeSystemImpl.StringPool(_handle, typeSystem.getName());
+    }
+
+    public XsbReader(SchemaTypeSystemImpl typeSystem, String handle, int filetype) {
+        this.typeSystem = typeSystem;
+        String resourcename = typeSystem.getBasePackage()  + handle + ".xsb";
+        InputStream rawinput = typeSystem.getLoaderStream(resourcename);
+        if (rawinput == null) {
+            throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Could not locate compiled schema resource " + resourcename, typeSystem.getName(), handle, SchemaTypeLoaderException.NO_RESOURCE);
+        }
+
+        _input = new LongUTFDataInputStream(rawinput);
+        _handle = handle;
+
+        int magic = readInt();
+        if (magic != DATA_BABE) {
+            throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", typeSystem.getName(), 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, typeSystem.getName(), 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, typeSystem.getName(), 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, typeSystem.getName(), handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
+        }
+
+        if (atLeast(2, 18, 0)) {
+            _releaseno = readShort();
+        }
+
+        int actualfiletype = readShort();
+        if (actualfiletype != filetype && filetype != 0xFFFF) {
+            throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, typeSystem.getName(), handle, SchemaTypeLoaderException.WRONG_FILE_TYPE);
+        }
+
+        _stringPool = new SchemaTypeSystemImpl.StringPool(_handle, typeSystem.getName());
+        _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;
+    }
+
+    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 = typeSystem.getBasePackage() + handle + ".xsb";
+        }
+
+        OutputStream rawoutput = typeSystem.getSaverStream(resourcename, _handle);
+        if (rawoutput == null) {
+            throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, typeSystem.getName(), handle, SchemaTypeLoaderException.NOT_WRITEABLE);
+        }
+
+        _output = new LongUTFDataOutputStream(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(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+        _output = null;
+        _stringPool = null;
+        _handle = null;
+    }
+
+    void writeIndexData() {
+        // has a handle pool (count, handle/type, handle/type...)
+        typeSystem.getTypePool().writeHandlePool(this);
+
+        // then a qname map of global elements (count, qname/handle, qname/handle...)
+        writeQNameMap(typeSystem.globalElements());
+
+        // qname map of global attributes
+        writeQNameMap(typeSystem.globalAttributes());
+
+        // qname map of model groups
+        writeQNameMap(typeSystem.modelGroups());
+
+        // qname map of attribute groups
+        writeQNameMap(typeSystem.attributeGroups());
+
+        // qname map of identity constraints
+        writeQNameMap(typeSystem.identityConstraints());
+
+        // qname map of global types
+        writeQNameMap(typeSystem.globalTypes());
+
+        // qname map of document types, by the qname of the contained element
+        writeDocumentTypeMap(typeSystem.documentTypes());
+
+        // qname map of attribute types, by the qname of the contained attribute
+        writeAttributeTypeMap(typeSystem.attributeTypes());
+
+        // all the types by classname
+        writeClassnameMap(typeSystem.getTypeRefsByClassname());
+
+        // all the namespaces
+        writeNamespaces(typeSystem.getNamespaces());
+
+        // VERSION 2.15 and newer below
+        writeQNameMap(typeSystem.redefinedGlobalTypes());
+        writeQNameMap(typeSystem.redefinedModelGroups());
+        writeQNameMap(typeSystem.redefinedAttributeGroups());
+        writeAnnotations(typeSystem.annotations());
+    }
+
+    int readShort() {
+        try {
+            return _input.readUnsignedShort();
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    void writeShort(int s) {
+        if (s >= MAX_UNSIGNED_SHORT || s < -1) {
+            throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit unsigned short.", typeSystem.getName(), _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
+        }
+        if (_output != null) {
+            try {
+                _output.writeShort(s);
+            } catch (IOException e) {
+                throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+            }
+        }
+    }
+
+    int readUnsignedShortOrInt() {
+        try {
+            return _input.readUnsignedShortOrInt();
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    void writeShortOrInt(int s) {
+        if (_output != null) {
+            try {
+                _output.writeShortOrInt(s);
+            } catch (IOException e) {
+                throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+            }
+        }
+    }
+
+    int readInt() {
+        try {
+            return _input.readInt();
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    void writeInt(int i) {
+        if (_output != null) {
+            try {
+                _output.writeInt(i);
+            } catch (IOException e) {
+                throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+            }
+        }
+    }
+
+    String readString() {
+        int code = readUnsignedShortOrInt();
+        return _stringPool.stringForCode(code);
+    }
+
+    void writeString(String str) {
+        int code = _stringPool.codeForString(str);
+        writeShortOrInt(code);
+    }
+
+    QName readQName() {
+        String namespace = readString();
+        String localname = readString();
+        if (localname == null) {
+            return null;
+        }
+        return new QName(namespace, localname);
+    }
+
+    void writeQName(QName qname) {
+        if (qname == null) {
+            writeString(null);
+            writeString(null);
+            return;
+        }
+        writeString(qname.getNamespaceURI());
+        writeString(qname.getLocalPart());
+    }
+
+    SOAPArrayType readSOAPArrayType() {
+        QName qName = readQName();
+        String dimensions = readString();
+        if (qName == null) {
+            return null;
+        }
+        return new SOAPArrayType(qName, dimensions);
+    }
+
+    void writeSOAPArrayType(SOAPArrayType arrayType) {
+        if (arrayType == null) {
+            writeQName(null);
+            writeString(null);
+        } else {
+            writeQName(arrayType.getQName());
+            writeString(arrayType.soap11DimensionString());
+        }
+    }
+
+    void writeAnnotation(SchemaAnnotation a) {
+        // Write attributes
+        if (a == null) {
+            writeInt(-1);
+            return;
+        }
+        SchemaAnnotation.Attribute[] attributes = a.getAttributes();
+        writeInt(attributes.length);
+        for (SchemaAnnotation.Attribute attribute : attributes) {
+            QName name = attribute.getName();
+            String value = attribute.getValue();
+            String valueURI = attribute.getValueUri();
+            writeQName(name);
+            writeString(value);
+            writeString(valueURI);
+        }
+
+        // Write documentation items
+        XmlObject[] documentationItems = a.getUserInformation();
+        writeInt(documentationItems.length);
+        XmlOptions opt = new XmlOptions().setSaveOuter().setSaveAggressiveNamespaces();
+        for (XmlObject doc : documentationItems) {
+            writeString(doc.xmlText(opt));
+        }
+
+        // Write application info items
+        XmlObject[] appInfoItems = a.getApplicationInformation();
+        writeInt(appInfoItems.length);
+        for (XmlObject doc : appInfoItems) {
+            writeString(doc.xmlText(opt));
+        }
+    }
+
+    SchemaAnnotation readAnnotation(SchemaContainer c) {
+        if (!atLeast(2, 19, 0)) {
+            return null; // no annotations for this version of the file
+        }
+        // Read attributes
+        int n = readInt();
+        if (n == -1) {
+            return null;
+        }
+        SchemaAnnotation.Attribute[] attributes =
+            new SchemaAnnotation.Attribute[n];
+        for (int i = 0; i < n; i++) {
+            QName name = readQName();
+            String value = readString();
+            String valueUri = null;
+            if (atLeast(2, 24, 0)) {
+                valueUri = readString();
+            }
+            attributes[i] = new SchemaAnnotationImpl.AttributeImpl(name, value, valueUri);
+        }
+
+        // Read documentation items
+        n = readInt();
+        String[] docStrings = new String[n];
+        for (int i = 0; i < n; i++) {
+            docStrings[i] = readString();
+        }
+
+        // Read application info items
+        n = readInt();
+        String[] appInfoStrings = new String[n];
+        for (int i = 0; i < n; i++) {
+            appInfoStrings[i] = readString();
+        }
+
+        return new SchemaAnnotationImpl(c, appInfoStrings,
+            docStrings, attributes);
+    }
+
+    void writeAnnotations(SchemaAnnotation[] anns) {
+        writeInt(anns.length);
+        for (SchemaAnnotation ann : anns) {
+            writeAnnotation(ann);
+        }
+    }
+
+    List<SchemaAnnotation> readAnnotations() {
+        int n = readInt();
+        List<SchemaAnnotation> result = new ArrayList<>(n);
+        // BUGBUG(radup)
+        SchemaContainer container = typeSystem.getContainerNonNull("");
+        for (int i = 0; i < n; i++) {
+            result.add(readAnnotation(container));
+        }
+        return result;
+    }
+
+    SchemaComponent.Ref readHandle() {
+        String handle = readString();
+        if (handle == null) {
+            return null;
+        }
+
+        if (handle.charAt(0) != '_') {
+            return typeSystem.getTypePool().refForHandle(handle);
+        }
+
+        switch (handle.charAt(2)) {
+            case 'I': // _BI_ - built-in schema type system
+                SchemaType st = (SchemaType) BuiltinSchemaTypeSystem.get().resolveHandle(handle);
+                if (st != null) {
+                    return st.getRef();
+                }
+                st = (SchemaType) XQuerySchemaTypeSystem.get().resolveHandle(handle);
+                return st.getRef();
+            case 'T': // _XT_ - external type
+                return typeSystem.getLinker().findTypeRef(QNameHelper.forPretty(handle, 4));
+            case 'E': // _XE_ - external element
+                return typeSystem.getLinker().findElementRef(QNameHelper.forPretty(handle, 4));
+            case 'A': // _XA_ - external attribute
+                return typeSystem.getLinker().findAttributeRef(QNameHelper.forPretty(handle, 4));
+            case 'M': // _XM_ - external model group
+                return typeSystem.getLinker().findModelGroupRef(QNameHelper.forPretty(handle, 4));
+            case 'N': // _XN_ - external attribute group
+                return typeSystem.getLinker().findAttributeGroupRef(QNameHelper.forPretty(handle, 4));
+            case 'D': // _XD_ - external identity constraint
+                return typeSystem.getLinker().findIdentityConstraintRef(QNameHelper.forPretty(handle, 4));
+            case 'R': // _XR_ - external ref to attribute's type
+                // deprecated: replaced by _XY_
+                SchemaGlobalAttribute attr = typeSystem.getLinker().findAttribute(QNameHelper.forPretty(handle, 4));
+                if (attr == null) {
+                    throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+                }
+                return attr.getType().getRef();
+            case 'S': // _XS_ - external ref to element's type
+                // deprecated: replaced by _XY_
+                SchemaGlobalElement elem = typeSystem.getLinker().findElement(QNameHelper.forPretty(handle, 4));
+                if (elem == null) {
+                    throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+                }
+                return elem.getType().getRef();
+            case 'O': // _XO_ - external ref to document type
+                return typeSystem.getLinker().findDocumentTypeRef(QNameHelper.forPretty(handle, 4));
+            case 'Y': // _XY_ - external ref to any possible type
+                SchemaType type = typeSystem.getLinker().typeForSignature(handle.substring(4));
+                if (type == null) {
+                    throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+                }
+                return type.getRef();
+            default:
+                throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+        }
+    }
+
+    void writeHandle(SchemaComponent comp) {
+        if (comp == null || comp.getTypeSystem() == typeSystem) {
+            writeString(typeSystem.getTypePool().handleForComponent(comp));
+            return;
+        }
+
+        switch (comp.getComponentType()) {
+            case SchemaComponent.ATTRIBUTE:
+                writeString("_XA_" + QNameHelper.pretty(comp.getName()));
+                return;
+            case SchemaComponent.MODEL_GROUP:
+                writeString("_XM_" + QNameHelper.pretty(comp.getName()));
+                return;
+            case SchemaComponent.ATTRIBUTE_GROUP:
+                writeString("_XN_" + QNameHelper.pretty(comp.getName()));
+                return;
+            case SchemaComponent.ELEMENT:
+                writeString("_XE_" + QNameHelper.pretty(comp.getName()));
+                return;
+            case SchemaComponent.IDENTITY_CONSTRAINT:
+                writeString("_XD_" + QNameHelper.pretty(comp.getName()));
+                return;
+            case SchemaComponent.TYPE:
+                SchemaType type = (SchemaType) comp;
+                if (type.isBuiltinType()) {
+                    writeString("_BI_" + type.getName().getLocalPart());
+                    return;
+                }
+
+                // fix for CR120759 - added output of types _XR_ & _XS_
+                // when an attribute (_XR_) or element (_XS_) declaration
+                // uses ref to refer to an attribute or element in another
+                // schema and the type of that attribute or element
+                // is an anonymous (local) type
+                // kkrouse 02/1/2005: _XR_ and _XS_ refs are replaced by _XY_
+                if (type.getName() != null) {
+                    writeString("_XT_" + QNameHelper.pretty(type.getName()));
+                } else if (type.isDocumentType()) {
+                    // Substitution groups will create document types that
+                    // extend from other document types, possibly in
+                    // different jars
+                    writeString("_XO_" + QNameHelper.pretty(type.getDocumentElementName()));
+                } else {
+                    // fix for XMLBEANS-105:
+                    // save out the external type reference using the type's signature.
+                    writeString("_XY_" + type);
+                }
+
+                return;
+
+            default:
+                assert (false);
+                throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE);
+        }
+    }
+
+    SchemaType.Ref readTypeRef() {
+        return (SchemaType.Ref) readHandle();
+    }
+
+    void writeType(SchemaType type) {
+        writeHandle(type);
+    }
+
+    Map<QName, SchemaComponent.Ref> readQNameRefMap() {
+        Map<QName, SchemaComponent.Ref> result = new HashMap<>();
+        int size = readShort();
+        for (int i = 0; i < size; i++) {
+            QName name = readQName();
+            SchemaComponent.Ref obj = readHandle();
+            result.put(name, obj);
+        }
+        return result;
+    }
+
+    List<SchemaComponent.Ref> readQNameRefMapAsList(List<QName> names) {
+        int size = readShort();
+        List<SchemaComponent.Ref> result = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            QName name = readQName();
+            SchemaComponent.Ref obj = readHandle();
+            result.add(obj);
+            names.add(name);
+        }
+        return result;
+    }
+
+    void writeQNameMap(SchemaComponent[] components) {
+        writeShort(components.length);
+        for (SchemaComponent component : components) {
+            writeQName(component.getName());
+            writeHandle(component);
+        }
+    }
+
+    void writeDocumentTypeMap(SchemaType[] doctypes) {
+        writeShort(doctypes.length);
+        for (SchemaType doctype : doctypes) {
+            writeQName(doctype.getDocumentElementName());
+            writeHandle(doctype);
+        }
+    }
+
+    void writeAttributeTypeMap(SchemaType[] attrtypes) {
+        writeShort(attrtypes.length);
+        for (SchemaType attrtype : attrtypes) {
+            writeQName(attrtype.getAttributeTypeAttributeName());
+            writeHandle(attrtype);
+        }
+    }
+
+    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 (SchemaType schemaType : array) {
+            writeHandle(schemaType);
+        }
+    }
+
+    Map<String, SchemaComponent.Ref> readClassnameRefMap() {
+        Map<String, SchemaComponent.Ref> 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<String, SchemaComponent.Ref> typesByClass) {
+        writeShort(typesByClass.size());
+        typesByClass.forEach((className, ref) -> {
+            writeString(className);
+            writeHandle(((SchemaType.Ref) ref).get());
+        });
+    }
+
+    Set<String> readNamespaces() {
+        Set<String> result = new HashSet<>();
+        int size = readShort();
+        for (int i = 0; i < size; i++) {
+            String ns = readString();
+            result.add(ns);
+        }
+        return result;
+    }
+
+    void writeNamespaces(Set<String> namespaces) {
+        writeShort(namespaces.size());
+        namespaces.forEach(this::writeString);
+    }
+
+    void checkContainerNotNull(SchemaContainer container, QName name) {
+        if (container == null) {
+            throw new LinkageError("Loading of resource " + name + '.' + _handle +
+                                   "failed, information from " + name + ".index.xsb is " +
+                                   " out of sync (or conflicting index files found)");
+        }
+    }
+
+    /**
+     * Finishes loading an element after the header has already been loaded.
+     */
+    public SchemaGlobalElement finishLoadingElement() {
+        try {
+            int particleType = readShort();
+            if (particleType != SchemaParticle.ELEMENT) {
+                throw new SchemaTypeLoaderException("Wrong particle type ", typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
+            }
+            int particleFlags = readShort();
+            BigInteger minOccurs = readBigInteger();
+            BigInteger maxOccurs = readBigInteger();
+            QNameSet transitionRules = readQNameSet();
+            QName name = readQName();
+            SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+            checkContainerNotNull(container, name);
+            SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(container);
+            impl.setParticleType(particleType);
+            impl.setMinOccurs(minOccurs);
+            impl.setMaxOccurs(maxOccurs);
+            impl.setTransitionRules(transitionRules,
+                (particleFlags & FLAG_PART_SKIPPABLE) != 0);
+            impl.setNameAndTypeRef(name, readTypeRef());
+            impl.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
+            if (atLeast(2, 16, 0)) {
+                impl.setDefaultValue(readXmlValueObject());
+            }
+            impl.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
+            impl.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
+                (particleFlags & FLAG_PART_BLOCKREST) != 0,
+                (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
+            impl.setWsdlArrayType(readSOAPArrayType());
+            impl.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
+            impl.setAnnotation(readAnnotation(container));
+            impl.setFinal(
+                (particleFlags & FLAG_PART_FINALEXT) != 0,
+                (particleFlags & FLAG_PART_FINALREST) != 0);
+
+            if (atLeast(2, 17, 0)) {
+                impl.setSubstitutionGroup((SchemaGlobalElement.Ref) readHandle());
+            }
+
+            int substGroupCount = readShort();
+            for (int i = 0; i < substGroupCount; i++) {
+                impl.addSubstitutionGroupMember(readQName());
+            }
+            SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
+
+            for (int i = 0; i < idcs.length; i++) {
+                idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
+            }
+
+            impl.setIdentityConstraints(idcs);
+            impl.setFilename(readString());
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), null, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    public SchemaGlobalAttribute finishLoadingAttribute() {
+        try {
+            QName name = readQName();
+            SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+            checkContainerNotNull(container, name);
+            SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(container);
+            loadAttribute(impl, name, container);
+            impl.setFilename(readString());
+
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    SchemaModelGroup finishLoadingModelGroup() {
+        QName name = readQName();
+        SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+        checkContainerNotNull(container, name);
+        SchemaModelGroupImpl impl = new SchemaModelGroupImpl(container);
+
+        try {
+            impl.init(name, readString(), readShort() == 1,
+                atLeast(2, 22, 0) ? readString() : null,
+                atLeast(2, 22, 0) ? readString() : null,
+                atLeast(2, 15, 0) && readShort() == 1,
+                GroupDocument.Factory.parse(readString()).getGroup(), readAnnotation(container), null);
+            if (atLeast(2, 21, 0)) {
+                impl.setFilename(readString());
+            }
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    SchemaIdentityConstraint finishLoadingIdentityConstraint() {
+        try {
+            QName name = readQName();
+            SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+            checkContainerNotNull(container, name);
+            SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(container);
+            impl.setName(name);
+            impl.setConstraintCategory(readShort());
+            impl.setSelector(readString());
+            impl.setAnnotation(readAnnotation(container));
+
+            String[] fields = new String[readShort()];
+            for (int i = 0; i < fields.length; i++) {
+                fields[i] = readString();
+            }
+            impl.setFields(fields);
+
+            if (impl.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
+                impl.setReferencedKey((SchemaIdentityConstraint.Ref) readHandle());
+            }
+
+            int mapCount = readShort();
+            Map<String, String> nsMappings = new HashMap<>();
+            for (int i = 0; i < mapCount; i++) {
+                String prefix = readString();
+                String uri = readString();
+                nsMappings.put(prefix, uri);
+            }
+            impl.setNSMap(nsMappings);
+
+            if (atLeast(2, 21, 0)) {
+                impl.setFilename(readString());
+            }
+
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    SchemaAttributeGroup finishLoadingAttributeGroup() {
+        QName name = readQName();
+        SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+        checkContainerNotNull(container, name);
+        SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(container);
+
+        try {
+            impl.init(name, readString(), readShort() == 1,
+                atLeast(2, 22, 0) ? readString() : null,
+                atLeast(2, 15, 0) && readShort() == 1,
+                AttributeGroupDocument.Factory.parse(readString()).getAttributeGroup(),
+                readAnnotation(container), null);
+            if (atLeast(2, 21, 0)) {
+                impl.setFilename(readString());
+            }
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    public SchemaType finishLoadingType() {
+        try {
+            SchemaContainer cNonNull = typeSystem.getContainerNonNull(""); //HACKHACK
+            SchemaTypeImpl impl = new SchemaTypeImpl(cNonNull, true);
+            impl.setName(readQName());
+            impl.setOuterSchemaTypeRef(readTypeRef());
+            impl.setBaseDepth(readShort());
+            impl.setBaseTypeRef(readTypeRef());
+            impl.setDerivationType(readShort());
+            impl.setAnnotation(readAnnotation(null));
+
+            switch (readShort()) {
+                case FIELD_GLOBAL:
+                    impl.setContainerFieldRef(readHandle());
+                    break;
+                case FIELD_LOCALATTR:
+                    impl.setContainerFieldIndex((short) 1, readShort());
+                    break;
+                case FIELD_LOCALELT:
+                    impl.setContainerFieldIndex((short) 2, readShort());
+                    break;
+            }
+            // TODO (radup) find the right solution here
+            String jn = readString();
+            impl.setFullJavaName(jn == null ? "" : jn);
+            jn = readString();
+            impl.setFullJavaImplName(jn == null ? "" : jn);
+
+            impl.setAnonymousTypeRefs(readTypeRefArray());
+
+            impl.setAnonymousUnionMemberOrdinal(readShort());
+
+            int flags;
+            flags = readInt();
+
+
+            boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0);
+            impl.setCompiled((flags & FLAG_COMPILED) != 0);
+            impl.setDocumentType((flags & FLAG_DOCUMENT_TYPE) != 0);
+            impl.setAttributeType((flags & FLAG_ATTRIBUTE_TYPE) != 0);
+            impl.setSimpleType(!isComplexType);
+
+            int complexVariety = SchemaType.NOT_COMPLEX_TYPE;
+            if (isComplexType) {
+                impl.setAbstractFinal((flags & FLAG_ABSTRACT) != 0,
+                    (flags & FLAG_FINAL_EXT) != 0,
+                    (flags & FLAG_FINAL_REST) != 0,
+                    (flags & FLAG_FINAL_LIST) != 0,
+                    (flags & FLAG_FINAL_UNION) != 0);
+                impl.setBlock((flags & FLAG_BLOCK_EXT) != 0,
+                    (flags & FLAG_BLOCK_REST) != 0);
+
+                impl.setOrderSensitive((flags & FLAG_ORDER_SENSITIVE) != 0);
+                complexVariety = readShort();
+                impl.setComplexTypeVariety(complexVariety);
+
+                if (atLeast(2, 23, 0)) {
+                    impl.setContentBasedOnTypeRef(readTypeRef());
+                }
+
+                // Attribute Model Table
+                SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl();
+
+                int attrCount = readShort();
+                for (int i = 0; i < attrCount; i++) {
+                    attrModel.addAttribute(readAttributeData());
+                }
+
+                attrModel.setWildcardSet(readQNameSet());
+                attrModel.setWildcardProcess(readShort());
+
+                // Attribute Property Table
+                Map<QName, SchemaProperty> attrProperties = new LinkedHashMap<>();
+                int attrPropCount = readShort();
+                for (int i = 0; i < attrPropCount; i++) {
+                    SchemaProperty prop = readPropertyData();
+                    if (!prop.isAttribute()) {
+                        throw new SchemaTypeLoaderException("Attribute property " + i + " is not an attribute", typeSystem.getName(), _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
+                    }
+                    attrProperties.put(prop.getName(), prop);
+                }
+
+                SchemaParticle contentModel = null;
+                Map<QName, SchemaProperty> elemProperties = null;
+                int isAll = 0;
+
+                if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT) {
+                    // Content Model Tree
+                    isAll = readShort();
+                    SchemaParticle[] parts = readParticleArray();
+                    if (parts.length == 1) {
+                        contentModel = parts[0];
+                    } else if (parts.length == 0) {
+                        contentModel = null;
+                    } else {
+                        throw new SchemaTypeLoaderException("Content model not well-formed", typeSystem.getName(), _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL);
+                    }
+
+                    // Element Property Table
+
+                    elemProperties = new LinkedHashMap<>();
+                    int elemPropCount = readShort();
+                    for (int i = 0; i < elemPropCount; i++) {
+                        SchemaProperty prop = readPropertyData();
+                        if (prop.isAttribute()) {
+                            throw new SchemaTypeLoaderException("Element property " + i + " is not an element", typeSystem.getName(), _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
+                        }
+                        elemProperties.put(prop.getName(), prop);
+                    }
+                }
+
+                impl.setContentModel(contentModel, attrModel, elemProperties, attrProperties, isAll == 1);
+                StscComplexTypeResolver.WildcardResult wcElt = StscComplexTypeResolver.summarizeEltWildcards(contentModel);
+                StscComplexTypeResolver.WildcardResult wcAttr = StscComplexTypeResolver.summarizeAttrWildcards(attrModel);
+                impl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards);
+            }
+
+            if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT) {
+                int simpleVariety = readShort();
+                impl.setSimpleTypeVariety(simpleVariety);
+
+                boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0);
+
+                impl.setOrdered((flags & FLAG_ORDERED) != 0 ? SchemaType.UNORDERED : ((flags & FLAG_TOTAL_ORDER) != 0 ? SchemaType.TOTAL_ORDER : SchemaType.PARTIAL_ORDER));
+                impl.setBounded((flags & FLAG_BOUNDED) != 0);
+                impl.setFinite((flags & FLAG_FINITE) != 0);
+                impl.setNumeric((flags & FLAG_NUMERIC) != 0);
+                impl.setUnionOfLists((flags & FLAG_UNION_OF_LISTS) != 0);
+                impl.setSimpleFinal((flags & FLAG_FINAL_REST) != 0,
+                    (flags & FLAG_FINAL_LIST) != 0,
+                    (flags & FLAG_FINAL_UNION) != 0);
+
+                XmlValueRef[] facets = new XmlValueRef[SchemaType.LAST_FACET + 1];
+                boolean[] fixedFacets = new boolean[SchemaType.LAST_FACET + 1];
+                int facetCount = readShort();
+                for (int i = 0; i < facetCount; i++) {
+                    int facetCode = readShort();
+                    facets[facetCode] = readXmlValueObject();
+                    fixedFacets[facetCode] = (readShort() == 1);
+                }
+                impl.setBasicFacets(facets, fixedFacets);
+
+                impl.setWhiteSpaceRule(readShort());
+
+                impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0);
+
+                int patternCount = readShort();
+                org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = new org.apache.xmlbeans.impl.regex.RegularExpression[patternCount];
+                for (int i = 0; i < patternCount; i++) {
+                    patterns[i] = new org.apache.xmlbeans.impl.regex.RegularExpression(readString(), "X");
+                }
+                impl.setPatterns(patterns);
+
+                int enumCount = readShort();
+                XmlValueRef[] enumValues = new XmlValueRef[enumCount];
+                for (int i = 0; i < enumCount; i++) {
+                    enumValues[i] = readXmlValueObject();
+                }
+                impl.setEnumerationValues(enumCount == 0 ? null : enumValues);
+
+                impl.setBaseEnumTypeRef(readTypeRef());
+                if (isStringEnum) {
+                    int seCount = readUnsignedShortOrInt();
+                    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", typeSystem.getName(), _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY);
+                }
+            }
+
+            impl.setFilename(readString());
+            // Set the container for global, attribute or document types
+            if (impl.getName() != null) {
+                SchemaContainer container = typeSystem.getContainer(impl.getName().getNamespaceURI());
+                checkContainerNotNull(container, impl.getName());
+                impl.setContainer(container);
+            } else if (impl.isDocumentType()) {
+                QName name = impl.getDocumentElementName();
+                if (name != null) {
+                    SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+                    checkContainerNotNull(container, name);
+                    impl.setContainer(container);
+                }
+            } else if (impl.isAttributeType()) {
+                QName name = impl.getAttributeTypeAttributeName();
+                if (name != null) {
+                    SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI());
+                    checkContainerNotNull(container, name);
+                    impl.setContainer(container);
+                }
+            }
+
+            return impl;
+        } catch (SchemaTypeLoaderException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
+        } finally {
+            readEnd();
+        }
+    }
+
+    void writeTypeData(SchemaType type) {
+        writeQName(type.getName());
+        writeType(type.getOuterType());
+        writeShort(((SchemaTypeImpl) type).getBaseDepth());
+        writeType(type.getBaseType());
+        writeShort(type.getDerivationType());
+        writeAnnotation(type.getAnnotation());
+        if (type.getContainerField() == null) {
+            writeShort(FIELD_NONE);
+        } else if (type.getOuterType().isAttributeType() || type.getOuterType().isDocumentType()) {
+            writeShort(FIELD_GLOBAL);
+            writeHandle((SchemaComponent) type.getContainerField());
+        } else if (type.getContainerField().isAttribute()) {
+            writeShort(FIELD_LOCALATTR);
+            writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalAttribute((SchemaLocalAttribute) type.getContainerField()));
+        } else {
+            writeShort(FIELD_LOCALELT);
+            writeShort(((SchemaTypeImpl) type.getOuterType()).getIndexForLocalElement((SchemaLocalElement) type.getContainerField()));
+        }
+        writeString(type.getFullJavaName());
+        writeString(type.getFullJavaImplName());
+        writeTypeArray(type.getAnonymousTypes());
+        writeShort(type.getAnonymousUnionMemberOrdinal());
+
+        int flags = 0;
+        if (type.isSimpleType()) {
+            flags |= FLAG_SIMPLE_TYPE;
+        }
+        if (type.isDocumentType()) {
+            flags |= FLAG_DOCUMENT_TYPE;
+        }
+        if (type.isAttributeType()) {
+            flags |= FLAG_ATTRIBUTE_TYPE;
+        }
+        if (type.ordered() != SchemaType.UNORDERED) {
+            flags |= FLAG_ORDERED;
+        }
+        if (type.ordered() == SchemaType.TOTAL_ORDER) {
+            flags |= FLAG_TOTAL_ORDER;
+        }
+        if (type.isBounded()) {
+            flags |= FLAG_BOUNDED;
+        }
+        if (type.isFinite()) {
+            flags |= FLAG_FINITE;
+        }
+        if (type.isNumeric()) {
+            flags |= FLAG_NUMERIC;
+        }
+        if (type.hasStringEnumValues()) {
+            flags |= FLAG_STRINGENUM;
+        }
+        if (((SchemaTypeImpl) type).isUnionOfLists()) {
+            flags |= FLAG_UNION_OF_LISTS;
+        }
+        if (type.hasPatternFacet()) {
+            flags |= FLAG_HAS_PATTERN;
+        }
+        if (type.isOrderSensitive()) {
+            flags |= FLAG_ORDER_SENSITIVE;
+        }
+
+        if (type.blockExtension()) {
+            flags |= FLAG_BLOCK_EXT;
+        }
+        if (type.blockRestriction()) {
+            flags |= FLAG_BLOCK_REST;
+        }
+        if (type.finalExtension()) {
+            flags |= FLAG_FINAL_EXT;
+        }
+        if (type.finalRestriction()) {
+            flags |= FLAG_FINAL_EXT;
+        }
+        if (type.finalList()) {
+            flags |= FLAG_FINAL_LIST;
+        }
+        if (type.finalUnion()) {
+            flags |= FLAG_FINAL_UNION;
+        }
+        if (type.isAbstract()) {
+            flags |= FLAG_ABSTRACT;
+        }
+
+        writeInt(flags);
+
+        if (!type.isSimpleType()) {
+            writeShort(type.getContentType());
+
+            writeType(type.getContentBasedOnType());
+
+            // Attribute Model Table
+            SchemaAttributeModel attrModel = type.getAttributeModel();
+            SchemaLocalAttribute[] attrs = attrModel.getAttributes();
+
+            writeShort(attrs.length);
+            for (SchemaLocalAttribute attr : attrs) {
+                writeAttributeData(attr);
+            }
+
+            writeQNameSet(attrModel.getWildcardSet());
+            writeShort(attrModel.getWildcardProcess());
+
+            // Attribute Property Table
+            SchemaProperty[] attrProperties = type.getAttributeProperties();
+            writeShort(attrProperties.length);
+            for (SchemaProperty attrProperty : attrProperties) {
+                writePropertyData(attrProperty);
+            }
+
+            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 (SchemaProperty eltProperty : eltProperties) {
+                    writePropertyData(eltProperty);
+                }
+            }
+        }
+
+        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 (org.apache.xmlbeans.impl.regex.RegularExpression pattern : patterns) {
+                writeString(pattern.getPattern());
+            }
+
+            XmlAnySimpleType[] enumValues = type.getEnumerationValues();
+            if (enumValues == null) {
+                writeShort(0);
+            } else {
+                writeShortOrInt(enumValues.length);
+                for (XmlAnySimpleType enumValue : enumValues) {
+                    writeXmlValueObject(enumValue);
+                }
+            }
+
+            // new for version 2.3
+            writeType(type.getBaseEnumType());
+            if (type.hasStringEnumValues()) {
+                SchemaStringEnumEntry[] entries = type.getStringEnumEntries();
+                writeShort(entries.length);
+                for (SchemaStringEnumEntry entry : entries) {
+                    writeString(entry.getString());
+                    writeShort(entry.getIntValue());
+                    writeString(entry.getEnumName());
+                }
+            }
+
+            switch (type.getSimpleVariety()) {
+                case SchemaType.ATOMIC:
+                    writeType(type.getPrimitiveType());
+                    writeInt(type.getDecimalSize());
+                    break;
+
+                case SchemaType.LIST:
+                    writeType(type.getListItemType());
+                    break;
+
+                case SchemaType.UNION:
+                    writeTypeArray(type.getUnionMemberTypes());
+                    break;
+            }
+        }
+
+        writeString(type.getSourceName());
+    }
+
+        /*
+        void readExtensionsList() {
+            int count = readShort();
+            assert count == 0;
+
+            for (int i = 0; i < count; i++) {
+                readString();
+                readString();
+                readString();
+            }
+        }
+         */
+
+    SchemaLocalAttribute readAttributeData() {
+        SchemaLocalAttributeImpl result = new SchemaLocalAttributeImpl();
+        loadAttribute(result, readQName(), null);
+        return result;
+    }
+
+
+    void loadAttribute(SchemaLocalAttributeImpl result, QName name, SchemaContainer container) {
+        // name, type, use, deftext, defval, fixed, soaparraytype, annotation
+        result.init(name, readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType(), readAnnotation(container), null);
+    }
+
+    void writeAttributeData(SchemaLocalAttribute attr) {
+        writeQName(attr.getName());
+        writeType(attr.getType());
+        writeShort(attr.getUse());
+        writeString(attr.getDefaultText());
+        writeXmlValueObject(attr.getDefaultValue());
+        writeShort(attr.isFixed() ? 1 : 0);
+        writeSOAPArrayType(((SchemaWSDLArrayType) attr).getWSDLArrayType());
+        writeAnnotation(attr.getAnnotation());
+    }
+
+    void writeIdConstraintData(SchemaIdentityConstraint idc) {
+        writeQName(idc.getName());
+        writeShort(idc.getConstraintCategory());
+        writeString(idc.getSelector());
+        writeAnnotation(idc.getAnnotation());
+
+        String[] fields = idc.getFields();
+        writeShort(fields.length);
+        for (String field : fields) {
+            writeString(field);
+        }
+
+
+        if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) {
+            writeHandle(idc.getReferencedKey());
+        }
+
+        Map<String, String> mappings = idc.getNSMap();
+        writeShort(mappings.size());
+        mappings.forEach((prefix, uri) -> {
+            writeString(prefix);
+            writeString(uri);
+        });
+        writeString(idc.getSourceName());
+    }
+
+    SchemaParticle[] readParticleArray() {
+        SchemaParticle[] result = new SchemaParticle[readShort()];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = readParticleData();
+        }
+        return result;
+    }
+
+    void writeParticleArray(SchemaParticle[] spa) {
+        writeShort(spa.length);
+        for (SchemaParticle schemaParticle : spa) {
+            writeParticleData(schemaParticle);
+        }
+    }
+
+    SchemaParticle readParticleData() {
+        int particleType = readShort();
+        SchemaParticleImpl result;
+        if (particleType != SchemaParticle.ELEMENT) {
+            result = new SchemaParticleImpl();
+        } else {
+            result = new SchemaLocalElementImpl();
+        }
+        loadParticle(result, particleType);
+        return result;
+    }
+
+    void loadParticle(SchemaParticleImpl result, int particleType) {
+        int particleFlags = readShort();
+
+        result.setParticleType(particleType);
+        result.setMinOccurs(readBigInteger());
+        result.setMaxOccurs(readBigInteger());
+
+        result.setTransitionRules(readQNameSet(),
+            (particleFlags & FLAG_PART_SKIPPABLE) != 0);
+
+        switch (particleType) {
+            case SchemaParticle.WILDCARD:
+                result.setWildcardSet(readQNameSet());
+                result.setWildcardProcess(readShort());
+                break;
+
+            case SchemaParticle.ELEMENT:
+                SchemaLocalElementImpl lresult = (SchemaLocalElementImpl) result;
+                lresult.setNameAndTypeRef(readQName(), readTypeRef());
+                lresult.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
+                if (atLeast(2, 16, 0)) {
+                    lresult.setDefaultValue(readXmlValueObject());
+                }
+                lresult.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
+                lresult.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
+                    (particleFlags & FLAG_PART_BLOCKREST) != 0,
+                    (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
+                lresult.setWsdlArrayType(readSOAPArrayType());
+                lresult.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
+                lresult.setAnnotation(readAnnotation(null));
+
+                SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
+
+                for (int i = 0; i < idcs.length; i++) {
+                    idcs[i] = (SchemaIdentityConstraint.Ref) readHandle();
+                }
+
+                lresult.setIdentityConstraints(idcs);
+
+                break;
+
+            case SchemaParticle.ALL:
+            case SchemaParticle.SEQUENCE:
+            case SchemaParticle.CHOICE:
+                result.setParticleChildren(readParticleArray());
+                break;
+
+            default:
+                throw new SchemaTypeLoaderException("Unrecognized particle type ", typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
+        }
+    }
+
+    void writeParticleData(SchemaParticle part) {
+        writeShort(part.getParticleType());
+        short flags = 0;
+        if (part.isSkippable()) {
+            flags |= FLAG_PART_SKIPPABLE;
+        }
+        if (part.getParticleType() == SchemaParticle.ELEMENT) {
+            SchemaLocalElement lpart = (SchemaLocalElement) part;
+            if (lpart.isFixed()) {
+                flags |= FLAG_PART_FIXED;
+            }
+            if (lpart.isNillable()) {
+                flags |= FLAG_PART_NILLABLE;
+            }
+            if (lpart.blockExtension()) {
+                flags |= FLAG_PART_BLOCKEXT;
+            }
+            if (lpart.blockRestriction()) {
+                flags |= FLAG_PART_BLOCKREST;
+            }
+            if (lpart.blockSubstitution()) {
+                flags |= FLAG_PART_BLOCKSUBST;
+            }
+            if (lpart.isAbstract()) {
+                flags |= FLAG_PART_ABSTRACT;
+            }
+
+            if (lpart instanceof SchemaGlobalElement) {
+                SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;
+                if (gpart.finalExtension()) {
+                    flags |= FLAG_PART_FINALEXT;
+                }
+                if (gpart.finalRestriction()) {
+                    flags |= FLAG_PART_FINALREST;
+                }
+            }
+        }
+        writeShort(flags);
+        writeBigInteger(part.getMinOccurs());
+        writeBigInteger(part.getMaxOccurs());
+        writeQNameSet(part.acceptedStartNames());
+
+        switch (part.getParticleType()) {
+            case SchemaParticle.WILDCARD:
+                writeQNameSet(part.getWildcardSet());
+                writeShort(part.getWildcardProcess());
+                break;
+
+            case SchemaParticle.ELEMENT:
+                SchemaLocalElement lpart = (SchemaLocalElement) part;
+                writeQName(lpart.getName());
+                writeType(lpart.getType());
+                writeString(lpart.getDefaultText());
+                writeXmlValueObject(lpart.getDefaultValue());
+                writeSOAPArrayType(((SchemaWSDLArrayType) lpart).getWSDLArrayType());
+                writeAnnotation(lpart.getAnnotation());
+                if (lpart instanceof SchemaGlobalElement) {
+                    SchemaGlobalElement gpart = (SchemaGlobalElement) lpart;
+
+                    writeHandle(gpart.substitutionGroup());
+
+                    QName[] substGroupMembers = gpart.substitutionGroupMembers();
+                    writeShort(substGroupMembers.length);
+                    for (QName substGroupMember : substGroupMembers) {
+                        writeQName(substGroupMember);
+                    }
+                }
+
+                SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints();
+
+                writeShort(idcs.length);
+                for (SchemaIdentityConstraint idc : idcs) {
+                    writeHandle(idc);
+                }
+
+                break;
+
+            case SchemaParticle.ALL:
+            case SchemaParticle.SEQUENCE:
+            case SchemaParticle.CHOICE:
+                writeParticleArray(part.getParticleChildren());
+                break;
+
+            default:
+                throw new SchemaTypeLoaderException("Unrecognized particle type ", typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
+        }
+    }
+
+    SchemaProperty readPropertyData() {
+        SchemaPropertyImpl prop = new SchemaPropertyImpl();
+        prop.setName(readQName());
+        prop.setTypeRef(readTypeRef());
+        int propflags = readShort();
+        prop.setAttribute((propflags & FLAG_PROP_ISATTR) != 0);
+        prop.setContainerTypeRef(readTypeRef());
+        prop.setMinOccurs(readBigInteger());
+        prop.setMaxOccurs(readBigInteger());
+        prop.setNillable(readShort());
+        prop.setDefault(readShort());
+        prop.setFixed(readShort());
+        prop.setDefaultText(readString());
+
+        prop.setJavaPropertyName(readString());
+        prop.setJavaTypeCode(readShort());
+        prop.setExtendsJava(readTypeRef(),
+            (propflags & FLAG_PROP_JAVASINGLETON) != 0,
+            (propflags & FLAG_PROP_JAVAOPTIONAL) != 0,
+            (propflags & FLAG_PROP_JAVAARRAY) != 0);
+        if (atMost(2, 19, 0)) {
+            prop.setJavaSetterDelimiter(readQNameSet());
+        }
+        if (atLeast(2, 16, 0)) {
+            prop.setDefaultValue(readXmlValueObject());
+        }
+
+        if (!prop.isAttribute() && atLeast(2, 17, 0)) {
+            int size = readShort();
+            Set<QName> qnames = new LinkedHashSet<>(size);
+            for (int i = 0; i < size; i++) {
+                qnames.add(readQName());
+            }
+            prop.setAcceptedNames(qnames);
+        }
+        prop.setImmutable();
+        return prop;
+    }
+
+    void writePropertyData(SchemaProperty prop) {
+        writeQName(prop.getName());
+        writeType(prop.getType());
+        writeShort((prop.isAttribute() ? FLAG_PROP_ISATTR : 0) |
+                   (prop.extendsJavaSingleton() ? FLAG_PROP_JAVASINGLETON : 0) |
+                   (prop.extendsJavaOption() ? FLAG_PROP_JAVAOPTIONAL : 0) |
+                   (prop.extendsJavaArray() ? FLAG_PROP_JAVAARRAY : 0));
+        writeType(prop.getContainerType());
+        writeBigInteger(prop.getMinOccurs());
+        writeBigInteger(prop.getMaxOccurs());
+        writeShort(prop.hasNillable());
+        writeShort(prop.hasDefault());
+        writeShort(prop.hasFixed());
+        writeString(prop.getDefaultText());
+
+        writeString(prop.getJavaPropertyName());
+        writeShort(prop.getJavaTypeCode());
+        writeType(prop.javaBasedOnType());
+        writeXmlValueObject(prop.getDefaultValue());
+
+        if (!prop.isAttribute()) {
+            QName[] names = prop.acceptedNames();
+            writeShort(names.length);
+            for (QName name : names) {
+                writeQName(name);
+            }
+        }
+    }
+
+    void writeModelGroupData(SchemaModelGroup grp) {
+        SchemaModelGroupImpl impl = (SchemaModelGroupImpl) grp;
+        writeQName(impl.getName());
+        writeString(impl.getTargetNamespace());
+        writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
+        writeString(impl.getElemFormDefault()); // new for version 2.22
+        writeString(impl.getAttFormDefault()); // new for version 2.22
+        writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
+        writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
+        writeAnnotation(impl.getAnnotation());
+        writeString(impl.getSourceName());
+    }
+
+    void writeAttributeGroupData(SchemaAttributeGroup grp) {
+        SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl) grp;
+        writeQName(impl.getName());
+        writeString(impl.getTargetNamespace());
+        writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
+        writeString(impl.getFormDefault()); // new for version 2.22
+        writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
+        writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
+        writeAnnotation(impl.getAnnotation());
+        writeString(impl.getSourceName());
+    }
+
+    XmlValueRef readXmlValueObject() {
+        SchemaType.Ref typeref = readTypeRef();
+        if (typeref == null) {
+            return null;
+        }
+        int btc = readShort();
+        switch (btc) {
+            default:
+                assert (false);
+            case 0:
+                return new XmlValueRef(typeref, null);
+            case 0xFFFF: {
+                int size = readShort();
+                List<XmlValueRef> values = new ArrayList<>();
+                // BUGBUG: this was: writeShort(values.size());
+                writeShort(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, 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<? extends XmlAnySimpleType> values = ((XmlObjectBase) value).xgetListValue();
+            writeShort(values.size());
+            values.forEach(this::writeXmlValueObject);
+        } 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(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    void writeDouble(double d) {
+        if (_output != null) {
+            try {
+                _output.writeDouble(d);
+            } catch (IOException e) {
+                throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+            }
+        }
+    }
+
+    QNameSet readQNameSet() {
+        int flag = readShort();
+
+        Set<String> uriSet = new HashSet<>();
+        int uriCount = readShort();
+        for (int i = 0; i < uriCount; i++) {
+            uriSet.add(readString());
+        }
+
+        Set<QName> qnameSet1 = new HashSet<>();
+        int qncount1 = readShort();
+        for (int i = 0; i < qncount1; i++) {
+            qnameSet1.add(readQName());
+        }
+
+        Set<QName> qnameSet2 = new HashSet<>();
+        int qncount2 = readShort();
+        for (int i = 0; i < qncount2; i++) {
+            qnameSet2.add(readQName());
+        }
+
+        if (flag == 1) {
+            return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2);
+        } else {
+            return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1);
+        }
+    }
+
+    void writeQNameSet(QNameSet set) {
+        boolean invert = (set.excludedURIs() != null);
+        writeShort(invert ? 1 : 0);
+
+        Set<String> uriSet = invert ? set.excludedURIs() : set.includedURIs();
+        assert (uriSet != null);
+        writeShort(uriSet.size());
+        uriSet.forEach(this::writeString);
+
+        Set<QName> qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs();
+        writeShort(qnameSet1.size());
+        qnameSet1.forEach(this::writeQName);
+
+        Set<QName> qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs();
+        writeShort(qnameSet2.size());
+        qnameSet2.forEach(this::writeQName);
+    }
+
+    byte[] readByteArray() {
+        try {
+            int len = _input.readShort();
+            byte[] result = new byte[len];
+            _input.readFully(result);
+            return result;
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    void writeByteArray(byte[] ba) {
+        try {
+            writeShort(ba.length);
+            if (_output != null) {
+                _output.write(ba);
+            }
+        } catch (IOException e) {
+            throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
+        }
+    }
+
+    BigInteger readBigInteger() {
+        byte[] result = readByteArray();
+        if (result.length == 0) {
+            return null;
+        }
+        if (result.length == 1 && result[0] == 0) {
+            return BigInteger.ZERO;
+        }
+        if (result.length == 1 && result[0] == 1) {
+            return BigInteger.ONE;
+        }
+        return new BigInteger(result);
+    }
+
+    void writeBigInteger(BigInteger bi) {
+        if (bi == null) {
+            writeShort(0);
+        } else if (bi.signum() == 0) {
+            writeByteArray(SINGLE_ZERO_BYTE);
+        } else {
+            writeByteArray(bi.toByteArray());
+        }
+    }
+
+}
+
