diff --git a/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java b/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java
deleted file mode 100644
index 7ab1a51..0000000
--- a/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*   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;
-
-/**
- * Same as {@link XmlOptions} but adhering to JavaBean conventions
- *
- * @deprecated use XmlOptions instead
- */
-@Deprecated
-public class XmlOptionsBean extends XmlOptions {
-    /**
-     * Construct a new blank XmlOptions.
-     */
-    public XmlOptionsBean() {
-    }
-
-    /**
-     * Construct a new XmlOptions, copying the options.
-     *
-     * @param other the source <code>XmlOptions</code> object
-     */
-    public XmlOptionsBean(XmlOptions other) {
-        super(other);
-    }
-}
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/DocumentHelper.java b/src/main/java/org/apache/xmlbeans/impl/common/DocumentHelper.java
index 7e12d26..adab35a 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/DocumentHelper.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/DocumentHelper.java
@@ -17,7 +17,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.xmlbeans.XmlOptionsBean;
+import org.apache.xmlbeans.XmlOptions;
 import org.w3c.dom.Document;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.InputSource;
@@ -78,11 +78,11 @@
     /**
      * Creates a new document builder, with sensible defaults
      *
-     * @param xmlOptions
+     * @param xmlOptions the factory option
      * @throws IllegalStateException If creating the DocumentBuilder fails, e.g.
      *  due to {@link ParserConfigurationException}.
      */
-    public static DocumentBuilder newDocumentBuilder(XmlOptionsBean xmlOptions) {
+    public static DocumentBuilder newDocumentBuilder(XmlOptions xmlOptions) {
         try {
             DocumentBuilder documentBuilder = documentBuilderFactory(xmlOptions).newDocumentBuilder();
             documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
@@ -93,7 +93,7 @@
         }
     }
 
-    private static DocumentBuilderFactory documentBuilderFactory(XmlOptionsBean options) {
+    private static DocumentBuilderFactory documentBuilderFactory(XmlOptions options) {
         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         documentBuilderFactory.setNamespaceAware(true);
         documentBuilderFactory.setValidating(false);
@@ -114,7 +114,7 @@
         }
     }
 
-    private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf, XmlOptionsBean options) {
+    private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf, XmlOptions options) {
         // Try built-in JVM one first, standalone if not
         for (String securityManagerClassName : new String[]{
                 //"com.sun.org.apache.xerces.internal.util.SecurityManager",
@@ -154,7 +154,7 @@
      * @param inp Stream to read the XML data from
      * @return the parsed Document
      */
-    public static Document readDocument(XmlOptionsBean xmlOptions, InputStream inp) throws IOException, SAXException {
+    public static Document readDocument(XmlOptions xmlOptions, InputStream inp) throws IOException, SAXException {
         return newDocumentBuilder(xmlOptions).parse(inp);
     }
 
@@ -164,12 +164,12 @@
      * @param inp sax source to read the XML data from
      * @return the parsed Document
      */
-    public static Document readDocument(XmlOptionsBean xmlOptions, InputSource inp) throws IOException, SAXException {
+    public static Document readDocument(XmlOptions xmlOptions, InputSource inp) throws IOException, SAXException {
         return newDocumentBuilder(xmlOptions).parse(inp);
     }
 
     // must only be used to create empty documents, do not use it for parsing!
-    private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(new XmlOptionsBean());
+    private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(new XmlOptions());
 
     /**
      * Creates a new DOM Document
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java b/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java
index f99f69f..8c88bf2 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java
@@ -18,7 +18,6 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlOptionsBean;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -27,7 +26,6 @@
 import javax.xml.XMLConstants;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
-import java.io.IOException;
 import java.io.StringReader;
 import java.lang.reflect.Method;
 import java.util.concurrent.TimeUnit;
@@ -53,16 +51,11 @@
         return xmlReader;
     }
 
-    public static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
-        @Override
-        public InputSource resolveEntity(String publicId, String systemId)
-            throws SAXException, IOException {
-            return new InputSource(new StringReader(""));
-        }
-    };
+    public static final EntityResolver IGNORING_ENTITY_RESOLVER =
+        (publicId, systemId) -> new InputSource(new StringReader(""));
 
     static SAXParserFactory saxFactory() {
-        return saxFactory(new XmlOptionsBean());
+        return saxFactory(new XmlOptions());
     }
 
     static SAXParserFactory saxFactory(XmlOptions options) {
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/StaxHelper.java b/src/main/java/org/apache/xmlbeans/impl/common/StaxHelper.java
index 207e8cd..f787102 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/StaxHelper.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/StaxHelper.java
@@ -17,7 +17,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.xmlbeans.XmlOptionsBean;
+import org.apache.xmlbeans.XmlOptions;
 
 import javax.xml.stream.XMLEventFactory;
 import javax.xml.stream.XMLInputFactory;
@@ -34,7 +34,7 @@
     /**
      * Creates a new StAX XMLInputFactory, with sensible defaults
      */
-    public static XMLInputFactory newXMLInputFactory(XmlOptionsBean options) {
+    public static XMLInputFactory newXMLInputFactory(XmlOptions options) {
         XMLInputFactory factory = XMLInputFactory.newFactory();
         trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
         trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false);
@@ -46,7 +46,7 @@
     /**
      * Creates a new StAX XMLOutputFactory, with sensible defaults
      */
-    public static XMLOutputFactory newXMLOutputFactory(XmlOptionsBean options) {
+    public static XMLOutputFactory newXMLOutputFactory(XmlOptions options) {
         XMLOutputFactory factory = XMLOutputFactory.newFactory();
         trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
         return factory;
@@ -55,7 +55,7 @@
     /**
      * Creates a new StAX XMLEventFactory, with sensible defaults
      */
-    public static XMLEventFactory newXMLEventFactory(XmlOptionsBean options) {
+    public static XMLEventFactory newXMLEventFactory(XmlOptions options) {
         return XMLEventFactory.newFactory();
     }
 
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/readme.txt b/src/main/java/org/apache/xmlbeans/impl/common/readme.txt
deleted file mode 100644
index ea25143..0000000
--- a/src/main/java/org/apache/xmlbeans/impl/common/readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-There are isolated files in this directory taken from the Apache
-Xerces-J 2.0 project
-
-It contains very minor modifications including a change in namespace.
-
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java b/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java
index d96663f..6c5f40b 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java
@@ -37,8 +37,6 @@
 import java.util.Map;
 import java.util.function.Supplier;
 
-import static org.apache.xmlbeans.impl.values.TypeStore.WS_PRESERVE;
-
 public final class Cursor implements XmlCursor, ChangeListener {
     static final int ROOT = Cur.ROOT;
     static final int ELEM = Cur.ELEM;
@@ -1049,7 +1047,7 @@
         // If there are no children (hopefully the common case), I can get the text faster.
 
         if (_cur.hasChildren()) {
-            return Locale.getTextValue(_cur, WS_PRESERVE, chars, offset, max);
+            return Locale.getTextValue(_cur, chars, offset, max);
         }
 
         // Fast way
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Locale.java b/src/main/java/org/apache/xmlbeans/impl/store/Locale.java
index 9d9ace7..2079791 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Locale.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Locale.java
@@ -47,6 +47,7 @@
 
 import static org.apache.xmlbeans.impl.values.TypeStore.*;
 
+@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
 public final class Locale
     implements DOMImplementation, SaajCallback, XmlLocale {
     private static final Logger LOG = LogManager.getLogger(Locale.class);
@@ -59,7 +60,7 @@
     static final int TEXT = Cur.TEXT;
 
     static final String _xsi = "http://www.w3.org/2001/XMLSchema-instance";
-    static final String _schema = "http://www.w3.org/2001/XMLSchema";
+    // static final String _schema = "http://www.w3.org/2001/XMLSchema";
     static final String _openFragUri = "http://www.openuri.org/fragment";
     static final String _xml1998Uri = "http://www.w3.org/XML/1998/namespace";
     static final String _xmlnsUri = "http://www.w3.org/2000/xmlns/";
@@ -67,19 +68,13 @@
     static final QName _xsiNil = new QName(_xsi, "nil", "xsi");
     static final QName _xsiType = new QName(_xsi, "type", "xsi");
     static final QName _xsiLoc = new QName(_xsi, "schemaLocation", "xsi");
-    static final QName _xsiNoLoc = new QName(_xsi, "noNamespaceSchemaLocation",
-        "xsi");
-    static final QName _openuriFragment = new QName(_openFragUri, "fragment",
-        "frag");
+    static final QName _xsiNoLoc = new QName(_xsi, "noNamespaceSchemaLocation", "xsi");
+    static final QName _openuriFragment = new QName(_openFragUri, "fragment", "frag");
     static final QName _xmlFragment = new QName("xml-fragment");
 
     private Locale(SchemaTypeLoader stl, XmlOptions options) {
         options = XmlOptions.maskNull(options);
 
-        //
-        //
-        //
-
         // TODO - add option for no=sync, or make it all thread safe
         //
         // Also - have a thread local setting for thread safety?  .. Perhaps something
@@ -115,10 +110,6 @@
         }
     }
 
-    //
-    //
-    //
-
     public static Locale getLocale(SchemaTypeLoader stl, XmlOptions options) {
         if (stl == null) {
             stl = XmlBeans.getContextTypeLoader();
@@ -162,10 +153,6 @@
         return l;
     }
 
-    //
-    //
-    //
-
     public static void associateSourceName(Cur c, XmlOptions options) {
         String sourceName = options == null ? null : options.getDocumentSourceName();
 
@@ -174,10 +161,6 @@
         }
     }
 
-    //
-    //
-    //
-
     public static void autoTypeDocument(Cur c, SchemaType requestedType,
                                         XmlOptions options)
         throws XmlException {
@@ -290,7 +273,7 @@
         return Objects.equals(n1.getNamespaceURI(), n2.getNamespaceURI());
     }
 
-    private static void addNamespace(StringBuffer sb, QName name) {
+    private static void addNamespace(StringBuilder sb, QName name) {
         if (name.getNamespaceURI() == null) {
             sb.append("<no namespace>");
         } else {
@@ -307,11 +290,11 @@
         c.push();
 
         try {
-            StringBuffer sb = null;
+            StringBuilder sb = null;
 
             if (!Locale.toFirstChildElement(c) ||
                 Locale.toNextSiblingElement(c)) {
-                sb = new StringBuffer();
+                sb = new StringBuilder();
 
                 sb.append("The document is not a ");
                 sb.append(QNameHelper.pretty(docElemName));
@@ -322,7 +305,7 @@
                 QName name = c.getName();
 
                 if (!name.equals(docElemName)) {
-                    sb = new StringBuffer();
+                    sb = new StringBuilder();
 
                     sb.append("The document is not a ");
                     sb.append(QNameHelper.pretty(docElemName));
@@ -355,17 +338,16 @@
         }
     }
 
-    private static void verifyAttributeType(Cur c, QName attrName)
-        throws XmlException {
+    private static void verifyAttributeType(Cur c, QName attrName) throws XmlException {
         assert c.isRoot();
 
         c.push();
 
         try {
-            StringBuffer sb = null;
+            StringBuilder sb = null;
 
             if (!Locale.toFirstNormalAttr(c) || Locale.toNextNormalAttr(c)) {
-                sb = new StringBuffer();
+                sb = new StringBuilder();
 
                 sb.append("The document is not a ");
                 sb.append(QNameHelper.pretty(attrName));
@@ -375,7 +357,7 @@
                 QName name = c.getName();
 
                 if (!name.equals(attrName)) {
-                    sb = new StringBuffer();
+                    sb = new StringBuilder();
 
                     sb.append("The document is not a ");
                     sb.append(QNameHelper.pretty(attrName));
@@ -388,8 +370,8 @@
                         addNamespace(sb, name);
                     } else if (namespacesSame(attrName, name)) {
                         sb.append(": attribute local name mismatch ");
-                        sb.append("expected " + attrName.getLocalPart());
-                        sb.append(" got " + name.getLocalPart());
+                        sb.append("expected ").append(attrName.getLocalPart());
+                        sb.append(" got ").append(name.getLocalPart());
                     } else {
                         sb.append(": attribute element mismatch ");
                         sb.append("got ");
@@ -454,80 +436,48 @@
         return isFrag || numDocElems != 1;
     }
 
-    //
-    //
-    //
+    public static XmlObject newInstance(SchemaTypeLoader stl, SchemaType type, XmlOptions options) {
+        try {
+            return syncWrap(stl, options, (l) -> {
+                Cur c = l.tempCur();
+                SchemaType sType = XmlOptions.maskNull(options).getDocumentType();
 
-    public static XmlObject newInstance(SchemaTypeLoader stl, SchemaType type,
-                                        XmlOptions options) {
-        Locale l = getLocale(stl, options);
-
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.newInstance(type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.newInstance(type, options);
-                } finally {
-                    l.exit();
+                if (sType == null) {
+                    sType = type == null ? XmlObject.type : type;
                 }
-            }
+                if (sType.isDocumentType()) {
+                    c.createDomDocumentRoot();
+                } else {
+                    c.createRoot();
+                }
+                c.setType(sType);
+
+                XmlObject x = (XmlObject) c.getUser();
+                c.release();
+                return x;
+            });
+        } catch (XmlException | IOException e) {
+            assert false : "newInstance doesn't throw XmlException or IOException";
+            throw new RuntimeException(e);
         }
     }
 
-    private XmlObject newInstance(SchemaType type, XmlOptions options) {
-        options = XmlOptions.maskNull(options);
-
-        Cur c = tempCur();
-
-
-        SchemaType sType = options.getDocumentType();
-
-        if (sType == null) {
-            sType = type == null ? XmlObject.type : type;
-        }
-        if (sType.isDocumentType()) {
-            c.createDomDocumentRoot();
-        } else {
-            c.createRoot();
-        }
-        c.setType(sType);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
-    }
-
-    //
-    //
-    //
-
-    public static DOMImplementation newDomImplementation(SchemaTypeLoader stl,
-                                                         XmlOptions options) {
+    public static DOMImplementation newDomImplementation(SchemaTypeLoader stl, XmlOptions options) {
         return getLocale(stl, options);
     }
 
-    //
-    //
-    //
+    private interface SyncWrapFun<T> {
+        T parse(Locale l) throws XmlException, IOException;
+    }
 
-    public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-                                             String xmlText, SchemaType type, XmlOptions options)
-        throws XmlException {
+    private static <T> T syncWrap(SchemaTypeLoader stl, XmlOptions options, SyncWrapFun<T> fun)
+    throws XmlException, IOException {
         Locale l = getLocale(stl, options);
 
         if (l.noSync()) {
             l.enter();
             try {
-                return l.parseToXmlObject(xmlText, type, options);
+                return fun.parse(l);
             } finally {
                 l.exit();
             }
@@ -535,7 +485,7 @@
             synchronized (l) {
                 l.enter();
                 try {
-                    return l.parseToXmlObject(xmlText, type, options);
+                    return fun.parse(l);
                 } finally {
                     l.exit();
                 }
@@ -543,86 +493,44 @@
         }
     }
 
-    private XmlObject parseToXmlObject(String xmlText, SchemaType type,
-                                       XmlOptions options)
-        throws XmlException {
-        Cur c = parse(xmlText, type, options);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
-    }
-
-    Cur parse(String s, SchemaType type, XmlOptions options)
-        throws XmlException {
-
-        try (Reader r = new StringReader(s)) {
-            Cur c = getSaxLoader(options).load(this, new InputSource(r),
-                options);
-
-            autoTypeDocument(c, type, options);
-
-            return c;
+    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, String xmlText, SchemaType type, XmlOptions options)
+    throws XmlException {
+        try {
+            return syncWrap(stl, options, (l) -> {
+                try (Reader r = new StringReader(xmlText)) {
+                    Cur c = getSaxLoader(options).load(l, new InputSource(r), options);
+                    autoTypeDocument(c, type, options);
+                    XmlObject x = (XmlObject) c.getUser();
+                    c.release();
+                    return x;
+                }
+            });
         } catch (IOException e) {
             assert false : "StringReader should not throw IOException";
-
             throw new XmlException(e.getMessage(), e);
         }
     }
 
-    //
-    //
-    //
-
-
-    //
-    //
-    //
-
-    public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-                                             XMLStreamReader xsr, SchemaType type, XmlOptions options)
-        throws XmlException {
-        Locale l = getLocale(stl, options);
-
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.parseToXmlObject(xsr, type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.parseToXmlObject(xsr, type, options);
-                } finally {
-                    l.exit();
-                }
-            }
-        }
-    }
-
-    public XmlObject parseToXmlObject(XMLStreamReader xsr, SchemaType type,
-                                      XmlOptions options)
-        throws XmlException {
-        Cur c;
-
+    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, XMLStreamReader xsr, SchemaType type, XmlOptions options)
+    throws XmlException {
         try {
-            c = loadXMLStreamReader(xsr, options);
-        } catch (XMLStreamException e) {
-            throw new XmlException(e.getMessage(), e);
+            return syncWrap(stl, options, (l) -> {
+                Cur c;
+                try {
+                    c = l.loadXMLStreamReader(xsr, options);
+                } catch (XMLStreamException e) {
+                    throw new XmlException(e.getMessage(), e);
+                }
+
+                autoTypeDocument(c, type, options);
+                XmlObject x = (XmlObject) c.getUser();
+                c.release();
+                return x;
+            });
+        } catch (IOException e) {
+            assert false : "doesn't throw IOException";
+            throw new RuntimeException(e);
         }
-
-        autoTypeDocument(c, type, options);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
     }
 
     private static void lineNumber(XMLStreamReader xsr, LoadContext context) {
@@ -780,8 +688,7 @@
                     break;
 
                 default:
-                    throw new RuntimeException(
-                        "Unhandled xml event type: " + eventType);
+                    throw new RuntimeException("Unhandled xml event type: " + eventType);
             }
 
             if (!xsr.hasNext() || depth <= 0) {
@@ -802,140 +709,47 @@
         return c;
     }
 
-    //
-    //
-    //
+    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, InputStream is, SchemaType type, XmlOptions options)
+    throws XmlException, IOException {
+        return syncWrap(stl, options, (l) -> {
+            Cur c = getSaxLoader(options).load(l, new InputSource(is), options);
+            autoTypeDocument(c, type, options);
+            XmlObject x = (XmlObject) c.getUser();
+            c.release();
+            return x;
+        });
+    }
 
-    public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-                                             InputStream is, SchemaType type, XmlOptions options)
-        throws XmlException, IOException {
-        Locale l = getLocale(stl, options);
+    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, Reader reader, SchemaType type, XmlOptions options)
+    throws XmlException, IOException {
+        return syncWrap(stl, options, (l) -> {
+            Cur c = getSaxLoader(options).load(l, new InputSource(reader), options);
+            autoTypeDocument(c, type, options);
+            XmlObject x = (XmlObject) c.getUser();
+            c.release();
+            return x;
+        });
+    }
 
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.parseToXmlObject(is, type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.parseToXmlObject(is, type, options);
-                } finally {
-                    l.exit();
-                }
-            }
+    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, Node node, SchemaType type, XmlOptions options)
+    throws XmlException {
+        try {
+            return syncWrap(stl, options, (l) -> {
+                LoadContext context = new Cur.CurLoadContext(l, options);
+                l.loadNode(node, context);
+                Cur c = context.finish();
+                associateSourceName(c, options);
+                autoTypeDocument(c, type, options);
+                XmlObject x = (XmlObject) c.getUser();
+                c.release();
+                return x;
+            });
+        } catch (IOException e) {
+            assert false : "Doesn't throw IOException";
+            throw new RuntimeException(e);
         }
     }
 
-    private XmlObject parseToXmlObject(InputStream is, SchemaType type,
-                                       XmlOptions options)
-        throws XmlException, IOException {
-        Cur c = getSaxLoader(options).load(this, new InputSource(is),
-            options);
-
-        autoTypeDocument(c, type, options);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
-    }
-
-    //
-    //
-    //
-
-    public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-                                             Reader reader, SchemaType type, XmlOptions options)
-        throws XmlException, IOException {
-        Locale l = getLocale(stl, options);
-
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.parseToXmlObject(reader, type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.parseToXmlObject(reader, type, options);
-                } finally {
-                    l.exit();
-                }
-            }
-        }
-    }
-
-    private XmlObject parseToXmlObject(Reader reader, SchemaType type,
-                                       XmlOptions options)
-        throws XmlException, IOException {
-        Cur c = getSaxLoader(options).load(this, new InputSource(reader),
-            options);
-
-        autoTypeDocument(c, type, options);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
-    }
-
-    //
-    //
-    //
-
-    public static XmlObject parseToXmlObject(SchemaTypeLoader stl, Node node,
-                                             SchemaType type, XmlOptions options)
-        throws XmlException {
-        Locale l = getLocale(stl, options);
-
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.parseToXmlObject(node, type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.parseToXmlObject(node, type, options);
-                } finally {
-                    l.exit();
-                }
-            }
-        }
-    }
-
-    public XmlObject parseToXmlObject(Node node, SchemaType type,
-                                      XmlOptions options)
-        throws XmlException {
-        LoadContext context = new Cur.CurLoadContext(this, options);
-
-        loadNode(node, context);
-
-        Cur c = context.finish();
-
-        associateSourceName(c, options);
-
-        autoTypeDocument(c, type, options);
-
-        XmlObject x = (XmlObject) c.getUser();
-
-        c.release();
-
-        return x;
-    }
-
     private void loadNodeChildren(Node n, LoadContext context) {
         for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling()) {
             loadNode(c, context);
@@ -1077,33 +891,15 @@
         private final XmlOptions _options;
     }
 
-    public static XmlSaxHandler newSaxHandler(SchemaTypeLoader stl,
-                                              SchemaType type, XmlOptions options) {
-        Locale l = getLocale(stl, options);
-
-        if (l.noSync()) {
-            l.enter();
-            try {
-                return l.newSaxHandler(type, options);
-            } finally {
-                l.exit();
-            }
-        } else {
-            synchronized (l) {
-                l.enter();
-                try {
-                    return l.newSaxHandler(type, options);
-                } finally {
-                    l.exit();
-                }
-            }
+    public static XmlSaxHandler newSaxHandler(SchemaTypeLoader stl, SchemaType type, XmlOptions options) {
+        try {
+            return syncWrap(stl, options, (l) -> new XmlSaxHandlerImpl(l, type, options));
+        } catch (XmlException | IOException e) {
+            assert false : "XmlException or IOException is not thrown";
+            throw new RuntimeException(e);
         }
     }
 
-    public XmlSaxHandler newSaxHandler(SchemaType type, XmlOptions options) {
-        return new XmlSaxHandlerImpl(this, type, options);
-    }
-
     // TODO (ericvas ) - have a qname factory here so that the same factory may be
     // used by the parser.  This factory would probably come from my
     // high speed parser.  Otherwise, use a thread local on
@@ -1244,12 +1040,12 @@
         return sb.toString();
     }
 
-    static int getTextValue(Cur c, int wsr, char[] chars, int off, int maxCch) {
+    static int getTextValue(Cur c, char[] chars, int off, int maxCch) {
         // TODO - hack impl for now ... improve
 
         assert c.isNode();
 
-        String s = c._xobj.getValueAsString(wsr);
+        String s = c._xobj.getValueAsString(WS_PRESERVE);
 
         int n = s.length();
 
@@ -1566,19 +1362,6 @@
     }
 
     public static boolean toFirstChildElement(Cur c) {
-//        if (!pushToContainer(c))
-//            return false;
-//
-//        if (!c.toFirstChild() || (!c.isElem() && !toNextSiblingElement(c)))
-//        {
-//            c.pop();
-//            return false;
-//        }
-//
-//        c.popButStay();
-//
-//        return true;
-
         Xobj originalXobj = c._xobj;
         int originalPos = c._pos;
 
@@ -1761,8 +1544,6 @@
         assert c.isContainer();
 
         do {
-            QName cName = c.getName();
-
             while (c.toNextAttr()) {
                 if (c.isXmlns()) {
                     String prefix = c.getXmlnsPrefix();
@@ -1842,14 +1623,11 @@
                 _child = null;
                 _n = -1;
 
-                loop:
-                for (Xobj x = parent._firstChild;
-                     x != null; x = x._nextSibling) {
+                for (Xobj x = parent._firstChild; x != null; x = x._nextSibling) {
                     if (x.isElem() && nameHit(name, set, x._name)) {
                         _child = x;
                         _n = 0;
-
-                        break loop;
+                        break;
                     }
                 }
             }
@@ -1976,9 +1754,9 @@
         }
     }
 
-    boolean isDomCached(Dom d) {
-        return _domNthCache_A._parent == d || _domNthCache_B._parent == d;
-    }
+//    boolean isDomCached(Dom d) {
+//        return _domNthCache_A._parent == d || _domNthCache_B._parent == d;
+//    }
 
     class domNthCache {
 
@@ -2056,36 +1834,31 @@
 
             if (n > _n) {
                 while (n > _n) {
-                    for (Dom x = (Dom) DomImpl.nextSibling(_child); ; x = (Dom) DomImpl.nextSibling(x)) {
-                        if (x == null) {
-                            return null;
-                        }
-
-                        _child = x;
-                        _n++;
-
-                        break;
+                    Dom x = (Dom) DomImpl.nextSibling(_child);
+                    if (x == null) {
+                        return null;
                     }
+
+                    _child = x;
+                    _n++;
                 }
             } else if (n < _n) {
                 while (n < _n) {
-                    for (Dom x = (Dom) DomImpl.prevSibling(_child); ; x = (Dom) DomImpl.prevSibling(x)) {
-                        if (x == null) {
-                            return null;
-                        }
-
-                        _child = x;
-                        _n--;
-
-                        break;
+                    Dom x = (Dom) DomImpl.prevSibling(_child);
+                    if (x == null) {
+                        return null;
                     }
+
+                    _child = x;
+                    _n--;
                 }
             }
 
             return _child;
         }
 
-        public static final int BLITZ_BOUNDARY = 40; //walk small lists
+        // walk small lists
+        public static final int BLITZ_BOUNDARY = 40;
         private long _version;
         private Dom _parent;
         private Dom _child;
@@ -2122,16 +1895,15 @@
         return c;
     }
 
-    final ReferenceQueue refQueue() {
+    final ReferenceQueue<Ref> refQueue() {
         if (_refQueue == null) {
-            _refQueue = new ReferenceQueue();
+            _refQueue = new ReferenceQueue<>();
         }
 
         return _refQueue;
     }
 
-    final static class Ref
-        extends PhantomReference {
+    final static class Ref extends PhantomReference {
         Ref(Cur c, Object obj) {
             super(obj, c._locale.refQueue());
 
@@ -2309,32 +2081,24 @@
         return true;
     }
 
-    static boolean isWhiteSpace(StringBuffer sb) {
-        int l = sb.length();
-
-        while (l-- > 0) {
-            if (!CharUtil.isWhiteSpace(sb.charAt(l))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
+//    static boolean isWhiteSpace(StringBuffer sb) {
+//        int l = sb.length();
+//
+//        while (l-- > 0) {
+//            if (!CharUtil.isWhiteSpace(sb.charAt(l))) {
+//                return false;
+//            }
+//        }
+//
+//        return true;
+//    }
 
     static boolean beginsWithXml(String name) {
-        if (name.length() < 3) {
-            return false;
-        }
-
         char ch;
-
-        if (((ch = name.charAt(0)) == 'x' || ch == 'X') &&
-            ((ch = name.charAt(1)) == 'm' || ch == 'M') &&
-            ((ch = name.charAt(2)) == 'l' || ch == 'L')) {
-            return true;
-        }
-
-        return false;
+        return name.length() >= 3 &&
+               ((ch = name.charAt(0)) == 'x' || ch == 'X') &&
+               ((ch = name.charAt(1)) == 'm' || ch == 'M') &&
+               ((ch = name.charAt(2)) == 'l' || ch == 'L');
     }
 
     static boolean isXmlns(QName name) {
@@ -2408,7 +2172,7 @@
 
         protected void addIdAttr(String eName, String aName) {
             if (_idAttrs == null) {
-                _idAttrs = new java.util.Hashtable();
+                _idAttrs = new java.util.Hashtable<>();
             }
             _idAttrs.put(aName, eName);
         }
@@ -2420,19 +2184,18 @@
             String pre = aqn.getPrefix();
             String lName = aqn.getLocalPart();
             String urnName = "".equals(pre) ? lName : pre + ":" + lName;
-            String eName = (String) _idAttrs.get(urnName);
+            String eName = _idAttrs.get(urnName);
             if (eName == null) {
                 return false;
             }
             //get the name of the parent elt
             pre = eqn.getPrefix();
             lName = eqn.getLocalPart();
-            lName = eqn.getLocalPart();
             urnName = "".equals(pre) ? lName : pre + ":" + lName;
             return eName.equals(urnName);
         }
 
-        private java.util.Hashtable _idAttrs;
+        private java.util.Hashtable<String,String> _idAttrs;
     }
 
     private static class DefaultEntityResolver
@@ -2463,7 +2226,7 @@
 
         if (xr == null) {
             try {
-                xr = SAXHelper.newXMLReader(new XmlOptionsBean(options));
+                xr = SAXHelper.newXMLReader(new XmlOptions(options));
             } catch (Exception e) {
                 throw new XmlException("Problem creating XMLReader", e);
             }
@@ -2506,10 +2269,6 @@
             _startLocator = startLocator;
         }
 
-        SaxHandler() {
-            this(null);
-        }
-
         void initSaxHandler(Locale l, final XmlOptions options) {
             _locale = l;
 
@@ -2531,17 +2290,14 @@
             // Do nothing ... start of document is implicit
         }
 
-        public void endDocument()
-            throws SAXException {
+        public void endDocument() throws SAXException {
             // Do nothing ... end of document is implicit
         }
 
-        public void startElement(String uri, String local, String qName,
-                                 Attributes atts)
-            throws SAXException {
-            if (local.length() == 0) {
-                local = qName;
-            }
+
+        @Override
+        public void startElement(String uri, String localIgnored, String qName, Attributes atts) throws SAXException {
+            // local is ignored in this method
 
             // Out current parser does not error when a
             // namespace is used and not defined.  Check for these here
@@ -2608,9 +2364,7 @@
             }
         }
 
-        public void endElement(String namespaceURI, String localName,
-                               String qName)
-            throws SAXException {
+        public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
             _context.endElement();
             if (_wantLineNumbersAtEndElt && _startLocator != null) {
                 _context.bookmark(
@@ -2619,8 +2373,7 @@
             }
         }
 
-        public void characters(char[] ch, int start, int length)
-            throws SAXException {
+        public void characters(char[] ch, int start, int length) throws SAXException {
             _context.text(ch, start, length);
 
             if (_wantCdataBookmarks && _insideCDATA && _startLocator != null) {
@@ -2637,27 +2390,22 @@
             }
         }
 
-        public void ignorableWhitespace(char[] ch, int start, int length)
-            throws SAXException {
+        public void ignorableWhitespace(char[] ch, int start, int length) {
         }
 
-        public void comment(char[] ch, int start, int length)
-            throws SAXException {
+        public void comment(char[] ch, int start, int length) throws SAXException {
             _context.comment(ch, start, length);
         }
 
-        public void processingInstruction(String target, String data)
-            throws SAXException {
+        public void processingInstruction(String target, String data) throws SAXException {
             _context.procInst(target, data);
         }
 
-        public void startDTD(String name, String publicId, String systemId)
-            throws SAXException {
+        public void startDTD(String name, String publicId, String systemId) throws SAXException {
             _context.startDTD(name, publicId, systemId);
         }
 
-        public void endDTD()
-            throws SAXException {
+        public void endDTD() {
             _context.endDTD();
         }
 
@@ -2678,18 +2426,15 @@
             throws SAXException {
         }
 
-        public void skippedEntity(String name)
-            throws SAXException {
+        public void skippedEntity(String name) {
 //            throw new RuntimeException( "Not impl: skippedEntity" );
         }
 
-        public void startCDATA()
-            throws SAXException {
+        public void startCDATA() {
             _insideCDATA = true;
         }
 
-        public void endCDATA()
-            throws SAXException {
+        public void endCDATA() {
             _insideCDATA = false;
         }
 
@@ -2738,9 +2483,7 @@
         }
     }
 
-    private static abstract class SaxLoader
-        extends SaxHandler
-        implements ErrorHandler {
+    private static abstract class SaxLoader extends SaxHandler implements ErrorHandler {
         SaxLoader(XMLReader xr, Locator startLocator) {
             super(startLocator);
 
@@ -2766,10 +2509,6 @@
             }
         }
 
-        void setEntityResolver(EntityResolver er) {
-            _xr.setEntityResolver(er);
-        }
-
         void postLoad(Cur c) {
             // fix garbage collection of Locale -> Xobj -> STL
             _locale = null;
@@ -2866,21 +2605,12 @@
         return load(s, null);
     }
 
-    public Dom load(String s, XmlOptions options)
-        throws XmlException {
-        Reader r = new StringReader(s);
-
-        try {
+    public Dom load(String s, XmlOptions options) throws XmlException {
+        try (Reader r = new StringReader(s)) {
             return load(r, options);
         } catch (IOException e) {
             assert false : "StringReader should not throw IOException";
-
             throw new XmlException(e.getMessage(), e);
-        } finally {
-            try {
-                r.close();
-            } catch (IOException e) {
-            }
         }
     }
 
@@ -3006,45 +2736,11 @@
     }
 
 
-    private static final class LocalDocumentQNameFactory
-        implements QNameFactory {
-        private final QNameCache _cache = new QNameCache(32);
-
-        public QName getQName(String uri, String local) {
-            return _cache.getName(uri, local, "");
-        }
-
-        public QName getQName(String uri, String local, String prefix) {
-            return _cache.getName(uri, local, prefix);
-        }
-
-        public QName getQName(char[] uriSrc, int uriPos, int uriCch,
-                              char[] localSrc, int localPos, int localCch) {
-            return
-                _cache.getName(new String(uriSrc, uriPos, uriCch),
-                    new String(localSrc, localPos, localCch),
-                    "");
-        }
-
-        public QName getQName(char[] uriSrc, int uriPos, int uriCch,
-                              char[] localSrc, int localPos, int localCch,
-                              char[] prefixSrc, int prefixPos, int prefixCch) {
-            return
-                _cache.getName(new String(uriSrc, uriPos, uriCch),
-                    new String(localSrc, localPos, localCch),
-                    new String(prefixSrc, prefixPos, prefixCch));
-        }
-    }
-
-    //
-    //
-    //
-
     boolean _noSync;
 
     SchemaTypeLoader _schemaTypeLoader;
 
-    private ReferenceQueue _refQueue;
+    private ReferenceQueue<Ref> _refQueue;
     private int _entryCount;
 
     int _numTempFramesLeft;
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Public2.java b/src/main/java/org/apache/xmlbeans/impl/store/Public2.java
deleted file mode 100755
index 6984028..0000000
--- a/src/main/java/org/apache/xmlbeans/impl/store/Public2.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*   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.store;
-
-import org.apache.xmlbeans.*;
-import org.apache.xmlbeans.impl.store.DomImpl.Dom;
-import org.apache.xmlbeans.impl.store.Saver.TextSaver;
-import org.apache.xmlbeans.impl.values.NamespaceManager;
-import org.apache.xmlbeans.impl.values.TypeStore;
-import org.apache.xmlbeans.impl.values.TypeStoreUser;
-import org.apache.xmlbeans.impl.values.TypeStoreVisitor;
-import org.apache.xmlbeans.impl.xpath.XPathFactory;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-public final class Public2
-{
-    private static Locale newLocale ( Saaj saaj )
-    {
-        XmlOptions options = null;
-
-        if (saaj != null)
-        {
-            options = new XmlOptions();
-            options.setSaaj(saaj);
-        }
-
-        return Locale.getLocale( null, options );
-    }
-
-    private static Locale newLocale ( )
-    {
-        return Locale.getLocale( null, null );
-    }
-
-    public static void setSync ( Document doc, boolean sync )
-    {
-        assert doc instanceof Dom;
-
-        Locale l = ((Dom) doc).locale();
-
-        l._noSync = ! sync;
-    }
-
-    public static String compilePath ( String path, XmlOptions options )
-    {
-        return XPathFactory.compilePath( path, options );
-    }
-
-    public static DOMImplementation getDomImplementation ( )
-    {
-        return newLocale( );
-    }
-
-    public static DOMImplementation getDomImplementation ( Saaj saaj )
-    {
-        return newLocale( saaj );
-    }
-
-    public static Document parse ( String s )
-        throws XmlException
-    {
-        Locale l = newLocale();
-
-        Dom d;
-
-        if (l.noSync())         { l.enter(); try { d = l.load( s ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } }
-
-        return (Document) d;
-    }
-
-    public static Document parse ( String s, XmlOptions options )
-        throws XmlException
-    {
-        Locale l = newLocale();
-
-        Dom d;
-
-        if (l.noSync())         { l.enter(); try { d = l.load( s, options ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { d = l.load( s, options ); } finally { l.exit(); } }
-
-        return (Document) d;
-    }
-
-    public static Document parse ( String s, Saaj saaj )
-        throws XmlException
-    {
-        Locale l = newLocale( saaj );
-
-        Dom d;
-
-        if (l.noSync())         { l.enter(); try { d = l.load( s ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } }
-
-        return (Document) d;
-    }
-
-    public static Document parse ( InputStream is, XmlOptions options )
-        throws XmlException, IOException
-    {
-        Locale l = newLocale();
-
-        Dom d;
-
-        if (l.noSync())         { l.enter(); try { d = l.load( is, options ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { d = l.load( is, options ); } finally { l.exit(); } }
-
-        return (Document) d;
-    }
-
-    public static Document parse ( InputStream is, Saaj saaj )
-        throws XmlException, IOException
-    {
-        Locale l = newLocale( saaj );
-
-        Dom d;
-
-        if (l.noSync())         { l.enter(); try { d = l.load( is ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { d = l.load( is ); } finally { l.exit(); } }
-
-        return (Document) d;
-    }
-
-    public static Node getNode ( XMLStreamReader s )
-    {
-        return Jsr173.nodeFromStream( s );
-    }
-
-    public static XMLStreamReader getStream ( Node n )
-    {
-        assert n instanceof Dom;
-
-        Dom d = (Dom) n;
-
-        Locale l = d.locale();
-
-        if (l.noSync())         { l.enter(); try { return DomImpl.getXmlStreamReader( d ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return DomImpl.getXmlStreamReader( d ); } finally { l.exit(); } }
-    }
-
-    public static String save ( Node n )
-    {
-        return save( n, null );
-    }
-
-    public static void save ( Node n, OutputStream os, XmlOptions options ) throws IOException
-    {
-        XmlCursor c = getCursor( n );
-
-        c.save( os, options );
-
-        c.dispose();
-    }
-
-    public static String save ( Node n, XmlOptions options )
-    {
-        assert n instanceof Dom;
-
-        Dom d = (Dom) n;
-
-        Locale l = d.locale();
-
-        if (l.noSync())         { l.enter(); try { return saveImpl( d, options ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return saveImpl( d, options ); } finally { l.exit(); } }
-    }
-
-    private static String saveImpl ( Dom d, XmlOptions options )
-    {
-        Cur c = d.tempCur();
-
-        String s = new TextSaver( c, options, null ).saveToString();
-
-        c.release();
-
-        return s;
-    }
-
-    public static String save ( XmlCursor c )
-    {
-        return save( c, null );
-    }
-
-    public static String save ( XmlCursor xc, XmlOptions options )
-    {
-        Cursor cursor = (Cursor) xc;
-
-        Locale l = cursor.locale();
-
-        if (l.noSync())         { l.enter(); try { return saveImpl( cursor, options ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return saveImpl( cursor, options ); } finally { l.exit(); } }
-    }
-
-    private static String saveImpl ( Cursor cursor, XmlOptions options )
-    {
-        Cur c = cursor.tempCur();
-
-        String s = new TextSaver( c, options, null ).saveToString();
-
-        c.release();
-
-        return s;
-    }
-
-    public static XmlCursor newStore ( )
-    {
-        return newStore( null );
-    }
-
-    public static XmlCursor newStore ( Saaj saaj )
-    {
-        Locale l = newLocale( saaj );
-
-        if (l.noSync())         { l.enter(); try { return _newStore( l ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return _newStore( l ); } finally { l.exit(); } }
-    }
-
-    public static XmlCursor _newStore ( Locale l )
-    {
-        Cur c = l.tempCur();
-
-        c.createRoot();
-
-        Cursor cursor = new Cursor( c );
-
-        c.release();
-
-        return cursor;
-    }
-
-    public static XmlCursor getCursor ( Node n )
-    {
-        assert n instanceof Dom;
-
-        Dom d = (Dom) n;
-
-        Locale l = d.locale();
-
-        if (l.noSync())         { l.enter(); try { return DomImpl.getXmlCursor( d ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return DomImpl.getXmlCursor( d ); } finally { l.exit(); } }
-    }
-
-    public static void dump ( PrintStream o, Dom d )
-    {
-        d.dump( o );
-    }
-
-    public static void dump ( PrintStream o, Node n )
-    {
-        dump( o, (Dom) n );
-    }
-
-    public static void dump ( PrintStream o, XmlCursor c )
-    {
-        ((Cursor) c).dump( o );
-    }
-
-    public static void dump ( PrintStream o, XmlObject x )
-    {
-        XmlCursor xc = x.newCursor();
-        Node n = xc.getDomNode();
-        Dom d = (Dom) n;
-        xc.dispose();
-
-        dump( o, d );
-    }
-
-    public static void dump ( Dom  d )      { dump( System.out, d ); }
-    public static void dump ( Node n )      { dump( System.out, n ); }
-    public static void dump ( XmlCursor c ) { dump( System.out, c ); }
-    public static void dump ( XmlObject x ) { dump( System.out, x ); }
-
-    private static class TestTypeStoreUser implements TypeStoreUser
-    {
-        TestTypeStoreUser ( String value ) { _value = value; }
-        public void attach_store(TypeStore store) { }
-        public SchemaType get_schema_type() { throw new RuntimeException( "Not impl" ); }
-        public TypeStore get_store() { throw new RuntimeException( "Not impl" ); }
-        public void invalidate_value() { }
-        public boolean uses_invalidate_value() { throw new RuntimeException( "Not impl" ); }
-        public String build_text(NamespaceManager nsm) { return _value; }
-        public boolean build_nil() { throw new RuntimeException( "Not impl" ); }
-        public void invalidate_nilvalue() { throw new RuntimeException( "Not impl" ); }
-        public void invalidate_element_order() { throw new RuntimeException( "Not impl" ); }
-        public void validate_now() { throw new RuntimeException( "Not impl" ); }
-        public void disconnect_store() { throw new RuntimeException( "Not impl" ); }
-        public TypeStoreUser create_element_user(QName eltName, QName xsiType) { return new TestTypeStoreUser( "ELEM" ); }
-        public TypeStoreUser create_attribute_user(QName attrName) { throw new RuntimeException( "Not impl" ); }
-        public String get_default_element_text(QName eltName) { throw new RuntimeException( "Not impl" ); }
-        public String get_default_attribute_text(QName attrName) { throw new RuntimeException( "Not impl" ); }
-        public SchemaType get_element_type(QName eltName, QName xsiType) { throw new RuntimeException( "Not impl" ); }
-        public SchemaType get_attribute_type(QName attrName) { throw new RuntimeException( "Not impl" ); }
-        public int get_elementflags(QName eltName) { throw new RuntimeException( "Not impl" ); }
-        public int get_attributeflags(QName attrName) { throw new RuntimeException( "Not impl" ); }
-        public SchemaField get_attribute_field(QName attrName) { throw new RuntimeException( "Not impl" ); }
-        public boolean is_child_element_order_sensitive() { throw new RuntimeException( "Not impl" ); }
-        public QNameSet get_element_ending_delimiters(QName eltname) { throw new RuntimeException( "Not impl" ); }
-        public TypeStoreVisitor new_visitor() { throw new RuntimeException( "Not impl" ); }
-
-        private String _value;
-    }
-
-    public static void test ( ) throws Exception
-    {
-        Xobj x = (Xobj) Public2.parse( "<a>XY</a>" );
-
-        Locale l = x._locale;
-
-        l.enter();
-
-        try
-        {
-            Cur c = x.tempCur();
-
-            c.next();
-
-            Cur c2 = c.tempCur();
-            c2.next();
-
-            Cur c3 = c2.tempCur();
-            c3.nextChars( 1 );
-
-            Cur c4 = c3.tempCur();
-            c4.nextChars( 1 );
-
-            c.dump();
-
-            c.moveNodeContents( c, true );
-
-            c.dump();
-        }
-        catch ( Throwable e )
-        {
-            e.printStackTrace();
-        }
-        finally
-        {
-            l.exit();
-        }
-    }
-}
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Saver.java b/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
index 4f5fc12..372eb55 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
@@ -21,10 +21,6 @@
 import org.apache.xmlbeans.XmlOptions;
 import org.apache.xmlbeans.impl.common.EncodingMap;
 import org.apache.xmlbeans.impl.common.QNameHelper;
-import org.apache.xmlbeans.impl.common.XmlEventBase;
-import org.apache.xmlbeans.impl.common.XmlNameImpl;
-import org.apache.xmlbeans.xml.stream.CharacterData;
-import org.apache.xmlbeans.xml.stream.*;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.ext.LexicalHandler;
@@ -275,14 +271,6 @@
         return _saveNamespacesFirst;
     }
 
-    protected void enterLocale() {
-        _locale.enter();
-    }
-
-    protected void exitLocale() {
-        _locale.exit();
-    }
-
     protected final boolean process() {
         assert _locale.entered();
 
@@ -797,13 +785,6 @@
         return _prefixMap.get(prefix);
     }
 
-    protected Map<String, String> getPrefixMap() {
-        return _prefixMap;
-    }
-
-    //
-    //
-    //
 
     static final class SynthNamespaceSaver extends Saver {
         LinkedHashMap<String, String> _synthNamespaces = new LinkedHashMap<>();
@@ -2159,6 +2140,31 @@
         }
     }
 
+    private interface SyncWrapFun {
+        int process() throws IOException;
+    }
+
+    private static int syncWrap(Locale l, SyncWrapFun fun) throws IOException {
+        if (l.noSync()) {
+            l.enter();
+            try {
+                return fun.process();
+            } finally {
+                l.exit();
+            }
+        } else {
+            synchronized (l) {
+                l.enter();
+                try {
+                    return fun.process();
+                } finally {
+                    l.exit();
+                }
+            }
+        }
+    }
+
+
     static final class TextReader extends Reader {
         TextReader(Cur c, XmlOptions options) {
             _textSaver = new TextSaver(c, options, null);
@@ -2176,68 +2182,17 @@
 
         public int read() throws IOException {
             checkClosed();
-
-            if (_locale.noSync()) {
-                _locale.enter();
-                try {
-                    return _textSaver.read();
-                } finally {
-                    _locale.exit();
-                }
-            } else {
-                synchronized (_locale) {
-                    _locale.enter();
-                    try {
-                        return _textSaver.read();
-                    } finally {
-                        _locale.exit();
-                    }
-                }
-            }
+            return syncWrap(_locale, _textSaver::read);
         }
 
         public int read(char[] cbuf) throws IOException {
             checkClosed();
-
-            if (_locale.noSync()) {
-                _locale.enter();
-                try {
-                    return _textSaver.read(cbuf, 0, cbuf == null ? 0 : cbuf.length);
-                } finally {
-                    _locale.exit();
-                }
-            } else {
-                synchronized (_locale) {
-                    _locale.enter();
-                    try {
-                        return _textSaver.read(cbuf, 0, cbuf == null ? 0 : cbuf.length);
-                    } finally {
-                        _locale.exit();
-                    }
-                }
-            }
+            return syncWrap(_locale, () -> _textSaver.read(cbuf, 0, cbuf == null ? 0 : cbuf.length));
         }
 
         public int read(char[] cbuf, int off, int len) throws IOException {
             checkClosed();
-
-            if (_locale.noSync()) {
-                _locale.enter();
-                try {
-                    return _textSaver.read(cbuf, off, len);
-                } finally {
-                    _locale.exit();
-                }
-            } else {
-                synchronized (_locale) {
-                    _locale.enter();
-                    try {
-                        return _textSaver.read(cbuf, off, len);
-                    } finally {
-                        _locale.exit();
-                    }
-                }
-            }
+            return syncWrap(_locale, () -> _textSaver.read(cbuf, off, len));
         }
 
         private void checkClosed() throws IOException {
@@ -2349,23 +2304,7 @@
                 throw new IndexOutOfBoundsException("Offset is not within buf");
             }
 
-            if (_locale.noSync()) {
-                _locale.enter();
-                try {
-                    return _outStreamImpl.read(bbuf, off, len);
-                } finally {
-                    _locale.exit();
-                }
-            } else {
-                synchronized (_locale) {
-                    _locale.enter();
-                    try {
-                        return _outStreamImpl.read(bbuf, off, len);
-                    } finally {
-                        _locale.exit();
-                    }
-                }
-            }
+            return syncWrap(_locale, () -> _outStreamImpl.read(bbuf, off, len));
         }
 
         private int ensure(int cbyte) {
@@ -2395,22 +2334,11 @@
         }
 
         public int available() {
-            if (_locale.noSync()) {
-                _locale.enter();
-                try {
-                    return ensure(1024);
-                } finally {
-                    _locale.exit();
-                }
-            } else {
-                synchronized (_locale) {
-                    _locale.enter();
-                    try {
-                        return ensure(1024);
-                    } finally {
-                        _locale.exit();
-                    }
-                }
+            try {
+                return syncWrap(_locale, () -> ensure(1024));
+            } catch (IOException e) {
+                assert false : "ensure doesn't throw IOException and available() shouldn't throw either";
+                throw new RuntimeException(e);
             }
         }
 
@@ -2498,8 +2426,7 @@
                 }
 
                 if (_in == _out) {
-                    assert getAvailable() == 0;
-                    assert _free == _buf.length - getAvailable();
+                    assert getAvailable() == 0 && _buf != null && _free == _buf.length;
                     _in = _out = 0;
                 }
 
@@ -2569,597 +2496,6 @@
         private final OutputStreamWriter _converter;
     }
 
-    static final class XmlInputStreamSaver extends Saver {
-        XmlInputStreamSaver(Cur c, XmlOptions options) {
-            super(c, options);
-        }
-
-        @Override
-        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
-            assert c.isElem();
-
-            for (iterateMappings(); hasMapping(); nextMapping()) {
-                enqueue(new StartPrefixMappingImpl(mappingPrefix(), mappingUri()));
-            }
-
-            StartElementImpl.AttributeImpl lastAttr = null;
-            StartElementImpl.AttributeImpl attributes = null;
-            StartElementImpl.AttributeImpl namespaces = null;
-
-            for (int i = 0; i < attrNames.size(); i++) {
-                XMLName attXMLName = computeName(attrNames.get(i), this, true);
-                StartElementImpl.AttributeImpl attr =
-                    new StartElementImpl.NormalAttributeImpl(attXMLName, attrValues.get(i));
-
-                if (attributes == null) {
-                    attributes = attr;
-                } else {
-                    lastAttr._next = attr;
-                }
-
-                lastAttr = attr;
-            }
-
-            lastAttr = null;
-
-            for (iterateMappings(); hasMapping(); nextMapping()) {
-                String prefix = mappingPrefix();
-                String uri = mappingUri();
-
-                StartElementImpl.AttributeImpl attr =
-                    new StartElementImpl.XmlnsAttributeImpl(prefix, uri);
-
-                if (namespaces == null) {
-                    namespaces = attr;
-                } else {
-                    lastAttr._next = attr;
-                }
-
-                lastAttr = attr;
-            }
-
-
-            QName name = c.getName();
-            enqueue(new StartElementImpl(computeName(name, this, false), attributes, namespaces, getPrefixMap()));
-
-            return false;  // still need to be called on end element
-        }
-
-        protected void emitFinish(SaveCur c) {
-            if (c.isRoot()) {
-                enqueue(new EndDocumentImpl());
-            } else {
-                XMLName xmlName = computeName(c.getName(), this, false);
-                enqueue(new EndElementImpl(xmlName));
-            }
-
-            emitEndPrefixMappings();
-        }
-
-        protected void emitText(SaveCur c) {
-            assert c.isText();
-            Object src = c.getChars();
-            int cch = c._cchSrc;
-            int off = c._offSrc;
-
-            enqueue(new CharacterDataImpl(src, cch, off));
-        }
-
-        protected void emitComment(SaveCur c) {
-            enqueue(new CommentImpl(c.getChars(), c._cchSrc, c._offSrc));
-        }
-
-        protected void emitProcinst(SaveCur c) {
-            String target = null;
-            QName name = c.getName();
-
-            if (name != null) {
-                target = name.getLocalPart();
-            }
-
-            enqueue(new ProcessingInstructionImpl(target, c.getChars(), c._cchSrc, c._offSrc));
-        }
-
-        protected void emitDocType(String doctypeName, String publicID, String systemID) {
-            enqueue(new StartDocumentImpl(systemID, null, true, null)); //todo
-        }
-
-        protected void emitStartDoc(SaveCur c) {
-            emitDocType(null, null, null);
-        }
-
-        protected void emitEndDoc(SaveCur c) {
-            enqueue(new EndDocumentImpl());
-        }
-
-        XMLEvent dequeue() {
-            if (_out == null) {
-                enterLocale();
-                try {
-                    if (!process()) {
-                        return null;
-                    }
-                } finally {
-                    exitLocale();
-                }
-            }
-
-            if (_out == null) {
-                return null;
-            }
-
-            XmlEventImpl e = _out;
-
-            if ((_out = _out._next) == null) {
-                _in = null;
-            }
-
-            return e;
-        }
-
-        private void enqueue(XmlEventImpl e) {
-            assert e._next == null;
-
-            if (_in == null) {
-                assert _out == null;
-                _out = _in = e;
-            } else {
-                _in._next = e;
-                _in = e;
-            }
-        }
-
-        //
-        //
-        //
-
-        protected void emitEndPrefixMappings() {
-            for (iterateMappings(); hasMapping(); nextMapping()) {
-                String prevPrefixUri = null; // todo mappingPrevPrefixUri();
-                String prefix = mappingPrefix();
-                String uri = mappingUri();
-
-                if (prevPrefixUri == null) {
-                    enqueue(new EndPrefixMappingImpl(prefix));
-                } else {
-                    enqueue(new ChangePrefixMappingImpl(prefix, uri, prevPrefixUri));
-                }
-            }
-        }
-
-        //
-        //
-        //
-
-        private static XMLName computeName(QName name, Saver saver, boolean needsPrefix) {
-            String uri = name.getNamespaceURI();
-            String local = name.getLocalPart();
-
-            assert uri != null;
-            assert local.length() > 0;
-
-            String prefix = null;
-
-            if (!uri.isEmpty()) {
-                prefix = name.getPrefix();
-                String mappedUri = saver.getNamespaceForPrefix(prefix);
-
-                if (mappedUri == null || !mappedUri.equals(uri)) {
-                    prefix = saver.getUriMapping(uri);
-                }
-
-                // Attrs need a prefix.  If I have not found one, then there must be a default
-                // prefix obscuring the prefix needed for this attr.  Find it manually.
-
-                // NOTE - Consider keeping the currently mapped default URI separate fromn the
-                // _urpMap and _prefixMap.  This way, I would not have to look it up manually
-                // here
-
-                if (needsPrefix && prefix.length() == 0) {
-                    prefix = saver.getNonDefaultUriMapping(uri);
-                }
-
-            }
-
-            return new XmlNameImpl(uri, local, prefix);
-        }
-
-        private static abstract class XmlEventImpl extends XmlEventBase {
-            XmlEventImpl(int type) {
-                super(type);
-            }
-
-            public XMLName getName() {
-                return null;
-            }
-
-            public XMLName getSchemaType() {
-                throw new RuntimeException("NYI");
-            }
-
-            public boolean hasName() {
-                return false;
-            }
-
-            public final Location getLocation() {
-                // (orig v1 comment)TODO - perhaps I can save a location goober sometimes?
-                return null;
-            }
-
-            XmlEventImpl _next;
-        }
-
-        private static class StartDocumentImpl
-            extends XmlEventImpl implements StartDocument {
-            StartDocumentImpl(String systemID, String encoding, boolean isStandAlone, String version) {
-                super(XMLEvent.START_DOCUMENT);
-                _systemID = systemID;
-                _encoding = encoding;
-                _standAlone = isStandAlone;
-                _version = version;
-            }
-
-            public String getSystemId() {
-                return _systemID;
-            }
-
-            public String getCharacterEncodingScheme() {
-                return _encoding;
-            }
-
-            public boolean isStandalone() {
-                return _standAlone;
-            }
-
-            public String getVersion() {
-                return _version;
-            }
-
-            String _systemID;
-            String _encoding;
-            boolean _standAlone;
-            String _version;
-        }
-
-        private static class StartElementImpl
-            extends XmlEventImpl implements StartElement {
-            StartElementImpl(XMLName name, AttributeImpl attributes, AttributeImpl namespaces, Map<String, String> prefixMap) {
-                super(XMLEvent.START_ELEMENT);
-
-                _name = name;
-                _attributes = attributes;
-                _namespaces = namespaces;
-                _prefixMap = prefixMap;
-            }
-
-            public boolean hasName() {
-                return true;
-            }
-
-            public XMLName getName() {
-                return _name;
-            }
-
-            public AttributeIterator getAttributes() {
-                return new AttributeIteratorImpl(_attributes, null);
-            }
-
-            public AttributeIterator getNamespaces() {
-                return new AttributeIteratorImpl(null, _namespaces);
-            }
-
-            public AttributeIterator getAttributesAndNamespaces() {
-                return new AttributeIteratorImpl(_attributes, _namespaces);
-            }
-
-            public Attribute getAttributeByName(XMLName xmlName) {
-                for (AttributeImpl a = _attributes; a != null; a = a._next) {
-                    if (xmlName.equals(a.getName())) {
-                        return a;
-                    }
-                }
-
-                return null;
-            }
-
-            public String getNamespaceUri(String prefix) {
-                return _prefixMap.get(prefix == null ? "" : prefix);
-            }
-
-            public Map<String, String> getNamespaceMap() {
-                return _prefixMap;
-            }
-
-            private static class AttributeIteratorImpl
-                implements AttributeIterator {
-                AttributeIteratorImpl(AttributeImpl attributes, AttributeImpl namespaces) {
-                    _attributes = attributes;
-                    _namespaces = namespaces;
-                }
-
-                public Object monitor() {
-                    return this;
-                }
-
-                public Attribute next() {
-                    synchronized (monitor()) {
-                        checkVersion();
-
-                        AttributeImpl attr = null;
-
-                        if (_attributes != null) {
-                            attr = _attributes;
-                            _attributes = attr._next;
-                        } else if (_namespaces != null) {
-                            attr = _namespaces;
-                            _namespaces = attr._next;
-                        }
-
-                        return attr;
-                    }
-                }
-
-                public boolean hasNext() {
-                    synchronized (monitor()) {
-                        checkVersion();
-
-                        return _attributes != null || _namespaces != null;
-                    }
-                }
-
-                public Attribute peek() {
-                    synchronized (monitor()) {
-                        checkVersion();
-
-                        if (_attributes != null) {
-                            return _attributes;
-                        } else if (_namespaces != null) {
-                            return _namespaces;
-                        }
-
-                        return null;
-                    }
-                }
-
-                public void skip() {
-                    synchronized (monitor()) {
-                        checkVersion();
-
-                        if (_attributes != null) {
-                            _attributes = _attributes._next;
-                        } else if (_namespaces != null) {
-                            _namespaces = _namespaces._next;
-                        }
-                    }
-                }
-
-                private void checkVersion() {
-//                    if (_version != _root.getVersion())
-//                        throw new IllegalStateException( "Document changed" );
-                }
-
-                //                private long          _version;
-                private AttributeImpl _attributes;
-                private AttributeImpl _namespaces;
-            }
-
-            private static abstract class AttributeImpl implements Attribute {
-                /**
-                 * Don't forget to set _name
-                 */
-                AttributeImpl() {
-                }
-
-                public XMLName getName() {
-                    return _name;
-                }
-
-                public String getType() {
-                    // (from v1 impl) TODO - Make sure throwing away this DTD info is ok.
-                    // (from v1 impl) Is there schema info which can return more useful info?
-                    return "CDATA";
-                }
-
-                public XMLName getSchemaType() {
-                    // (from v1 impl) TODO - Can I return something reasonable here?
-                    return null;
-                }
-
-                AttributeImpl _next;
-
-                protected XMLName _name;
-            }
-
-            private static class XmlnsAttributeImpl extends AttributeImpl {
-                XmlnsAttributeImpl(String prefix, String uri) {
-                    super();
-                    _uri = uri;
-
-                    String local;
-
-                    if (prefix.length() == 0) {
-                        prefix = null;
-                        local = "xmlns";
-                    } else {
-                        local = prefix;
-                        prefix = "xmlns";
-                    }
-
-                    _name = new XmlNameImpl(null, local, prefix);
-                }
-
-                public String getValue() {
-                    return _uri;
-                }
-
-                private final String _uri;
-            }
-
-            private static class NormalAttributeImpl extends AttributeImpl {
-                NormalAttributeImpl(XMLName name, String value) {
-                    _name = name;
-                    _value = value;
-                }
-
-                public String getValue() {
-                    return _value;
-                }
-
-                private final String _value; // If invalid in the store
-            }
-
-            private final XMLName _name;
-            private final Map<String, String> _prefixMap;
-
-            private final AttributeImpl _attributes;
-            private final AttributeImpl _namespaces;
-        }
-
-        private static class StartPrefixMappingImpl
-            extends XmlEventImpl implements StartPrefixMapping {
-            StartPrefixMappingImpl(String prefix, String uri) {
-                super(XMLEvent.START_PREFIX_MAPPING);
-
-                _prefix = prefix;
-                _uri = uri;
-            }
-
-            public String getNamespaceUri() {
-                return _uri;
-            }
-
-            public String getPrefix() {
-                return _prefix;
-            }
-
-            private final String _prefix;
-            private final String _uri;
-        }
-
-        private static class ChangePrefixMappingImpl
-            extends XmlEventImpl implements ChangePrefixMapping {
-            ChangePrefixMappingImpl(String prefix, String oldUri, String newUri) {
-                super(XMLEvent.CHANGE_PREFIX_MAPPING);
-
-                _oldUri = oldUri;
-                _newUri = newUri;
-                _prefix = prefix;
-            }
-
-            public String getOldNamespaceUri() {
-                return _oldUri;
-            }
-
-            public String getNewNamespaceUri() {
-                return _newUri;
-            }
-
-            public String getPrefix() {
-                return _prefix;
-            }
-
-            private final String _oldUri;
-            private final String _newUri;
-            private final String _prefix;
-        }
-
-        private static class EndPrefixMappingImpl
-            extends XmlEventImpl implements EndPrefixMapping {
-            EndPrefixMappingImpl(String prefix) {
-                super(XMLEvent.END_PREFIX_MAPPING);
-                _prefix = prefix;
-            }
-
-            public String getPrefix() {
-                return _prefix;
-            }
-
-            private final String _prefix;
-        }
-
-        private static class EndElementImpl
-            extends XmlEventImpl implements EndElement {
-            EndElementImpl(XMLName name) {
-                super(XMLEvent.END_ELEMENT);
-
-                _name = name;
-            }
-
-            public boolean hasName() {
-                return true;
-            }
-
-            public XMLName getName() {
-                return _name;
-            }
-
-            private final XMLName _name;
-        }
-
-        private static class EndDocumentImpl
-            extends XmlEventImpl implements EndDocument {
-            EndDocumentImpl() {
-                super(XMLEvent.END_DOCUMENT);
-            }
-        }
-
-        private static class TripletEventImpl
-            extends XmlEventImpl implements CharacterData {
-            TripletEventImpl(int eventType, Object obj, int cch, int off) {
-                super(eventType);
-                _obj = obj;
-                _cch = cch;
-                _off = off;
-            }
-
-            public String getContent() {
-                return CharUtil.getString(_obj, _off, _cch);
-            }
-
-            public boolean hasContent() {
-                return _cch > 0;
-            }
-
-            private final Object _obj;
-            private final int _cch;
-            private final int _off;
-        }
-
-        private static class CharacterDataImpl
-            extends TripletEventImpl implements CharacterData {
-            CharacterDataImpl(Object obj, int cch, int off) {
-                super(XMLEvent.CHARACTER_DATA, obj, cch, off);
-            }
-        }
-
-        private static class CommentImpl
-            extends TripletEventImpl implements Comment {
-            CommentImpl(Object obj, int cch, int off) {
-                super(XMLEvent.COMMENT, obj, cch, off);
-            }
-        }
-
-        private static class ProcessingInstructionImpl
-            extends TripletEventImpl implements ProcessingInstruction {
-            ProcessingInstructionImpl(String target, Object obj, int cch, int off) {
-                super(XMLEvent.PROCESSING_INSTRUCTION, obj, cch, off);
-                _target = target;
-            }
-
-            public String getTarget() {
-                return _target;
-            }
-
-            public String getData() {
-                return getContent();
-            }
-
-            private final String _target;
-        }
-
-        private XmlEventImpl _in, _out;
-    }
-
     static final class SaxSaver extends Saver {
         SaxSaver(Cur c, XmlOptions options, ContentHandler ch, LexicalHandler lh)
             throws SAXException {
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java
index b83eb5e..1d81ae0 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java
@@ -148,91 +148,6 @@
     @Parameter
     private String partialMethods;
 
-
-
-    /*
-    public String getSourceDir() {
-        return sourceDir;
-    }
-
-    public void setSourceDir(String sourceDir) {
-        this.sourceDir = sourceDir;
-    }
-
-    public String getSourceSchemas() {
-        return sourceSchemas;
-    }
-
-    public void setSourceSchemas(String sourceSchemas) {
-        this.sourceSchemas = sourceSchemas;
-    }
-
-    public String getXmlConfigs() {
-        return xmlConfigs;
-    }
-
-    public void setXmlConfigs(String xmlConfigs) {
-        this.xmlConfigs = xmlConfigs;
-    }
-
-    public String getJavaTargetDir() {
-        return javaTargetDir;
-    }
-
-    public void setJavaTargetDir(String javaTargetDir) {
-        this.javaTargetDir = javaTargetDir;
-    }
-
-    public String getClassTargetDir() {
-        return classTargetDir;
-    }
-
-    public void setClassTargetDir(String classTargetDir) {
-        this.classTargetDir = classTargetDir;
-    }
-
-    public String getCatalogLocation() {
-        return catalogLocation;
-    }
-
-    public void setCatalogLocation(String catalogLocation) {
-        this.catalogLocation = catalogLocation;
-    }
-
-    public String getClassPath() {
-        return classPath;
-    }
-
-    public void setClassPath(String classPath) {
-        this.classPath = classPath;
-    }
-
-    public List<Resource> getResources() {
-        return resources;
-    }
-
-    public void setResources(List<Resource> resources) {
-        this.resources = resources;
-    }
-
-    public boolean isBuildSchemas() {
-        return buildSchemas;
-    }
-
-    public void setBuildSchemas(boolean buildSchemas) {
-        this.buildSchemas = buildSchemas;
-    }
-
-    public String getBaseSchemaLocation() {
-        return baseSchemaLocation;
-    }
-
-    public void setBaseSchemaLocation(String baseSchemaLocation) {
-        if (baseSchemaLocation != null && !(baseSchemaLocation.length() == 0)) {
-            this.baseSchemaLocation = baseSchemaLocation;
-        }
-    }*/
-
     public void execute() throws MojoExecutionException, MojoFailureException {
         if (sourceDir == null || sourceDir.isEmpty() || !new File(sourceDir).isDirectory()) {
             throw new MojoFailureException("Set configuration <sourceDir> (='"+sourceDir+"') to a valid directory containing *.xsd,*.wsdl files.");
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPluginHelp.java b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPluginHelp.java
index cc491f1..a3ee353 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPluginHelp.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPluginHelp.java
@@ -19,15 +19,14 @@
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.impl.common.DocumentHelper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -77,10 +76,8 @@
     private Document build() throws MojoExecutionException {
         getLog().debug("load plugin-help.xml: " + PLUGIN_HELP_PATH);
         try (InputStream is = getClass().getResourceAsStream(PLUGIN_HELP_PATH)) {
-            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-            return dBuilder.parse(is);
-        } catch (IOException | ParserConfigurationException | SAXException e) {
+            return DocumentHelper.readDocument(new XmlOptions(), is);
+        } catch (IOException | SAXException e) {
             throw new MojoExecutionException(e.getMessage(), e);
         }
     }
@@ -154,10 +151,10 @@
         throws MojoExecutionException {
         List<Node> namedChild = findNamedChild(node, elementName);
         if (namedChild.isEmpty()) {
-            throw new MojoExecutionException("Could not find " + elementName + " in plugin-help.xml");
+            throw new MojoExecutionException("Could not find " + elementName + " in plugin.xml");
         }
         if (namedChild.size() > 1) {
-            throw new MojoExecutionException("Multiple " + elementName + " in plugin-help.xml");
+            throw new MojoExecutionException("Multiple " + elementName + " in plugin.xml");
         }
         return namedChild.get(0);
     }
@@ -181,7 +178,7 @@
             return null;
         }
         if (elementsByTagName.size() > 1) {
-            throw new MojoExecutionException("Multiple " + elementName + "in plugin-help.xml");
+            throw new MojoExecutionException("Multiple " + elementName + "in plugin.xml");
         }
         return elementsByTagName.get(0);
     }
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java b/src/main/java/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
index f9a8367..00ffc4e 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
@@ -15,29 +15,17 @@
 
 package org.apache.xmlbeans.impl.tool;
 
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlBeans;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlOptionsBean;
-import org.apache.xmlbeans.XmlError;
+import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.StaxHelper;
 import org.apache.xmlbeans.impl.validator.ValidatingXMLStreamReader;
 
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import java.io.File;
 import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
+import java.util.*;
 
 public class StreamInstanceValidator
 {
@@ -173,7 +161,7 @@
             errors.clear();
 
             try {
-                final XMLInputFactory xmlInputFactory = StaxHelper.newXMLInputFactory(new XmlOptionsBean(options));
+                final XMLInputFactory xmlInputFactory = StaxHelper.newXMLInputFactory(new XmlOptions(options));
 
                 final FileInputStream fis = new FileInputStream(file);
                 final XMLStreamReader rdr =
diff --git a/src/test/java/dom/checkin/ParserTest.java b/src/test/java/dom/checkin/ParserTest.java
index 5f58d30..3b64681 100755
--- a/src/test/java/dom/checkin/ParserTest.java
+++ b/src/test/java/dom/checkin/ParserTest.java
@@ -16,7 +16,7 @@
 
 package dom.checkin;
 
-import org.apache.xmlbeans.XmlOptionsBean;
+import org.apache.xmlbeans.XmlOptions;
 import org.apache.xmlbeans.impl.common.SAXHelper;
 import org.apache.xmlbeans.impl.common.StaxHelper;
 import org.apache.xmlbeans.impl.common.XMLBeansConstants;
@@ -37,7 +37,7 @@
 
     @Test
     public void testXmlOptionsDefaults() {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         assertEquals(2048, options.getEntityExpansionLimit());
         assertFalse(options.isLoadDTDGrammar());
         assertFalse(options.isLoadExternalDTD());
@@ -45,7 +45,7 @@
 
     @Test
     public void testXMLBeansConstantsOverrides() {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         options.setEntityExpansionLimit(1);
         options.setLoadDTDGrammar(true);
         options.setLoadExternalDTD(true);
@@ -56,7 +56,7 @@
 
     @Test
     public void testXmlInputFactoryPropertyDefaults() {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         XMLInputFactory factory = StaxHelper.newXMLInputFactory(options);
         assertEquals(true, factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
         assertEquals(false, factory.getProperty(XMLInputFactory.IS_VALIDATING));
@@ -66,7 +66,7 @@
 
     @Test
     public void testXmlInputFactoryPropertyOverrides() {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         options.setEntityExpansionLimit(1);
         options.setLoadDTDGrammar(true);
         options.setLoadExternalDTD(true);
@@ -77,7 +77,7 @@
 
     @Test
     public void testXMLReader() throws Exception {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         XMLReader reader = SAXHelper.newXMLReader(options);
         assertNotSame(reader, SAXHelper.newXMLReader(options));
         assertFalse(reader.getFeature(XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR));
@@ -90,7 +90,7 @@
 
     @Test
     public void testXMLReaderOverrides() throws Exception {
-        XmlOptionsBean options = new XmlOptionsBean();
+        XmlOptions options = new XmlOptions();
         options.setEntityExpansionLimit(1);
         options.setLoadDTDGrammar(true);
         options.setLoadExternalDTD(true);
diff --git a/src/test/java/dom/common/NewLoader.java b/src/test/java/dom/common/NewLoader.java
index 32fbf74..2230f90 100755
--- a/src/test/java/dom/common/NewLoader.java
+++ b/src/test/java/dom/common/NewLoader.java
@@ -15,32 +15,23 @@
 
 package dom.common;
 
-import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlRuntimeException;
 
 
-public class NewLoader extends Loader{
+public class NewLoader extends Loader {
 
-    public org.w3c.dom.Document load ( String sXml )
-    {
-        try
-        {
-            return (org.w3c.dom.Document) XmlObject.Factory.parse( sXml ).getDomNode();
-        }
-        catch ( XmlException e )
-        {
-            throw new XmlRuntimeException( e );
+    public org.w3c.dom.Document load(String sXml) {
+        try {
+            return (org.w3c.dom.Document) XmlObject.Factory.parse(sXml).getDomNode();
+        } catch (XmlException e) {
+            throw new XmlRuntimeException(e);
         }
     }
-    
 
-    public org.w3c.dom.Document loadSync ( String sXml )
-    {
-        org.w3c.dom.Document doc = load( sXml );
-        
-        org.apache.xmlbeans.impl.store.Public2.setSync( doc,true );
-        
-        return doc;
+
+    public org.w3c.dom.Document loadSync(String sXml) {
+        return load(sXml);
     }
 }
diff --git a/src/test/java/xmlcursor/jsr173/common/IsXXXTest.java b/src/test/java/xmlcursor/jsr173/common/IsXXXTest.java
index 83295c1..0ba5cdd 100755
--- a/src/test/java/xmlcursor/jsr173/common/IsXXXTest.java
+++ b/src/test/java/xmlcursor/jsr173/common/IsXXXTest.java
@@ -18,7 +18,6 @@
 
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.impl.store.Public2;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -101,37 +100,6 @@
         assertFalse(m_stream.hasNext());
     }
 
-    /**
-     * Not Impl
-     */
-    @Test
-    @Ignore
-    public void testNextTag() throws Exception {
-        try {
-            m_stream.nextTag();
-            fail("shouldn't jump to next tag");
-        } catch (IllegalStateException e) {
-        }
-        XmlCursor cur = Public2.newStore();
-        cur.toNextToken();
-        cur.insertComment("cmt");
-        cur.beginElement("foobar");
-        cur.insertChars("   \n");
-        cur.toNextToken();
-        cur.insertProcInst("xml-foo", "http://foo.org");
-        cur.insertElement("foobar1");
-        m_stream = cur.newXMLStreamReader();
-        assertEquals(XMLStreamConstants.START_ELEMENT, m_stream.nextTag());
-        assertEquals("fooabar", m_stream.getLocalName());
-        assertEquals(XMLStreamConstants.END_ELEMENT, m_stream.nextTag());
-        assertEquals("fooabar", m_stream.getLocalName());
-
-        assertEquals(XMLStreamConstants.START_ELEMENT, m_stream.nextTag());
-        assertEquals("fooabar1", m_stream.getLocalName());
-        assertEquals(XMLStreamConstants.END_ELEMENT, m_stream.nextTag());
-        assertEquals("fooabar1", m_stream.getLocalName());
-    }
-
     @Before
     public void setUp() throws Exception {
         XmlCursor cur = XmlObject.Factory.newInstance().newCursor();
