diff --git a/src/main/java/org/apache/xmlbeans/SchemaCodePrinter.java b/src/main/java/org/apache/xmlbeans/SchemaCodePrinter.java
index 8b65366..67821e7 100755
--- a/src/main/java/org/apache/xmlbeans/SchemaCodePrinter.java
+++ b/src/main/java/org/apache/xmlbeans/SchemaCodePrinter.java
@@ -15,26 +15,17 @@
 
 package org.apache.xmlbeans;
 
-import java.io.Writer;
 import java.io.IOException;
+import java.io.Writer;
 
 /**
  * This class is used to provide alternate implementations of the
  * schema Java code generation.
  */
 
-public interface SchemaCodePrinter
-{
-    public void printTypeImpl(Writer writer, SchemaType sType)
-        throws IOException;
-    
-    public void printType(Writer writer, SchemaType sType)
-        throws IOException;
-    
-    /**
-     * @deprecated Obsoleted by functionality in {@link SchemaTypeSystem.save()}
-     */
-    public void printLoader(Writer writer, SchemaTypeSystem system)
-        throws IOException;
+public interface SchemaCodePrinter {
+    void printTypeImpl(Writer writer, SchemaType sType) throws IOException;
+
+    void printType(Writer writer, SchemaType sType) throws IOException;
 }
 
diff --git a/src/main/java/org/apache/xmlbeans/XmlCursor.java b/src/main/java/org/apache/xmlbeans/XmlCursor.java
index 4bf5461..cb49624 100644
--- a/src/main/java/org/apache/xmlbeans/XmlCursor.java
+++ b/src/main/java/org/apache/xmlbeans/XmlCursor.java
@@ -15,74 +15,74 @@
 
 package org.apache.xmlbeans;
 
+import javax.xml.namespace.QName;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import java.util.Collection;
 import java.util.Map;
-import javax.xml.namespace.QName;
 
 /**
- * Represents a position between two logical tokens in an XML document. 
- * 
+ * Represents a position between two logical tokens in an XML document.
+ * <p>
  * The tokens themselves are not exposed as objects, but their type and properties
  * are discoverable through methods on the cursor.  In particular, the general
  * category of token is represented by a {@link XmlCursor.TokenType TokenType}.<br/><br/>
- * 
- * You use an XmlCursor instance to navigate through and manipulate an XML 
- * instance document. 
- * Once you obtain an XML document, you can create a cursor to represent 
- * a specific place in the XML. Because you can use a cursor with or 
- * without a schema corresponding to the XML, cursors are an ideal 
+ * <p>
+ * You use an XmlCursor instance to navigate through and manipulate an XML
+ * instance document.
+ * Once you obtain an XML document, you can create a cursor to represent
+ * a specific place in the XML. Because you can use a cursor with or
+ * without a schema corresponding to the XML, cursors are an ideal
  * way to handle XML without a schema. You can create a new cursor by
- * calling the {@link XmlTokenSource#newCursor() newCursor} method 
+ * calling the {@link XmlTokenSource#newCursor() newCursor} method
  * exposed by an object representing
- * the XML, whether it was parsed into a strong type compiled from 
+ * the XML, whether it was parsed into a strong type compiled from
  * schema or an {@link XmlObject XmlObject} (as in the no-schema case).<br/><br/>
- * 
+ * <p>
  * With an XmlCursor, you can also: <br/><br/>
- * 
+ *
  * <ul>
  * <li>Execute XQuery and XPath expressions against the XML with the
  * execQuery and selectPath methods.</li>
- * 
+ *
  * <li>Edit and reshape the document by inserting, moving, copying, and removing
  * XML.</li>
- * 
+ *
  * <li>Insert bookmarks that "stick" to the XML at the cursor's
  * position even if the cursor or XML moves.</li>
-
+ *
  * <li>Get and set values for containers (elements and whole documents),
  * attributes, processing instructions, and comments.</li>
  * </ul>
- * 
+ * <p>
  * A cursor moves through XML by moving past tokens. A
- * token represents a category of XML markup, such as the start of an element, 
+ * token represents a category of XML markup, such as the start of an element,
  * its end, an attribute, comment, and so on. XmlCursor methods such as
- * toNextToken, toNextSibling, toParent, and so on move the cursor 
- * among tokens. Each token's category is of a particular <em>type</em>, represented 
+ * toNextToken, toNextSibling, toParent, and so on move the cursor
+ * among tokens. Each token's category is of a particular <em>type</em>, represented
  * by one of the nine types defined by the {@link XmlCursor.TokenType TokenType} class. <br/><br/>
- * 
+ * <p>
  * When you get a new cursor for a whole instance document, the cursor is
  * intially located before the STARTDOC token. This token, which has no analogy
  * in the XML specification, is present in this logical model of XML
  * so that you may distinguish between the document as a whole
  * and the content of the document. Terminating the document is an ENDDOC
- * token. This token is also not part of the XML specification. A cursor 
- * located immediately before this token is at the very end of the document. 
- * It is not possible to position the cursor after the ENDDOC token. 
- * Thus, the STARTDOC and ENDDOC tokens are effectively "bookends" for the content of 
+ * token. This token is also not part of the XML specification. A cursor
+ * located immediately before this token is at the very end of the document.
+ * It is not possible to position the cursor after the ENDDOC token.
+ * Thus, the STARTDOC and ENDDOC tokens are effectively "bookends" for the content of
  * the document.<br/><br/>
- * 
+ * <p>
  * For example, for the following XML, if you were the navigate a cursor
- * through the XML document using toNextToken(), the list of token types that 
+ * through the XML document using toNextToken(), the list of token types that
  * follows represents the token sequence you would encounter. <br/><br/>
- * 
+ *
  * <pre>
  * &lt;sample x='y'&gt;
  *     &lt;value&gt;foo&lt;/value&gt;
  * &lt;/sample&gt;
  * </pre>
- * 
+ * <p>
  * STARTDOC <br/>
  * START (sample) <br/>
  * ATTR (x='y') <br/>
@@ -93,331 +93,435 @@
  * TEXT ("\n") <br/>
  * END (sample)<br/>
  * ENDDOC <br/><br/>
- *
+ * <p>
  * When there are no more tokens available, hasNextToken() returns
  * false and toNextToken() returns the special token type NONE and does not move
  * the cursor.
  * <br/><br/>
- * 
- * The {@link #currentTokenType() currentTokenType()} method 
- * will return the type of the token that is immediately after the cursor. 
- * You can also use a number of convenience methods that test for a particular 
- * token type. These include the methods isStart(), 
- * isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean 
- * value indicating whether the token that follows the cursor is the type 
- * in question. 
+ * <p>
+ * The {@link #currentTokenType() currentTokenType()} method
+ * will return the type of the token that is immediately after the cursor.
+ * You can also use a number of convenience methods that test for a particular
+ * token type. These include the methods isStart(),
+ * isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
+ * value indicating whether the token that follows the cursor is the type
+ * in question.
  * <br/><br/>
- * 
- * A few other methods determine whether the token is of a kind that may include 
+ * <p>
+ * A few other methods determine whether the token is of a kind that may include
  * multiple token types. The isAnyAttr() method, for example, returns true if
- * the token immediately following the cursor is any kind of attribute, 
+ * the token immediately following the cursor is any kind of attribute,
  * including those of the ATTR token type and xmlns attributes.
  * <br/><br/>
- * 
+ * <p>
  * Legitimate sequences of tokens for an XML document are described
  * by the following Backus-Naur Form (BNF): <br/>
- * 
+ *
  * <pre>
  * &lt;doc&gt; ::= STARTDOC &lt;attributes&gt; &lt;content&gt; ENDDOC
  * &lt;element&gt; ::= START &lt;attributes&gt; &lt;content&gt; END
  * &lt;attributes&gt; ::= ( ATTR | NAMESPACE ) *
  * &lt;content&gt; ::= ( COMMENT | PROCINST | TEXT | &lt;element&gt; ) *
  * </pre>
- * 
- * Note that a legitimate sequence is STARTDOC ENDDOC, the result of 
- * creating a brand new instance of an empty document. Also note that 
+ * <p>
+ * Note that a legitimate sequence is STARTDOC ENDDOC, the result of
+ * creating a brand new instance of an empty document. Also note that
  * attributes may only follow container tokens (STARTDOC or START)
  */
-public interface XmlCursor extends XmlTokenSource
-{
+public interface XmlCursor extends XmlTokenSource {
     /**
      * An enumeration that identifies the type of an XML token.
      */
-    public static final class TokenType
-    {
-        public String toString ( ) { return _name;  }
+    public static final class TokenType {
+        public String toString() {
+            return _name;
+        }
 
         /**
          * Returns one of the INT_ values defined in this class.
          */
-        public int intValue ( ) { return _value; }
-        
-        /** No token.  See {@link #intValue}. */ 
-        public static final int INT_NONE      = 0;
-        /** The start-document token.  See {@link #intValue}. */ 
-        public static final int INT_STARTDOC  = 1;
-        /** The end-document token.  See {@link #intValue}. */ 
-        public static final int INT_ENDDOC    = 2;
-        /** The start-element token.  See {@link #intValue}. */ 
-        public static final int INT_START     = 3;
-        /** The end-element token.  See {@link #intValue}. */ 
-        public static final int INT_END       = 4;
-        /** The text token.  See {@link #intValue}. */ 
-        public static final int INT_TEXT      = 5;
-        /** The attribute token.  See {@link #intValue}. */ 
-        public static final int INT_ATTR      = 6;
-        /** The namespace declaration token.  See {@link #intValue}. */ 
+        public int intValue() {
+            return _value;
+        }
+
+        /**
+         * No token.  See {@link #intValue}.
+         */
+        public static final int INT_NONE = 0;
+        /**
+         * The start-document token.  See {@link #intValue}.
+         */
+        public static final int INT_STARTDOC = 1;
+        /**
+         * The end-document token.  See {@link #intValue}.
+         */
+        public static final int INT_ENDDOC = 2;
+        /**
+         * The start-element token.  See {@link #intValue}.
+         */
+        public static final int INT_START = 3;
+        /**
+         * The end-element token.  See {@link #intValue}.
+         */
+        public static final int INT_END = 4;
+        /**
+         * The text token.  See {@link #intValue}.
+         */
+        public static final int INT_TEXT = 5;
+        /**
+         * The attribute token.  See {@link #intValue}.
+         */
+        public static final int INT_ATTR = 6;
+        /**
+         * The namespace declaration token.  See {@link #intValue}.
+         */
         public static final int INT_NAMESPACE = 7;
-        /** The comment token.  See {@link #intValue}. */ 
-        public static final int INT_COMMENT   = 8;
-        /** The processing instruction token.  See {@link #intValue}. */ 
-        public static final int INT_PROCINST  = 9;
-        
-        /** True if no token. */
-        public boolean isNone      ( ) { return this == NONE;      }
-        /** True if is start-document token. */
-        public boolean isStartdoc  ( ) { return this == STARTDOC;  }
-        /** True if is end-document token. */
-        public boolean isEnddoc    ( ) { return this == ENDDOC;    }
-        /** True if is start-element token. */
-        public boolean isStart     ( ) { return this == START;     }
-        /** True if is end-element token. */
-        public boolean isEnd       ( ) { return this == END;       }
-        /** True if is text token. */
-        public boolean isText      ( ) { return this == TEXT;      }
-        /** True if is attribute token. */
-        public boolean isAttr      ( ) { return this == ATTR;      }
-        /** True if is namespace declaration token. */
-        public boolean isNamespace ( ) { return this == NAMESPACE; }
-        /** True if is comment token. */
-        public boolean isComment   ( ) { return this == COMMENT;   }
-        /** True if is processing instruction token. */
-        public boolean isProcinst  ( ) { return this == PROCINST;  }
+        /**
+         * The comment token.  See {@link #intValue}.
+         */
+        public static final int INT_COMMENT = 8;
+        /**
+         * The processing instruction token.  See {@link #intValue}.
+         */
+        public static final int INT_PROCINST = 9;
 
-        /** True if is start-document or start-element token */
-        public boolean isContainer ( ) { return this == STARTDOC  || this == START; }
-        /** True if is end-document or end-element token */
-        public boolean isFinish    ( ) { return this == ENDDOC    || this == END;   }
-        /** True if is attribute or namespace declaration token */
-        public boolean isAnyAttr   ( ) { return this == NAMESPACE || this == ATTR;  }
+        /**
+         * True if no token.
+         */
+        public boolean isNone() {
+            return this == NONE;
+        }
 
-        /** The singleton no-token type */
-        public static final TokenType NONE      = new TokenType( "NONE",      INT_NONE      );
-        /** The singleton start-document token type */
-        public static final TokenType STARTDOC  = new TokenType( "STARTDOC",  INT_STARTDOC  );
-        /** The singleton start-document token type */
-        public static final TokenType ENDDOC    = new TokenType( "ENDDOC",    INT_ENDDOC    );
-        /** The singleton start-element token type */
-        public static final TokenType START     = new TokenType( "START",     INT_START     );
-        /** The singleton end-element token type */
-        public static final TokenType END       = new TokenType( "END",       INT_END       );
-        /** The singleton text token type */
-        public static final TokenType TEXT      = new TokenType( "TEXT",      INT_TEXT      );
-        /** The singleton attribute token type */
-        public static final TokenType ATTR      = new TokenType( "ATTR",      INT_ATTR      );
-        /** The singleton namespace declaration token type */
-        public static final TokenType NAMESPACE = new TokenType( "NAMESPACE", INT_NAMESPACE );
-        /** The singleton comment token type */
-        public static final TokenType COMMENT   = new TokenType( "COMMENT",   INT_COMMENT   );
-        /** The singleton processing instruction token type */
-        public static final TokenType PROCINST  = new TokenType( "PROCINST",  INT_PROCINST  );
+        /**
+         * True if is start-document token.
+         */
+        public boolean isStartdoc() {
+            return this == STARTDOC;
+        }
 
-        private TokenType ( String name, int value )
-        {
+        /**
+         * True if is end-document token.
+         */
+        public boolean isEnddoc() {
+            return this == ENDDOC;
+        }
+
+        /**
+         * True if is start-element token.
+         */
+        public boolean isStart() {
+            return this == START;
+        }
+
+        /**
+         * True if is end-element token.
+         */
+        public boolean isEnd() {
+            return this == END;
+        }
+
+        /**
+         * True if is text token.
+         */
+        public boolean isText() {
+            return this == TEXT;
+        }
+
+        /**
+         * True if is attribute token.
+         */
+        public boolean isAttr() {
+            return this == ATTR;
+        }
+
+        /**
+         * True if is namespace declaration token.
+         */
+        public boolean isNamespace() {
+            return this == NAMESPACE;
+        }
+
+        /**
+         * True if is comment token.
+         */
+        public boolean isComment() {
+            return this == COMMENT;
+        }
+
+        /**
+         * True if is processing instruction token.
+         */
+        public boolean isProcinst() {
+            return this == PROCINST;
+        }
+
+        /**
+         * True if is start-document or start-element token
+         */
+        public boolean isContainer() {
+            return this == STARTDOC || this == START;
+        }
+
+        /**
+         * True if is end-document or end-element token
+         */
+        public boolean isFinish() {
+            return this == ENDDOC || this == END;
+        }
+
+        /**
+         * True if is attribute or namespace declaration token
+         */
+        public boolean isAnyAttr() {
+            return this == NAMESPACE || this == ATTR;
+        }
+
+        /**
+         * The singleton no-token type
+         */
+        public static final TokenType NONE = new TokenType("NONE", INT_NONE);
+        /**
+         * The singleton start-document token type
+         */
+        public static final TokenType STARTDOC = new TokenType("STARTDOC", INT_STARTDOC);
+        /**
+         * The singleton start-document token type
+         */
+        public static final TokenType ENDDOC = new TokenType("ENDDOC", INT_ENDDOC);
+        /**
+         * The singleton start-element token type
+         */
+        public static final TokenType START = new TokenType("START", INT_START);
+        /**
+         * The singleton end-element token type
+         */
+        public static final TokenType END = new TokenType("END", INT_END);
+        /**
+         * The singleton text token type
+         */
+        public static final TokenType TEXT = new TokenType("TEXT", INT_TEXT);
+        /**
+         * The singleton attribute token type
+         */
+        public static final TokenType ATTR = new TokenType("ATTR", INT_ATTR);
+        /**
+         * The singleton namespace declaration token type
+         */
+        public static final TokenType NAMESPACE = new TokenType("NAMESPACE", INT_NAMESPACE);
+        /**
+         * The singleton comment token type
+         */
+        public static final TokenType COMMENT = new TokenType("COMMENT", INT_COMMENT);
+        /**
+         * The singleton processing instruction token type
+         */
+        public static final TokenType PROCINST = new TokenType("PROCINST", INT_PROCINST);
+
+        private TokenType(String name, int value) {
             _name = name;
             _value = value;
         }
-        
+
         private String _name;
-        private int    _value;
+        private int _value;
     }
 
     /**
      * Deallocates resources needed to manage the cursor, rendering this cursor
-     * inoperable. Because cursors are managed by a mechanism which stores the 
+     * inoperable. Because cursors are managed by a mechanism which stores the
      * XML, simply letting a cursor go out of scope and having the garbage collector
      * attempt to reclaim it may not produce desirable performance.<br/><br/>
-     *
+     * <p>
      * So, explicitly disposing a cursor allows the underlying implementation
      * to release its responsibility of maintaining its position.<br/><br/>
-     *
+     * <p>
      * After a cursor has been disposed, it may not be used again.  It can
      * throw IllegalStateException or NullPointerException if used after
      * disposal.<br/><br/>
      */
 
-    void dispose ( );
-    
+    void dispose();
+
     /**
      * Moves this cursor to the same position as the moveTo cursor.  if the
      * moveTo cursor is in a different document from this cursor, this cursor
      * will not be moved, and false returned.
-     * 
-     * @param  moveTo  The cursor at the location to which this cursor
-     * should be moved.
-     * @return  true if the cursor moved; otherwise, false.
+     *
+     * @param moveTo The cursor at the location to which this cursor
+     *               should be moved.
+     * @return true if the cursor moved; otherwise, false.
      */
 
-    boolean toCursor ( XmlCursor moveTo );
-    
+    boolean toCursor(XmlCursor moveTo);
+
     /**
      * Saves the current location of this cursor on an internal stack of saved
      * positions (independent of selection). This location may be restored
      * later by calling the pop() method.
      */
 
-    void push ( );
+    void push();
 
     /**
      * Restores the cursor location most recently saved with the push() method.
-     * 
-     * @return  true if there was a location to restore; otherwise, false.
+     *
+     * @return true if there was a location to restore; otherwise, false.
      */
 
-    boolean pop ( );
+    boolean pop();
 
     /**
-     * Executes the specified XPath expression against the XML that this 
+     * Executes the specified XPath expression against the XML that this
      * cursor is in.  The cursor's position does not change.  To navigate to the
      * selections, use {@link #hasNextSelection} and {@link #toNextSelection} (similar to
      * {@link java.util.Iterator}).<br/><br/>
-     * 
-     * The root referred to by the expression should be given as 
+     * <p>
+     * The root referred to by the expression should be given as
      * a dot. The following is an example path expression:
      * <pre>
      * cursor.selectPath("./purchase-order/line-item");
      * </pre>
-     *
+     * <p>
      * Note that this method does not support top-level XPath functions.
-     * 
-     * @param  path  The path expression to execute.
-     * @throws  XmlRuntimeException  If the query expression is invalid.
+     *
+     * @param path The path expression to execute.
+     * @throws XmlRuntimeException If the query expression is invalid.
      */
-    void selectPath ( String path );
+    void selectPath(String path);
 
     /**
-     * Executes the specified XPath expression against the XML that this 
+     * Executes the specified XPath expression against the XML that this
      * cursor is in. The cursor's position does not change.  To navigate to the
      * selections, use hasNextSelection and toNextSelection (similar to
      * java.util.Iterator).<br/><br/>
-     * 
-     * The root referred to by the expression should be given as 
+     * <p>
+     * The root referred to by the expression should be given as
      * a dot. The following is an example path expression:
      * <pre>
      * cursor.selectPath("./purchase-order/line-item");
      * </pre>
-     *
+     * <p>
      * Note that this method does not support top-level XPath functions.
-     * 
-     * @param  path  The path expression to execute.
-     * @param  options  Options for the query. For example, you can call 
-     * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
-     * method to specify a particular name for the query expression 
-     * variable that indicates the context node.
-     * @throws  XmlRuntimeException  If the query expression is invalid.
+     *
+     * @param path    The path expression to execute.
+     * @param options Options for the query. For example, you can call
+     *                the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
+     *                method to specify a particular name for the query expression
+     *                variable that indicates the context node.
+     * @throws XmlRuntimeException If the query expression is invalid.
      */
-    void selectPath ( String path, XmlOptions options );
+    void selectPath(String path, XmlOptions options);
 
     /**
      * Returns whether or not there is a next selection.
-     * 
-     * @return  true if there is a next selection; otherwise, false.
+     *
+     * @return true if there is a next selection; otherwise, false.
      */
 
-    boolean hasNextSelection ( );
-    
+    boolean hasNextSelection();
+
     /**
-     * Moves this cursor to the next location in the selection, 
+     * Moves this cursor to the next location in the selection,
      * if any. See the {@link #selectPath} and {@link #addToSelection} methods.
-     * 
-     * @return  true if the cursor moved; otherwise, false.
+     *
+     * @return true if the cursor moved; otherwise, false.
      */
 
-    boolean toNextSelection ( );
-   
+    boolean toNextSelection();
+
     /**
-     * Moves this cursor to the specified location in the selection. 
+     * Moves this cursor to the specified location in the selection.
      * If i is less than zero or greater than or equal to the selection
      * count, this method returns false.
-     *  
+     * <p>
      * See also the selectPath() and addToSelection() methods.
-     * 
-     * @param  i  The index of the desired location.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param i The index of the desired location.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toSelection ( int i );
-    
+    boolean toSelection(int i);
+
     /**
-     * Returns the count of the current selection. See also the selectPath() 
+     * Returns the count of the current selection. See also the selectPath()
      * and addToSelection() methods.
-     * 
+     * <p>
      * You may experience better performance if you use the iteration
-     * model using the toNextSelection method, rather than 
-     * the indexing model using the getSelectionCount and 
+     * model using the toNextSelection method, rather than
+     * the indexing model using the getSelectionCount and
      * toSelection methods.
-     * 
-     * @return  A number indicating the size of the current selection.
+     *
+     * @return A number indicating the size of the current selection.
      */
 
-    int getSelectionCount ( );
+    int getSelectionCount();
 
-    
+
     /**
-     * Appends the current location of the cursor to the selection.  
-     * See also the selectPath() method. You can use this as an 
+     * Appends the current location of the cursor to the selection.
+     * See also the selectPath() method. You can use this as an
      * alternative to calling the selectPath method when you want
      * to define your own selection.
      */
 
-    void addToSelection ( );
-    
+    void addToSelection();
+
     /**
      * Clears this cursor's selection, but does not modify the document.
      */
-    void clearSelections ( );    
-    
+    void clearSelections();
+
     /**
      * Moves this cursor to the same position as the bookmark.  If the
-     * bookmark is in a different document from this cursor or if the 
+     * bookmark is in a different document from this cursor or if the
      * bookmark is orphaned, this cursor
      * will not be moved, and false will be returned.
-     * 
-     * @param  bookmark  The bookmark at the location to which this
-     * cursor should be moved.
-     * @return  true if the cursor moved; otherwise, false.
+     *
+     * @param bookmark The bookmark at the location to which this
+     *                 cursor should be moved.
+     * @return true if the cursor moved; otherwise, false.
      */
 
-    boolean toBookmark ( XmlBookmark bookmark );
+    boolean toBookmark(XmlBookmark bookmark);
 
     /**
      * Moves this cursor to the location after its current position
      * where a bookmark with the given key exists.  Returns false if no
      * such bookmark exists.
-     * 
-     * @param  key  The key held by the next bookmark at the location to 
-     * which this cursor should be moved.
-     * @return  The next corresponding bookmark, if it exists; null if there
+     *
+     * @param key The key held by the next bookmark at the location to
+     *            which this cursor should be moved.
+     * @return The next corresponding bookmark, if it exists; null if there
      * is no next bookmark with the specified key.
      */
 
-    XmlBookmark toNextBookmark ( Object key );
-    
+    XmlBookmark toNextBookmark(Object key);
+
     /**
      * Moves this cursor to the location before its current position
      * where a bookmark with the given key exists.  Returns false if no
      * such bookmark exists.
-     * 
-     * @param  key  The key held by the previous bookmark at the location to 
-     * which this cursor should be moved.
-     * @return  The previous corresponding bookmark, if it exists; null if 
+     *
+     * @param key The key held by the previous bookmark at the location to
+     *            which this cursor should be moved.
+     * @return The previous corresponding bookmark, if it exists; null if
      * there is no previous bookmark with the specified key.
      */
 
-    XmlBookmark toPrevBookmark ( Object key );
-    
+    XmlBookmark toPrevBookmark(Object key);
+
     /**
      * Returns the name of the current token. Names may be associated with
      * START, ATTR, NAMESPACE or PROCINST. Returns null if there is no
-     * name associated with the current token. For START and ATTR, the 
-     * name returned identifies the name of the element or attribute. 
-     * For NAMESPACE, the local part of the name is the prefix, while 
-     * the URI is the namespace defined. For PROCINST, the local part 
+     * name associated with the current token. For START and ATTR, the
+     * name returned identifies the name of the element or attribute.
+     * For NAMESPACE, the local part of the name is the prefix, while
+     * the URI is the namespace defined. For PROCINST, the local part
      * is the target and the uri is "".
      * <p>
      * In the following example, <code>xmlObject</code> represents
      * an XML instance whose root element is not preceded by any other XML.
-     * This code prints the root element name (here, the local name, or 
+     * This code prints the root element name (here, the local name, or
      * name without URI).
      * <pre>
      * XmlCursor cursor = xmlObject.newCursor();
@@ -426,21 +530,21 @@
      * System.out.println(elementName);
      * </pre>
      *
-     * @return  The name of the XML at this cursor's location; null if there
+     * @return The name of the XML at this cursor's location; null if there
      * is no name.
      */
 
-    QName getName ( );
-    
+    QName getName();
+
     /**
      * Sets the name of the current token. This token can be START, NAMESPACE,
      * ATTR or PROCINST.
-     * 
-     * @param  name  The new name for the current token.
+     *
+     * @param name The new name for the current token.
      */
 
-    void setName ( QName name );
-    
+    void setName(QName name);
+
     /**
      * Returns the namespace URI indicated by the given prefix. The current
      * context must be at a START or STARTDOC. Namespace prefix mappings
@@ -449,18 +553,18 @@
      * a search for the default namespace.  To conform with the
      * XML spec, the default namespace will return the no-namespace ("")
      * if it is not mapped.<br/><br/>
-     * 
-     * Note that this queries the current state of the document. When the 
-     * document is persisted, the saving mechanism may synthesize namespaces 
-     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are 
-     * only present in the serialized form, and are not reflected back into 
+     * <p>
+     * Note that this queries the current state of the document. When the
+     * document is persisted, the saving mechanism may synthesize namespaces
+     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
+     * only present in the serialized form, and are not reflected back into
      * the document being saved.
-     * 
-     * @param  prefix  The namespace prefix for the requested namespace.
-     * @return  The URI for corresponding to the specified prefix if it
+     *
+     * @param prefix The namespace prefix for the requested namespace.
+     * @return The URI for corresponding to the specified prefix if it
      * exists; otherwise, null.
      */
-    String namespaceForPrefix ( String prefix );
+    String namespaceForPrefix(String prefix);
 
     /**
      * Returns a prefix that can be used to indicate a namespace URI.  The
@@ -469,464 +573,464 @@
      * prefix may be returned. Otherwise, a new prefix for the URI will be
      * defined by adding an xmlns attribute to the current container or a
      * parent container.
-     * 
-     * Note that this queries the current state of the document. When the 
-     * document is persisted, the saving mechanism may synthesize namespaces 
-     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are 
-     * only present in the serialized form, and are not reflected back into 
+     * <p>
+     * Note that this queries the current state of the document. When the
+     * document is persisted, the saving mechanism may synthesize namespaces
+     * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are
+     * only present in the serialized form, and are not reflected back into
      * the document being saved.
-     * 
-     * @param  namespaceURI  The namespace URI corresponding to the requested
-     * prefix.
-     * @return  The prefix corresponding to the specified URI if it exists; 
+     *
+     * @param namespaceURI The namespace URI corresponding to the requested
+     *                     prefix.
+     * @return The prefix corresponding to the specified URI if it exists;
      * otherwise, a newly generated prefix.
      */
-    String prefixForNamespace ( String namespaceURI );
-    
+    String prefixForNamespace(String namespaceURI);
+
     /**
      * Adds to the specified map, all the namespaces in scope at the container
-     * where this cursor is positioned. This method is useful for 
+     * where this cursor is positioned. This method is useful for
      * container tokens only.
-     * 
-     * @param  addToThis  The Map to add the namespaces to.
+     *
+     * @param addToThis The Map to add the namespaces to.
      */
 
-    void getAllNamespaces ( Map addToThis );
+    void getAllNamespaces(Map<String, String> addToThis);
 
     /**
      * Returns the strongly-typed XmlObject at the current START,
      * STARTDOC, or ATTR. <br/><br/>
-     * 
+     * <p>
      * The strongly-typed object can be cast to the strongly-typed
      * XBean interface corresponding to the XML Schema Type given
      * by result.getSchemaType().<br/><br/>
-     *
+     * <p>
      * If a more specific type cannot be determined, an XmlObject
      * whose schema type is anyType will be returned.
-     * 
-     * @return  The strongly-typed object at the cursor's current location;
+     *
+     * @return The strongly-typed object at the cursor's current location;
      * null if the current location is not a START, STARTDOC, or ATTR.
      */
 
-    XmlObject getObject ( );
-    
+    XmlObject getObject();
+
     /**
      * Returns the type of the current token. By definition, the current
-     * token is the token immediately to the right of the cursor. 
+     * token is the token immediately to the right of the cursor.
      * If you're in the middle of text, before a character, you get TEXT.
      * You can't dive into the text of an ATTR, COMMENT or PROCINST.<br/><br/>
-     * 
-     * As an alternative, it may be more convenient for you to use one of the 
-     * methods that test for a particular token type. These include the methods 
-     * isStart(), isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean 
-     * value indicating whether the token that follows the cursor is the type 
-     * in question. 
+     * <p>
+     * As an alternative, it may be more convenient for you to use one of the
+     * methods that test for a particular token type. These include the methods
+     * isStart(), isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean
+     * value indicating whether the token that follows the cursor is the type
+     * in question.
      * <br/><br/>
      *
-     * @return  The TokenType instance for the token at the cursor's current
+     * @return The TokenType instance for the token at the cursor's current
      * location.
      */
 
-    TokenType currentTokenType ( );
-    
+    TokenType currentTokenType();
+
     /**
-     * True if the current token is a STARTDOC token type, meaning 
+     * True if the current token is a STARTDOC token type, meaning
      * at the very root of the document.
-     * 
-     * @return  true if this token is a STARTDOC token type; 
+     *
+     * @return true if this token is a STARTDOC token type;
      * otherwise, false.
      */
 
-    boolean isStartdoc ( );
-    
+    boolean isStartdoc();
+
     /**
-     * True if this token is an ENDDOC token type, meaning 
+     * True if this token is an ENDDOC token type, meaning
      * at the very end of the document.
-     * 
-     * @return  true if this token is an ENDDOC token type; 
+     *
+     * @return true if this token is an ENDDOC token type;
      * otherwise, false.
      */
 
-    boolean isEnddoc ( );
-    
+    boolean isEnddoc();
+
     /**
-     * True if this token is a START token type, meaning 
+     * True if this token is a START token type, meaning
      * just before an element's start.
-     * 
-     * @return  true if this token is a START token type; 
+     *
+     * @return true if this token is a START token type;
      * otherwise, false.
      */
 
-    boolean isStart ( );
-    
+    boolean isStart();
+
     /**
-     * True if this token is an END token type, meaning 
+     * True if this token is an END token type, meaning
      * just before an element's end.
-     * 
-     * @return  true if this token is an END token type; 
+     *
+     * @return true if this token is an END token type;
      * otherwise, false.
      */
 
-    boolean isEnd ( );
-    
+    boolean isEnd();
+
     /**
-     * True if the this token is a TEXT token type, meaning 
+     * True if the this token is a TEXT token type, meaning
      * just before or inside text.
-     * 
-     * @return  true if this token is a TEXT token type; 
+     *
+     * @return true if this token is a TEXT token type;
      * otherwise, false.
      */
 
-    boolean isText ( );
-    
+    boolean isText();
+
     /**
-     * True if this token is an ATTR token type, meaning 
+     * True if this token is an ATTR token type, meaning
      * just before an attribute.
-     * 
-     * @return  true if this token is an ATTR token type; 
+     *
+     * @return true if this token is an ATTR token type;
      * otherwise, false.
      */
 
-    boolean isAttr ( );
-    
+    boolean isAttr();
+
     /**
-     * True if this token is a NAMESPACE token type, meaning 
+     * True if this token is a NAMESPACE token type, meaning
      * just before a namespace declaration.
-     * 
-     * @return  true if this token is a NAMESPACE token type; 
+     *
+     * @return true if this token is a NAMESPACE token type;
      * otherwise, false.
      */
 
-    boolean isNamespace ( );
-    
+    boolean isNamespace();
+
     /**
-     * True if this token is a COMMENT token type, meaning 
+     * True if this token is a COMMENT token type, meaning
      * just before a comment.
-     * 
-     * @return  true if this token is a COMMENT token type; 
+     *
+     * @return true if this token is a COMMENT token type;
      * otherwise, false.
      */
 
-    boolean isComment ( );
-    
+    boolean isComment();
+
     /**
-     * True if this token is a PROCINST token type, meaning 
+     * True if this token is a PROCINST token type, meaning
      * just before a processing instruction.
-     * 
-     * @return  true if this token is a PROCINST token type; 
+     *
+     * @return true if this token is a PROCINST token type;
      * otherwise, false.
      */
 
-    boolean isProcinst ( );
-    
+    boolean isProcinst();
+
     /**
-     * True if this token is a container token. The STARTDOC and START 
+     * True if this token is a container token. The STARTDOC and START
      * token types are containers. Containers, including documents and elements,
-     * have the same content model. In other words, a document and an element 
-     * may have the same contents. For example, a document may contain attributes 
+     * have the same content model. In other words, a document and an element
+     * may have the same contents. For example, a document may contain attributes
      * or text, without any child elements.
-     * 
-     * @return  true if this token is a container token; otherwise, false.
+     *
+     * @return true if this token is a container token; otherwise, false.
      */
 
-    boolean isContainer ( );
-    
+    boolean isContainer();
+
     /**
      * True if this token is a finish token. A finish token can be an ENDDOC
      * or END token type.
-
-     * @return  true if this token is a finish token; otherwise, false.
+     *
+     * @return true if this token is a finish token; otherwise, false.
      */
 
-    boolean isFinish ( );
-    
+    boolean isFinish();
+
     /**
      * True if this token is any attribute. This includes an ATTR token type and
      * the NAMESPACE token type attribute.
-     * 
-     * @return  true if the current cursor is at any attribute; otherwise, false.
+     *
+     * @return true if the current cursor is at any attribute; otherwise, false.
      */
 
-    boolean isAnyAttr ( );
-    
+    boolean isAnyAttr();
+
     /**
      * Returns the type of the previous token. By definition, the previous
      * token is the token immediately to the left of the cursor.<br/><br/>
-     *
+     * <p>
      * If you're in the middle of text, after a character, you get TEXT.
-     * 
-     * @return  The TokenType instance for the token immediately before the 
+     *
+     * @return The TokenType instance for the token immediately before the
      * token at the cursor's current location.
      */
 
-    TokenType prevTokenType ( );
-    
+    TokenType prevTokenType();
+
     /**
      * True if there is a next token. When this is false, as when the cursor is
-     * at the ENDDOC token, the toNextToken() method returns NONE and does not 
+     * at the ENDDOC token, the toNextToken() method returns NONE and does not
      * move the cursor.
-     * 
-     * @return  true if there is a next token; otherwise, false.
+     *
+     * @return true if there is a next token; otherwise, false.
      */
 
-    boolean hasNextToken ( );
+    boolean hasNextToken();
 
 
     /**
      * True if there is a previous token. When this is false, toPrevToken
      * returns NONE and does not move the cursor.
-     * 
-     * @return  true if there is a previous token; otherwise, false.
+     *
+     * @return true if there is a previous token; otherwise, false.
      */
 
-    boolean hasPrevToken ( );
-    
+    boolean hasPrevToken();
+
     /**
-     * Moves the cursor to the next token. When there are no more tokens 
-     * available, hasNextToken returns false and toNextToken() returns 
-     * NONE and does not move the cursor. Returns the token type 
+     * Moves the cursor to the next token. When there are no more tokens
+     * available, hasNextToken returns false and toNextToken() returns
+     * NONE and does not move the cursor. Returns the token type
      * of the token to the right of the cursor upon a successful move.
-     * 
-     * @return  The token type for the next token if the cursor was moved;
+     *
+     * @return The token type for the next token if the cursor was moved;
      * otherwise, NONE.
      */
 
-    TokenType toNextToken ( );
+    TokenType toNextToken();
 
     /**
      * Moves the cursor to the previous token. When there is no
      * previous token, returns NONE, otherwise returns the token
      * to the left of the new position of the cursor.
-     * 
-     * @return  The token type for the previous token if the cursor was moved;
+     *
+     * @return The token type for the previous token if the cursor was moved;
      * otherwise, NONE.
      */
 
-    TokenType toPrevToken ( );
-    
+    TokenType toPrevToken();
+
     /**
      * Moves the cursor to the first token in the content of the current
      * START or STARTDOC. That is, the first token after all ATTR and NAMESPACE
      * tokens associated with this START.<br/><br/>
-     *
+     * <p>
      * If the current token is not a START or STARTDOC, the cursor is not
      * moved and NONE is returned. If the current START or STARTDOC
      * has no content, the cursor is moved to the END or ENDDOC token.<br/><br/>
-     * 
-     * @return  The new current token type.
+     *
+     * @return The new current token type.
      */
 
-    TokenType toFirstContentToken ( );
+    TokenType toFirstContentToken();
 
 
     /**
      * Moves the cursor to the END or ENDDOC token corresponding to the
      * current START or STARTDOC, and returns END or ENDDOC. <br/><br/>
-     *
+     * <p>
      * If the current token is not a START or STARTDOC, the cursor is not
      * moved and NONE is returned.
-     * 
-     * @return  The new current token type.
+     *
+     * @return The new current token type.
      */
 
-    TokenType toEndToken ( );
-    
+    TokenType toEndToken();
+
     /**
      * Moves the cursor forward by the specified number of characters, and
      * stops at the next non-TEXT token. Returns the number of characters
-     * actually moved across, which is guaranteed to be less than or equal to  
-     * <em>maxCharacterCount</em>. If there is no further text, or if 
+     * actually moved across, which is guaranteed to be less than or equal to
+     * <em>maxCharacterCount</em>. If there is no further text, or if
      * there is no text at all, returns zero.<br/><br/>
-     *
+     * <p>
      * Note this does not dive into attribute values, comment contents,
      * processing instruction contents, etc., but only content text.<br/><br/>
-     *
-     * You can pass maxCharacterCount &lt; 0 to move over all the text to the 
-     * right. This has the same effect as toNextToken, but returns the amount 
+     * <p>
+     * You can pass maxCharacterCount &lt; 0 to move over all the text to the
+     * right. This has the same effect as toNextToken, but returns the amount
      * of text moved over.
      *
-     * @param  maxCharacterCount  The maximum number of characters by which
-     * the cursor should be moved.
-     * @return  The actual number of characters by which the cursor was moved; 
+     * @param maxCharacterCount The maximum number of characters by which
+     *                          the cursor should be moved.
+     * @return The actual number of characters by which the cursor was moved;
      * 0 if the cursor was not moved.
      */
 
-    int toNextChar ( int maxCharacterCount );
-    
+    int toNextChar(int maxCharacterCount);
+
     /**
      * Moves the cursor backwards by the number of characters given.  Has
      * similar characteristics to the {@link #toNextChar(int) toNextChar} method.
-     * 
-     * @param  maxCharacterCount  The maximum number of characters by which
-     * the cursor should be moved.
-     * @return  The actual number of characters by which the cursor was moved; 
+     *
+     * @param maxCharacterCount The maximum number of characters by which
+     *                          the cursor should be moved.
+     * @return The actual number of characters by which the cursor was moved;
      * 0 if the cursor was not moved.
      */
 
-    int toPrevChar ( int maxCharacterCount );
+    int toPrevChar(int maxCharacterCount);
 
     /**
      * Moves the cursor to the next sibling element, or returns
      * false and does not move the cursor if there is no next sibling
      * element. (By definition the position of an element is the same
      * as the position of its START token.)
-     *
-     * If the current token is not s START, the cursor will be 
-     * moved to the next START without moving out of the scope of the 
+     * <p>
+     * If the current token is not s START, the cursor will be
+     * moved to the next START without moving out of the scope of the
      * current element.
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toNextSibling ( );
-    
+    boolean toNextSibling();
+
     /**
      * Moves the cursor to the previous sibling element, or returns
      * false and does not move the cursor if there is no previous sibling
      * element. (By definition the position of an element is the same
      * as the position of its START token.)
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toPrevSibling ( );
+    boolean toPrevSibling();
 
     /**
      * Moves the cursor to the parent element or STARTDOC, or returns
      * false and does not move the cursor if there is no parent.<br/><br/>
-     *
+     * <p>
      * Works if you're in attributes or content. Returns false only if at
      * STARTDOC. Note that the parent of an END token is the corresponding
      * START token.
-     * 
-     * @return  true if the cursor was moved; false if the cursor is at the STARTDOC
+     *
+     * @return true if the cursor was moved; false if the cursor is at the STARTDOC
      * token.
      */
 
-    boolean toParent ( );
+    boolean toParent();
 
     /**
      * Moves the cursor to the first child element, or returns false and
      * does not move the cursor if there are no element children. <br/><br/>
-     *
-     * If the cursor is not currently in an element, it moves into the 
+     * <p>
+     * If the cursor is not currently in an element, it moves into the
      * first child element of the next element.
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toFirstChild ( );
-    
+    boolean toFirstChild();
+
     /**
      * Moves the cursor to the last element child, or returns false and
      * does not move the cursor if there are no element children.
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toLastChild ( );
-    
+    boolean toLastChild();
+
     /**
-     * Moves the cursor to the first child element of the specified name in 
+     * Moves the cursor to the first child element of the specified name in
      * no namespace.
-     * 
-     * @param  name  The name of the element to move the cursor to.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param name The name of the element to move the cursor to.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toChild ( String name );
-    
+    boolean toChild(String name);
+
     /**
-     * Moves the cursor to the first child element of the specified name in the 
+     * Moves the cursor to the first child element of the specified name in the
      * specified namespace.
-     * 
-     * @param  namespace  The namespace URI for the element to move the cursor 
-     * to.
-     * @param  name  The name of the element to move to.
-     * @return  true if the cursor was moved; otherwise, false.
-     * @throws  IllegalArgumentException  If the name is not a valid local name.
+     *
+     * @param namespace The namespace URI for the element to move the cursor
+     *                  to.
+     * @param name      The name of the element to move to.
+     * @return true if the cursor was moved; otherwise, false.
+     * @throws IllegalArgumentException If the name is not a valid local name.
      */
 
-    boolean toChild ( String namespace, String name );
+    boolean toChild(String namespace, String name);
 
     /**
      * Moves the cursor to the first child element of the specified qualified name.
-     * 
-     * @param  name  The name of the element to move the cursor to.
+     *
+     * @param name The name of the element to move the cursor to.
      */
 
-    boolean toChild ( QName name );
+    boolean toChild(QName name);
 
     /**
      * Moves the cursor to the child element specified by <em>index</em>.
-     * 
-     * @param  index  The position of the element in the sequence of child 
-     * elements.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param index The position of the element in the sequence of child
+     *              elements.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toChild ( int index );
-    
+    boolean toChild(int index);
+
     /**
-     * Moves the cursor to the specified <em>index</em> child element of the 
+     * Moves the cursor to the specified <em>index</em> child element of the
      * specified name, where that element is the .
-     * 
-     * @param  name  The name of the child element to move the cursor to.
-     * @param  index  The position of the element in the sequence of child
-     * elements.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param name  The name of the child element to move the cursor to.
+     * @param index The position of the element in the sequence of child
+     *              elements.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toChild ( QName name, int index );
-    
+    boolean toChild(QName name, int index);
+
     /**
      * Moves the cursor to the next sibling element of the specified name in no
      * namespace.
-     * 
-     * @param  name  The name of the element to move the cursor to.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param name The name of the element to move the cursor to.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toNextSibling ( String name );
-    
+    boolean toNextSibling(String name);
+
     /**
-     * Moves the cursor to the next sibling element of the specified name 
+     * Moves the cursor to the next sibling element of the specified name
      * in the specified namespace.
-     * 
-     * @param  namespace  The namespace URI for the element to move the cursor
-     * to.
-     * @param  name  The name of the element to move the cursor to.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param namespace The namespace URI for the element to move the cursor
+     *                  to.
+     * @param name      The name of the element to move the cursor to.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toNextSibling ( String namespace, String name );
+    boolean toNextSibling(String namespace, String name);
 
-    
+
     /**
-     * Moves the cursor to the next sibling element of the specified 
+     * Moves the cursor to the next sibling element of the specified
      * qualified name.
-     * 
-     * @param  name  The name of the element to move the cursor to.
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @param name The name of the element to move the cursor to.
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toNextSibling ( QName name );
+    boolean toNextSibling(QName name);
 
     /**
      * Moves the cursor to the first attribute of this element, or
      * returns false and does not move the cursor if there are no
      * attributes. The order of attributes is arbitrary, but stable.<br/><br/>
-     *
+     * <p>
      * If the cursor is on a STARTDOC of a document-fragment, this method will
      * move it to the first top level attribute if one exists.<br></br>
-     *
-     * xmlns attributes (namespace declarations) are not considered 
+     * <p>
+     * xmlns attributes (namespace declarations) are not considered
      * attributes by this function.<br/><br/>
-     *
+     * <p>
      * The cursor must be on a START or STARTDOC (in the case of a
      * document fragment with top level attributes) for this method to
      * succeed.
-     *
+     * <p>
      * Example for looping through attributes:
      * <pre>
      *      XmlCursor cursor = ... //cursor on START or STARTDOC
@@ -941,391 +1045,391 @@
      *          while (cursor.toNextAttribute());
      *      }
      * </pre>
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toFirstAttribute ( );
-    
+    boolean toFirstAttribute();
+
     /**
      * Moves the cursor to the last attribute of this element, or
      * returns false and does not move the cursor if there are no
      * attributes. The order of attributes is arbitrary, but stable.<br/><br/>
-     *
-     * xmlns attributes (namespace declarations) are not considered 
+     * <p>
+     * xmlns attributes (namespace declarations) are not considered
      * attributes by this function.<br/><br/>
-     *
+     * <p>
      * The cursor must be on a START or STARTDOC for this method
      * to succeed.
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toLastAttribute ( );
+    boolean toLastAttribute();
 
     /**
      * Moves the cursor to the next sibling attribute, or returns
      * false and does not move the cursor if there is no next
      * sibling attribute. The order of attributes is arbitrary, but stable.<br/><br/>
-     * 
-     * xmlns attributes (namespace declarations) are not considered 
+     * <p>
+     * xmlns attributes (namespace declarations) are not considered
      * attributes by this function.<br/><br/>
-     *
+     * <p>
      * The cursor must be on an attribute for this method to succeed.
-     * @see #toFirstAttribute()
      *
-     * @return  true if the cursor was moved; otherwise, false.
+     * @return true if the cursor was moved; otherwise, false.
+     * @see #toFirstAttribute()
      */
 
-    boolean toNextAttribute ( );
+    boolean toNextAttribute();
 
     /**
      * Moves the cursor to the previous sibling attribute, or returns
      * false and does not move the cursor if there is no previous
      * sibling attribute. The order of attributes is arbitrary, but stable.<br/><br/>
-     * 
-     * xmlns attributes (namespace declarations) are not considered 
+     * <p>
+     * xmlns attributes (namespace declarations) are not considered
      * attributes by this function.<br/><br/>
-     *
+     * <p>
      * The cursor must be on an attribute for this method to succeed.
-     * 
-     * @return  true if the cursor was moved; otherwise, false.
+     *
+     * @return true if the cursor was moved; otherwise, false.
      */
 
-    boolean toPrevAttribute ( );
-    
+    boolean toPrevAttribute();
+
     /**
      * When at a START or STARTDOC, returns the attribute text for the given
      * attribute. When not at a START or STARTDOC or the attribute does not
-     * exist, returns null.  
-     * 
-     * @param  attrName  The name of the attribute whose value is requested.
-     * @return  The attribute's value if it has one; otherwise, null.
+     * exist, returns null.
+     *
+     * @param attrName The name of the attribute whose value is requested.
+     * @return The attribute's value if it has one; otherwise, null.
      */
 
-    String getAttributeText ( QName attrName );
-    
+    String getAttributeText(QName attrName);
+
     /**
      * When at a START or STARTDOC, sets the attribute text for the given
      * attribute. When not at a START or STARTDOC returns false.
      * If the attribute does not exist, one is created.
-     * 
-     * @param  attrName  The name of the attribute whose value is being set.
-     * @param  value  The new value for the attribute.
-     * @return  true if the new value was set; otherwise, false.
+     *
+     * @param attrName The name of the attribute whose value is being set.
+     * @param value    The new value for the attribute.
+     * @return true if the new value was set; otherwise, false.
      */
 
-    boolean setAttributeText ( QName attrName, String value );
-  
+    boolean setAttributeText(QName attrName, String value);
+
     /**
      * When at a START or STARTDOC, removes the attribute with the given name.
-     * 
-     * @param  attrName  The name of the attribute that should be removed.
-     * @return  true if the attribute was removed; otherwise, false.
+     *
+     * @param attrName The name of the attribute that should be removed.
+     * @return true if the attribute was removed; otherwise, false.
      */
 
-    boolean removeAttribute ( QName attrName );
+    boolean removeAttribute(QName attrName);
 
     /**
      * Gets the text value of the current document, element, attribute,
      * comment, procinst or text token. <br/><br/>
-     *
+     * <p>
      * When getting the text value of an element, non-text content such
      * as comments and processing instructions are ignored and text is concatenated.
      * For elements that have nested element children, this
      * returns the concatenated text of all mixed content and the
      * text of all the element children, recursing in first-to-last
      * depthfirst order.<br/><br/>
-     *
+     * <p>
      * For attributes, including namespaces, this returns the attribute value.<br/><br/>
-     *
-     * For comments and processing instructions, this returns the text content 
+     * <p>
+     * For comments and processing instructions, this returns the text content
      * of the comment or PI, not including the delimiting sequences &lt;!-- --&gt;, &lt;? ?&gt;.
      * For a PI, the name of the PI is also not included.
-     *<br/><br/>
+     * <br/><br/>
      * The value of an empty tag is the empty string.<br/><br/>
+     * <p>
+     * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.<br/><br/>
      *
-     * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.<br/><br/>     
-     * 
-     * @return  The text value of the current token if the token's type is
-     * START, STARTDOC, TEXT, ATTR, COMMENT, PROCINST, or NAMESPACE; null 
+     * @return The text value of the current token if the token's type is
+     * START, STARTDOC, TEXT, ATTR, COMMENT, PROCINST, or NAMESPACE; null
      * if the type is NONE.
      */
 
-    String getTextValue ( );
-    
+    String getTextValue();
+
     /**
      * Copies the text value of the current document, element, attribute,
-     * comment, processing instruction or text token, counting right from 
+     * comment, processing instruction or text token, counting right from
      * this cursor's location up to <em>maxCharacterCount</em>,
      * and copies the returned text into <em>returnedChars</em>. <br/><br/>
-     * 
+     * <p>
      * When getting the text value of an element, non-text content such
      * as comments and processing instructions are ignored and text is concatenated.
      * For elements that have nested element children, this
      * returns the concatenated text of all mixed content and the
      * text of all the element children, recursing in first-to-last
      * depthfirst order.<br/><br/>
-     *
+     * <p>
      * For attributes, including namespaces, this returns the attribute value.<br/><br/>
-     *
-     * For comments and processing instructions, this returns the text contents 
+     * <p>
+     * For comments and processing instructions, this returns the text contents
      * of the comment or PI, not including the delimiting sequences &lt;!-- --&gt;, &lt;? ?&gt;. For
      * a PI, the text will not include the name of the PI.<br/><br/>
-     * 
+     * <p>
      * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.<br/><br/>
-     *
+     * <p>
      * The value of an empty tag is the empty string.<br/><br/>
-     * 
-     * @param  returnedChars  A character array to hold the returned characters.
-     * @param  offset  The position within returnedChars to which the first of the 
-     * returned characters should be copied.
-     * @param  maxCharacterCount  The maximum number of characters after this cursor's 
-     * location to copy. A negative value specifies that all characters should be copied.
-     * @return  The actual number of characters copied; 0 if no characters 
+     *
+     * @param returnedChars     A character array to hold the returned characters.
+     * @param offset            The position within returnedChars to which the first of the
+     *                          returned characters should be copied.
+     * @param maxCharacterCount The maximum number of characters after this cursor's
+     *                          location to copy. A negative value specifies that all characters should be copied.
+     * @return The actual number of characters copied; 0 if no characters
      * were copied.
      */
 
-    int getTextValue ( char[] returnedChars, int offset, int maxCharacterCount );
-    
+    int getTextValue(char[] returnedChars, int offset, int maxCharacterCount);
+
     /**
      * Returns the characters of the current TEXT token.  If the current token
      * is not TEXT, returns "".  If in the middle of a TEXT token, returns
      * those chars to the right of the cursor of the TEXT token.
-     * 
-     * @return  The requested text; an empty string if the current token type is
+     *
+     * @return The requested text; an empty string if the current token type is
      * not TEXT.
      */
 
     /**
      * Sets the text value of the XML at this cursor's location if that XML's
      * token type is START, STARTDOC, ATTR, COMMENT or PROCINST. <br/><br/>
-     *
+     * <p>
      * For elements that have nested children this first removes all
      * the content of the element and replaces it with the given text.
-     * 
-     * @param  text  The text to use as a new value.
-     * @throws  java.lang.IllegalStateException  If the token type at this
-     * cursor's location is not START, STARTDOC, ATTR, COMMENT or
-     * PROCINST.
+     *
+     * @param text The text to use as a new value.
+     * @throws java.lang.IllegalStateException If the token type at this
+     *                                         cursor's location is not START, STARTDOC, ATTR, COMMENT or
+     *                                         PROCINST.
      */
-    void setTextValue ( String text );
-    
+    void setTextValue(String text);
+
     /**
      * Sets the text value of the XML at this cursor's location (if that XML's
-     * token type is START, STARTDOC, ATTR, COMMENT or PROCINST) to the 
+     * token type is START, STARTDOC, ATTR, COMMENT or PROCINST) to the
      * contents of the specified character array. <br/><br/>
-     *
+     * <p>
      * For elements that have nested children this first removes all
      * the content of the element and replaces it with the given text.
-     * 
-     * @param  sourceChars  A character array containing the XML's new value.
-     * @param  offset  The position within sourceChars from which the first of 
-     * the source characters should be copied.
-     * @param  length  The maximum number of characters to set as the XML's new
-     * value.
-     * @throws  java.lang.IllegalArgumentException  If the token type at this
-     * cursor's location is not START, STARTDOC, ATTR, COMMENT or
-     * PROCINST.
+     *
+     * @param sourceChars A character array containing the XML's new value.
+     * @param offset      The position within sourceChars from which the first of
+     *                    the source characters should be copied.
+     * @param length      The maximum number of characters to set as the XML's new
+     *                    value.
+     * @throws java.lang.IllegalArgumentException If the token type at this
+     *                                            cursor's location is not START, STARTDOC, ATTR, COMMENT or
+     *                                            PROCINST.
      */
-    void setTextValue ( char[] sourceChars, int offset, int length );
+    void setTextValue(char[] sourceChars, int offset, int length);
 
     /**
      * Returns characters to the right of the cursor up to the next token.
      */
-    String getChars ( );
-    
+    String getChars();
+
     /**
-     * Copies characters up to the specified maximum number, counting right from 
-     * this cursor's location to the character at <em>maxCharacterCount</em>.  The 
+     * Copies characters up to the specified maximum number, counting right from
+     * this cursor's location to the character at <em>maxCharacterCount</em>.  The
      * returned characters are added to <em>returnedChars</em>, with the first
-     * character copied to the <em>offset</em> position. The <em>maxCharacterCount</em> 
-     * parameter should be less than or equal to the length of <em>returnedChars</em> 
-     * minus <em>offset</em>. Copies a number of characters, which is 
-     * either <em>maxCharacterCount</em> or the number of characters up to the next token, 
+     * character copied to the <em>offset</em> position. The <em>maxCharacterCount</em>
+     * parameter should be less than or equal to the length of <em>returnedChars</em>
+     * minus <em>offset</em>. Copies a number of characters, which is
+     * either <em>maxCharacterCount</em> or the number of characters up to the next token,
      * whichever is less.
-     * 
-     * @param  returnedChars  A character array to hold the returned characters.
-     * @param  offset  The position within returnedChars at which the first of the 
-     * returned characters should be added.
-     * @param  maxCharacterCount  The maximum number of characters after this cursor's 
-     * location to return.
-     * @return  The actual number of characters returned; 0 if no characters 
-     * were returned or if the current token is not TEXT. 
+     *
+     * @param returnedChars     A character array to hold the returned characters.
+     * @param offset            The position within returnedChars at which the first of the
+     *                          returned characters should be added.
+     * @param maxCharacterCount The maximum number of characters after this cursor's
+     *                          location to return.
+     * @return The actual number of characters returned; 0 if no characters
+     * were returned or if the current token is not TEXT.
      */
 
-    int getChars ( char[] returnedChars, int offset, int maxCharacterCount );
-    
+    int getChars(char[] returnedChars, int offset, int maxCharacterCount);
+
     /**
-     * Moves the cursor to the STARTDOC token, which is the 
+     * Moves the cursor to the STARTDOC token, which is the
      * root of the document.
      */
 
-    void toStartDoc ( );
-    
+    void toStartDoc();
+
     /**
      * Moves the cursor to the ENDDOC token, which is the end
      * of the document.
      */
 
-    void toEndDoc ( );
-    
+    void toEndDoc();
+
     /**
      * Determines if the specified cursor is in the same document as
      * this cursor.
-     * 
-     * @param  cursor  The cursor that may be in the same document
-     * as this cursor.
-     * @return  true if the specified cursor is in the same document;
+     *
+     * @param cursor The cursor that may be in the same document
+     *               as this cursor.
+     * @return true if the specified cursor is in the same document;
      * otherwise, false.
      */
 
-    boolean isInSameDocument ( XmlCursor cursor );
+    boolean isInSameDocument(XmlCursor cursor);
 
     /**
-     * Returns an integer indicating whether this cursor is before, 
+     * Returns an integer indicating whether this cursor is before,
      * after, or at the same position as the specified cursor. <br/><br/>
-     * 
+     *
      * <code>a.comparePosition(b) < 0</code> means a is to the left of b.<br/>
      * <code>a.comparePosition(b) == 0</code> means a is at the same position as b.<br/>
      * <code>a.comparePosition(b) > 0</code> means a is to the right of b.<br/><br/>
-     *
+     * <p>
      * The sort order of cursors in the document is the token order.
      * For example, if cursor "a" is at a START token and the cursor "b"
      * is at a token within the contents of the same element, then
      * a.comparePosition(b) will return -1, meaning that the position
      * of a is before b.
-     * 
-     * @param  cursor  The cursor whose position should be compared
-     * with this cursor.
-     * @return  1 if this cursor is after the specified cursor; 0 if 
-     * this cursor is at the same position as the specified cursor; 
+     *
+     * @param cursor The cursor whose position should be compared
+     *               with this cursor.
+     * @return 1 if this cursor is after the specified cursor; 0 if
+     * this cursor is at the same position as the specified cursor;
      * -1 if this cursor is before the specified cursor.
-     * @throws  java.lang.IllegalArgumentException  If the specified
-     * cursor is not in the same document as this cursor.
+     * @throws java.lang.IllegalArgumentException If the specified
+     *                                            cursor is not in the same document as this cursor.
      */
 
-    int comparePosition ( XmlCursor cursor );
-    
+    int comparePosition(XmlCursor cursor);
+
     /**
      * Determines if this cursor is to the left of (or before)
-     * the specified cursor. Note that this is the same as 
+     * the specified cursor. Note that this is the same as
      * <code>a.comparePosition(b) &lt; 0 </code>
-     * 
-     * @param  cursor  The cursor whose position should be compared
-     * with this cursor.
-     * @return  true if this cursor is to the left of the specified
+     *
+     * @param cursor The cursor whose position should be compared
+     *               with this cursor.
+     * @return true if this cursor is to the left of the specified
      * cursor; otherwise, false.
      */
 
-    boolean isLeftOf ( XmlCursor cursor );
-    
+    boolean isLeftOf(XmlCursor cursor);
+
     /**
      * Determines if this cursor is at the same position as
-     * the specified cursor. Note that this is the same as 
+     * the specified cursor. Note that this is the same as
      * <code>a.comparePosition(b) == 0 </code>
-     * 
-     * @param  cursor  The cursor whose position should be compared
-     * with this cursor.
-     * @return  true if this cursor is at the same position as 
+     *
+     * @param cursor The cursor whose position should be compared
+     *               with this cursor.
+     * @return true if this cursor is at the same position as
      * the specified cursor; otherwise, false.
      */
 
-    boolean isAtSamePositionAs ( XmlCursor cursor );
-    
+    boolean isAtSamePositionAs(XmlCursor cursor);
+
     /**
      * Determines if this cursor is to the right of (or after)
-     * the specified cursor. Note that this is the same as 
+     * the specified cursor. Note that this is the same as
      * <code>a.comparePosition(b) &gt; 0 </code>
-     * 
-     * @param  cursor  The cursor whose position should be compared
-     * with this cursor.
-     * @return  true if this cursor is to the right of the specified
+     *
+     * @param cursor The cursor whose position should be compared
+     *               with this cursor.
+     * @return true if this cursor is to the right of the specified
      * cursor; otherwise, false.
      */
 
-    boolean isRightOf ( XmlCursor cursor );
-    
+    boolean isRightOf(XmlCursor cursor);
+
     /**
      * Executes the specified XQuery expression against the XML this
      * cursor is in. <br/><br/>
-     * 
+     * <p>
      * The query may be a String or a compiled query. You can precompile
      * an XQuery expression using the XmlBeans.compileQuery method. <br/><br>
-     * 
-     * The root referred to by the expression should be given as 
+     * <p>
+     * The root referred to by the expression should be given as
      * a dot. The following is an example path expression:
      * <pre>
      * XmlCursor results = cursor.execQuery("purchase-order/line-item[price &lt;= 20.00]");
      * </pre>
-     * 
-     * @param  query  The XQuery expression to execute.
-     * @return  A cursor containing the results of the query.
-     * @throws  XmlRuntimeException  If the query expression is invalid.
+     *
+     * @param query The XQuery expression to execute.
+     * @return A cursor containing the results of the query.
+     * @throws XmlRuntimeException If the query expression is invalid.
      */
 
-    XmlCursor execQuery ( String query );
-    
+    XmlCursor execQuery(String query);
+
     /**
      * Executes the specified XQuery expression against the XML this
      * cursor is in, and using the specified options. <br/><br/>
-     * 
-     * @param  query  The XQuery expression to execute.
-     * @param  options  Options for the query. For example, you can call 
-     * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
-     * method to specify a particular name for the query expression 
-     * variable that indicates the context node.
-     * @throws  XmlRuntimeException  If the query expression is invalid.
+     *
+     * @param query   The XQuery expression to execute.
+     * @param options Options for the query. For example, you can call
+     *                the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)}
+     *                method to specify a particular name for the query expression
+     *                variable that indicates the context node.
+     * @throws XmlRuntimeException If the query expression is invalid.
      */
 
-    XmlCursor execQuery ( String query, XmlOptions options );
-    
+    XmlCursor execQuery(String query, XmlOptions options);
+
     /**
      * Represents the state of a dcoument at a particular point
      * in time.  It is used to determine if a document has been changed
      * since that point in time.
      */
-    interface ChangeStamp
-    {
+    interface ChangeStamp {
         /**
          * Returns whether or not the document assoiated with this ChangeStamp
          * has been altered since the ChangeStamp had been created.
          */
-        public boolean hasChanged ( );
+        public boolean hasChanged();
     }
-    
+
     /**
-     * Returns the current change stamp for the document the current cursor is in. 
+     * Returns the current change stamp for the document the current cursor is in.
      * This change stamp can be queried at a later point in time to find out
      * if the document has changed.
-     * 
-     * @return  The change stamp for the document the current cursor is in.
+     *
+     * @return The change stamp for the document the current cursor is in.
      */
-    ChangeStamp getDocChangeStamp ( );
-    
+    ChangeStamp getDocChangeStamp();
+
     /**
      * Subclasses of XmlBookmark can be used to annotate an XML document.
-     * This class is abstract to prevent parties from inadvertently 
+     * This class is abstract to prevent parties from inadvertently
      * interfering with each others' bookmarks without explicitly
      * sharing a bookmark class.
      */
 
-    abstract class XmlBookmark
-    {
+    abstract class XmlBookmark {
         /**
          * Constructs a strongly-referenced bookmark.
-         */ 
-        public XmlBookmark ( ) { this( false ); }
-        
+         */
+        public XmlBookmark() {
+            this(false);
+        }
+
         /**
          * Constructs a bookmark.
+         *
          * @param weak true if the document's reference to the bookmark should be a WeakReference
-         */ 
-        public XmlBookmark ( boolean weak )
-        {
-            _ref = weak ? new WeakReference( this ) : null;
+         */
+        public XmlBookmark(boolean weak) {
+            _ref = weak ? new WeakReference(this) : null;
         }
-        
+
         /**
          * Call the createCursor method to create a new cursor which is
          * positioned at the same splace as the bookmark.  It is much more
@@ -1339,18 +1443,16 @@
          *
          * @return the new cursor
          */
-        public final XmlCursor createCursor ( )
-        {
+        public final XmlCursor createCursor() {
             return _currentMark == null ? null : _currentMark.createCursor();
         }
 
         /**
          * @param c the cursor to be moved
          * @return the given cursor moved to this bookmark
-         */ 
-        public final XmlCursor toBookmark ( XmlCursor c )
-        {
-            return c == null || !c.toBookmark( this ) ? createCursor() : c;
+         */
+        public final XmlCursor toBookmark(XmlCursor c) {
+            return c == null || !c.toBookmark(this) ? createCursor() : c;
         }
 
         /**
@@ -1362,24 +1464,23 @@
          *
          * @return default key for bookmarks
          */
-        public Object getKey ( )
-        {
+        public Object getKey() {
             return this.getClass();
         }
-        
+
         /**
          * The mark is set by the host document; it is capable of
          * returning an XmlCursor implementation at the location of
          * the bookmark.
-         */ 
-        public       XmlMark   _currentMark;
-        
+         */
+        public XmlMark _currentMark;
+
         /**
          * If non-null, the ref is used by the host document
          * to maintain a reference to the bookmark.  If it is a weak
          * reference, the host document will not prevent the Bookmark
          * from being garbage collected.
-         */ 
+         */
         public final Reference _ref;
     }
 
@@ -1391,428 +1492,427 @@
      * receives the new content.
      */
 
-    interface XmlMark
-    {
-        XmlCursor createCursor ( );
+    interface XmlMark {
+        XmlCursor createCursor();
     }
 
     /**
      * Sets a bookmark to the document at this cursor's location.
-     *
-     * The bookmark is attached to the token in the tree immediately 
+     * <p>
+     * The bookmark is attached to the token in the tree immediately
      * after the cursor. If the tree is manipulated to move
      * that object to a different place, the bookmark moves with it.
      * If the tree is manipulated to delete that token from the
      * tree, the bookmark is orphaned. Copy operations do not copy
      * bookmarks.
-     * 
-     * @param  bookmark  The bookmark to set.
+     *
+     * @param bookmark The bookmark to set.
      */
 
-    void setBookmark ( XmlBookmark bookmark );
-    
+    void setBookmark(XmlBookmark bookmark);
+
     /**
-     * Retrieves the bookmark with the specified key 
-     * at this cursor's location. If there is no bookmark whose key is 
-     * given by the specified key at the current position, null is returned. 
-     * If the {@link XmlCursor.XmlBookmark#getKey() getKey} method is not overridden on 
+     * Retrieves the bookmark with the specified key
+     * at this cursor's location. If there is no bookmark whose key is
+     * given by the specified key at the current position, null is returned.
+     * If the {@link XmlCursor.XmlBookmark#getKey() getKey} method is not overridden on
      * the bookmark, then the bookmark's class is used as the key.
-     * 
-     * @param  key  The key for the bookmark to retrieve.
-     * @return  The requested bookmark; null if there is no bookmark
+     *
+     * @param key The key for the bookmark to retrieve.
+     * @return The requested bookmark; null if there is no bookmark
      * corresponding to the specified key.
      */
 
-    XmlBookmark getBookmark ( Object key );
-    
+    XmlBookmark getBookmark(Object key);
+
     /**
      * Clears the bookmark whose key is specified, if the bookmark
      * exists at this cursor's location.
-     * 
-     * @param  key  The for the bookmark to clear.
+     *
+     * @param key The for the bookmark to clear.
      */
 
-    void clearBookmark ( Object key );
+    void clearBookmark(Object key);
 
     /**
      * Retrieves all the bookmarks at this location, adding them to
      * the specified collection. Bookmarks held by weak references are
      * added to this collection as Weak referenced objects pointing to the
      * bookmark.
-     * 
-     * @param  listToFill  The collection that will contain bookmarks
-     * returned by this method.
+     *
+     * @param listToFill The collection that will contain bookmarks
+     *                   returned by this method.
      */
 
-    void getAllBookmarkRefs ( Collection listToFill );
+    void getAllBookmarkRefs(Collection listToFill);
 
     /**
      * Removes the XML that is immediately after this cursor.
-     * 
-     * For the TEXT, ATTR, NAMESPACE, COMMENT and PROCINST tokens, a single 
-     * token is removed. For a START token, the corresponding element and all 
-     * of its contents are removed. For all other tokens, this is a no-op. 
+     * <p>
+     * For the TEXT, ATTR, NAMESPACE, COMMENT and PROCINST tokens, a single
+     * token is removed. For a START token, the corresponding element and all
+     * of its contents are removed. For all other tokens, this is a no-op.
      * You cannot remove a STARTDOC.
-     * 
-     * The cursors located in the XML that was removed all collapse to the 
+     * <p>
+     * The cursors located in the XML that was removed all collapse to the
      * same location. All bookmarks in this XML will be orphaned.
-     * 
-     * @return true if anything was removed; false only if the cursor is 
+     *
+     * @return true if anything was removed; false only if the cursor is
      * just before END or ENDDOC token.
-     * @throws java.lang.IllegalArgumentException  If the cursor is at a 
-     * STARTDOC token.
+     * @throws java.lang.IllegalArgumentException If the cursor is at a
+     *                                            STARTDOC token.
      */
 
-    boolean removeXml ( );
+    boolean removeXml();
 
     /**
      * Moves the XML immediately after this cursor to the location
-     * specified by the <em>toHere</em> cursor, shifting XML at that location 
-     * to the right to make room. For the TEXT, ATTR, NAMESPACE, 
+     * specified by the <em>toHere</em> cursor, shifting XML at that location
+     * to the right to make room. For the TEXT, ATTR, NAMESPACE,
      * COMMENT and PROCINST tokens, a single token is moved. For a start token, the
      * element and all of its contents are moved. For all other tokens, this
      * is a no-op.
-     * 
+     * <p>
      * The bookmarks located in the XML that was moved also move to the
      * new location; the cursors don't move with the content.
-     * 
-     * @param  toHere  The cursor at the location to which the XML should
-     * be moved.
+     *
+     * @param toHere The cursor at the location to which the XML should
+     *               be moved.
      * @return true if anything was moved.  This only happens when the XML to be
      * moved contains the target of the move.
-     * @throws java.lang.IllegalArgumentException  If the operation is not allowed
-     * at the cursor's location.  This includes attempting to move an end token or the
-     * document as a whole.  Also, moving to a location before the start document or moving
-     * an attribute to a location other than after another attribute or start token
-     * will throw.
+     * @throws java.lang.IllegalArgumentException If the operation is not allowed
+     *                                            at the cursor's location.  This includes attempting to move an end token or the
+     *                                            document as a whole.  Also, moving to a location before the start document or moving
+     *                                            an attribute to a location other than after another attribute or start token
+     *                                            will throw.
      */
 
-    boolean moveXml ( XmlCursor toHere );
-    
+    boolean moveXml(XmlCursor toHere);
+
     /**
      * Copies the XML immediately after this cursor to the location
-     * specified by the <em>toHere</em> cursor. For the TEXT, ATTR, NAMESPACE, 
-     * COMMENT and PROCINST tokens, a single token is copied.  For a start token, 
+     * specified by the <em>toHere</em> cursor. For the TEXT, ATTR, NAMESPACE,
+     * COMMENT and PROCINST tokens, a single token is copied.  For a start token,
      * the element and all of its contents are copied. For all other tokens, this
      * is a no-op.
-     * 
-     * The cursors and bookmarks located in the XML that was copied are also copied 
+     * <p>
+     * The cursors and bookmarks located in the XML that was copied are also copied
      * to the new location.
-     * 
-     * @param  toHere  The cursor at the location to which the XML should
-     * be copied.
+     *
+     * @param toHere The cursor at the location to which the XML should
+     *               be copied.
      * @return true if anything was copied; false if the token supports the operation,
      * but nothing was copied.
-     * @throws java.lang.IllegalArgumentException  If the operation is not allowed
-     * at the cursor's location.
+     * @throws java.lang.IllegalArgumentException If the operation is not allowed
+     *                                            at the cursor's location.
      */
 
-    boolean copyXml ( XmlCursor toHere );
-    
+    boolean copyXml(XmlCursor toHere);
+
     /**
      * Removes the contents of the container (STARTDOC OR START) immediately after
      * this cursor. For all other situations, returns false. Does
      * not remove attributes or namspaces.
-     * 
+     *
      * @return true if anything was copied; otherwise, false.
      */
 
-    boolean removeXmlContents ( );
+    boolean removeXmlContents();
 
     /**
      * Moves the contents of the container (STARTDOC OR START) immediately after
      * this cursor to the location specified by the <em>toHere</em> cursor.
      * For all other situations, returns false. Does not move attributes or
      * namespaces.
-     * 
-     * @param  toHere  The cursor at the location to which the XML should be moved.
+     *
+     * @param toHere The cursor at the location to which the XML should be moved.
      * @return true if anything was moved; otherwise, false.
      */
-    boolean moveXmlContents ( XmlCursor toHere );
-    
+    boolean moveXmlContents(XmlCursor toHere);
+
     /**
      * Copies the contents of the container (STARTDOC OR START) immediately to
      * the right of the cursor to the location specified by the <em>toHere</em> cursor.
      * For all other situations, returns false.  Does not copy attributes or
      * namespaces.
-     * 
-     * @param  toHere  The cursor at the location to which the XML should
-     * be copied.
+     *
+     * @param toHere The cursor at the location to which the XML should
+     *               be copied.
      * @return true if anything was copied; otherwise, false.
      */
-    boolean copyXmlContents ( XmlCursor toHere );
-    
+    boolean copyXmlContents(XmlCursor toHere);
+
     /**
-     * Removes characters up to the specified maximum number, counting right from 
-     * this cursor's location to the character at <em>maxCharacterCount</em>. The 
+     * Removes characters up to the specified maximum number, counting right from
+     * this cursor's location to the character at <em>maxCharacterCount</em>. The
      * space remaining from removing the characters collapses up to this cursor.
-     * 
-     * @param  maxCharacterCount  The maximum number of characters after this cursor's 
-     * location to remove.
-     * @return  The actual number of characters removed.
-     * @throws java.lang.IllegalArgumentException  If the operation is not allowed
-     * at the cursor's location.
+     *
+     * @param maxCharacterCount The maximum number of characters after this cursor's
+     *                          location to remove.
+     * @return The actual number of characters removed.
+     * @throws java.lang.IllegalArgumentException If the operation is not allowed
+     *                                            at the cursor's location.
      */
 
-    int removeChars ( int maxCharacterCount );
+    int removeChars(int maxCharacterCount);
 
     /**
-     * Moves characters immediately after this cursor to the position immediately 
+     * Moves characters immediately after this cursor to the position immediately
      * after the specified cursor. Characters are counted to the right up to the
-     * specified maximum number. XML after the destination cursor is 
-     * shifted to the right to make room. The space remaining from moving the 
+     * specified maximum number. XML after the destination cursor is
+     * shifted to the right to make room. The space remaining from moving the
      * characters collapses up to this cursor.
-     * 
-     * @param  maxCharacterCount  The maximum number of characters after this cursor's 
-     * location to move.
-     * @param  toHere  The cursor to which the characters should be moved.
-     * @return  The actual number of characters moved.
-     * @throws java.lang.IllegalArgumentException  If the operation is not allowed
-     * at the cursor's location.
+     *
+     * @param maxCharacterCount The maximum number of characters after this cursor's
+     *                          location to move.
+     * @param toHere            The cursor to which the characters should be moved.
+     * @return The actual number of characters moved.
+     * @throws java.lang.IllegalArgumentException If the operation is not allowed
+     *                                            at the cursor's location.
      */
 
-    int moveChars ( int maxCharacterCount, XmlCursor toHere );
+    int moveChars(int maxCharacterCount, XmlCursor toHere);
 
     /**
      * Copies characters to the position immediately after the specified cursor.
-     * Characters are counted to the right up to the specified maximum number. 
+     * Characters are counted to the right up to the specified maximum number.
      * XML after the destination cursor is shifted to the right to make room.
-     * 
-     * @param  maxCharacterCount  The maximum number of characters after this cursor's 
-     * location to copy.
-     * @param  toHere  The cursor to which the characters should be copied.
-     * @return  The actual number of characters copied.
-     * @throws java.lang.IllegalArgumentException  If the operation is not allowed
-     * at the cursor's location.
+     *
+     * @param maxCharacterCount The maximum number of characters after this cursor's
+     *                          location to copy.
+     * @param toHere            The cursor to which the characters should be copied.
+     * @return The actual number of characters copied.
+     * @throws java.lang.IllegalArgumentException If the operation is not allowed
+     *                                            at the cursor's location.
      */
 
-    int copyChars ( int maxCharacterCount, XmlCursor toHere );
+    int copyChars(int maxCharacterCount, XmlCursor toHere);
 
     /**
      * Inserts the specified text immediately before this cursor's location.
-     * 
-     * @param  text  The text to insert.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param text The text to insert.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertChars ( String text );
-    
+    void insertChars(String text);
+
     /**
-     * Inserts an element immediately before this cursor's location, giving 
+     * Inserts an element immediately before this cursor's location, giving
      * the element the specified qualified name.
-     * 
-     * @param  name  The qualified name for the element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name The qualified name for the element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElement ( QName name );
+    void insertElement(QName name);
 
     /**
-     * Inserts an element immediately before this cursor's location, giving 
+     * Inserts an element immediately before this cursor's location, giving
      * the element the specified local name.
-     * 
-     * @param  localName  The local name for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElement ( String localName );
+    void insertElement(String localName);
 
     /**
      * Inserts a new element immediately before this cursor's location, giving the
-     * element the specified local name and associating it with specified namespace 
-     * 
-     * @param  localName  The local name for the new element.
-     * @param  uri  The URI for the new element's namespace.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     * element the specified local name and associating it with specified namespace
+     *
+     * @param localName The local name for the new element.
+     * @param uri       The URI for the new element's namespace.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElement ( String localName, String uri );
-    
+    void insertElement(String localName, String uri);
+
     /**
-     * Inserts a new element around this cursor, giving the element the specified 
-     * qualified name. After the element is inserted, this cursor is between its start 
-     * and end. This cursor can then be used to insert additional XML into 
+     * Inserts a new element around this cursor, giving the element the specified
+     * qualified name. After the element is inserted, this cursor is between its start
+     * and end. This cursor can then be used to insert additional XML into
      * the new element.
-     * 
-     * @param  name  The qualified name for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name The qualified name for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void beginElement ( QName name );
+    void beginElement(QName name);
 
     /**
-     * Inserts a new element around this cursor, giving the element the specified 
-     * local name. After the element is inserted, this cursor is between its start 
-     * and end. This cursor can then be used to insert additional XML into 
+     * Inserts a new element around this cursor, giving the element the specified
+     * local name. After the element is inserted, this cursor is between its start
+     * and end. This cursor can then be used to insert additional XML into
      * the new element.
-     * 
-     * @param  localName  The local name for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void beginElement ( String localName );
+    void beginElement(String localName);
 
     /**
-     * Inserts a new element around this cursor, giving the element the specified 
-     * local name and associating it with the specified namespace. After the element 
-     * is inserted, this cursor is between its start and end. This cursor 
+     * Inserts a new element around this cursor, giving the element the specified
+     * local name and associating it with the specified namespace. After the element
+     * is inserted, this cursor is between its start and end. This cursor
      * can then be used to insert additional XML into the new element.
-     * 
-     * @param  localName  The local name for the new element.
-     * @param  uri  The URI for the new element's namespace.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new element.
+     * @param uri       The URI for the new element's namespace.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void beginElement ( String localName, String uri );
-    
+    void beginElement(String localName, String uri);
+
     /**
      * Inserts a new element immediately before this cursor's location, giving the
      * element the specified qualified name and content.
-     * 
-     * @param  name  The qualified name for the new element.
-     * @param  text  The content for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name The qualified name for the new element.
+     * @param text The content for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElementWithText ( QName name, String text );
+    void insertElementWithText(QName name, String text);
 
     /**
      * Inserts a new element immediately before this cursor's location, giving the
      * element the specified local name and content.
-     * 
-     * @param  localName  The local name for the new element.
-     * @param  text  The content for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new element.
+     * @param text      The content for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElementWithText ( String localName, String text );
+    void insertElementWithText(String localName, String text);
 
     /**
      * Inserts a new element immediately before this cursor's location, giving the
-     * element the specified local name, associating it with the specified namespace, 
+     * element the specified local name, associating it with the specified namespace,
      * and giving it the specified content.
-     * 
-     * @param  localName  The local name for the new element.
-     * @param  uri  The URI for the new element's namespace.
-     * @param  text  The content for the new element.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new element.
+     * @param uri       The URI for the new element's namespace.
+     * @param text      The content for the new element.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertElementWithText ( String localName, String uri, String text );
-    
+    void insertElementWithText(String localName, String uri, String text);
+
     /**
      * Inserts a new attribute immediately before this cursor's location, giving it
      * the specified local name.
-     * 
-     * @param  localName  The local name for the new attribute.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new attribute.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttribute ( String localName );
+    void insertAttribute(String localName);
 
     /**
      * Inserts a new attribute immediately before this cursor's location, giving it
      * the specified local name and associating it with the specified namespace.
-     * 
-     * @param  localName  The local name for the new attribute.
-     * @param  uri  The URI for the new attribute's namespace.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param localName The local name for the new attribute.
+     * @param uri       The URI for the new attribute's namespace.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttribute ( String localName, String uri );
+    void insertAttribute(String localName, String uri);
 
     /**
      * Inserts a new attribute immediately before this cursor's location, giving it
      * the specified name.
-     * 
-     * @param  name  The local name for the new attribute.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name The local name for the new attribute.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttribute ( QName name );
+    void insertAttribute(QName name);
 
     /**
      * Inserts a new attribute immediately before this cursor's location, giving it
      * the specified value and name.
-     * 
-     * @param  Name  The local name for the new attribute.
-     * @param  value  The value for the new attribute.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param Name  The local name for the new attribute.
+     * @param value The value for the new attribute.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttributeWithValue ( String Name, String value );
+    void insertAttributeWithValue(String Name, String value);
 
     /**
      * Inserts an attribute immediately before the cursor's location, giving it
      * the specified name and value, and associating it with the specified namespace.
-     * 
-     * @param  name  The name for the new attribute.
-     * @param  uri  The URI for the new attribute's namespace.
-     * @param  value  The value for the new attribute.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name  The name for the new attribute.
+     * @param uri   The URI for the new attribute's namespace.
+     * @param value The value for the new attribute.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttributeWithValue ( String name, String uri, String value );
+    void insertAttributeWithValue(String name, String uri, String value);
 
     /**
      * Inserts an attribute immediately before the cursor's location, giving it
      * the specified name and value.
-     * 
-     * @param  name  The name for the new attribute.
-     * @param  value  The value for the new attribute.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param name  The name for the new attribute.
+     * @param value The value for the new attribute.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertAttributeWithValue ( QName name, String value );
-    
+    void insertAttributeWithValue(QName name, String value);
+
     /**
-     * Inserts a namespace declaration immediately before the cursor's location, 
+     * Inserts a namespace declaration immediately before the cursor's location,
      * giving it the specified prefix and URI.
-     * 
-     * @param  prefix  The prefix for the namespace.
-     * @param  namespace  The URI for the namespace.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param prefix    The prefix for the namespace.
+     * @param namespace The URI for the namespace.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertNamespace ( String prefix, String namespace );
-    
+    void insertNamespace(String prefix, String namespace);
+
     /**
-     * Inserts an XML comment immediately before the cursor's location, 
+     * Inserts an XML comment immediately before the cursor's location,
      * giving it the specified content.
-     * 
-     * @param  text  The new comment's content.
-     * @throws java.lang.IllegalArgumentException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param text The new comment's content.
+     * @throws java.lang.IllegalArgumentException If the insertion is not allowed
+     *                                            at the cursor's location.
      */
 
-    void insertComment ( String text );
+    void insertComment(String text);
 
     /**
-     * Inserts an XML processing instruction immediately before the cursor's location, 
+     * Inserts an XML processing instruction immediately before the cursor's location,
      * giving it the specified target and text.
-     * 
-     * @param  target  The target for the processing instruction.
-     * @param  text  The new processing instruction's text.
-     * @throws java.lang.IllegalStateException  If the insertion is not allowed
-     * at the cursor's location.
+     *
+     * @param target The target for the processing instruction.
+     * @param text   The new processing instruction's text.
+     * @throws java.lang.IllegalStateException If the insertion is not allowed
+     *                                         at the cursor's location.
      */
 
-    void insertProcInst ( String target, String text );
+    void insertProcInst(String target, String text);
 }
diff --git a/src/main/java/org/apache/xmlbeans/XmlOptions.java b/src/main/java/org/apache/xmlbeans/XmlOptions.java
index 7b57fc3..f45d529 100644
--- a/src/main/java/org/apache/xmlbeans/XmlOptions.java
+++ b/src/main/java/org/apache/xmlbeans/XmlOptions.java
@@ -18,13 +18,9 @@
 import org.xml.sax.EntityResolver;
 import org.xml.sax.XMLReader;
 
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
 import javax.xml.namespace.QName;
+import java.net.URI;
+import java.util.*;
 
 /**
  * Used to supply options for loading, saving, and compiling, and validating.
@@ -37,13 +33,13 @@
  * opts.setSavePrettyPrintIndent(4);
  * System.out.println(xobj.xmlText(opts));
  * </pre>
- * 
+ * <p>
  * The alternative is single-line usage:
  * <pre>
  * System.out.println(xobj.xmlText(
  *     new XmlOptions().setSavePrettyPrint().setSavePrettyPrintIndent(4)));
  * </pre>
- *
+ * <p>
  * Table showing where each option gets used.
  * Note that:
  * <ul>
@@ -83,117 +79,233 @@
  * </tr>
  * </table>
  */
-public class XmlOptions implements java.io.Serializable
-{
+public class XmlOptions implements java.io.Serializable {
+    //
+    // Complete set of XmlOption's
+    //
+
+    // TODO - Add selectPath option to track the seletion (deault is to clean selections fast).
+
+    public static final String SAVE_NAMESPACES_FIRST = "SAVE_NAMESPACES_FIRST";
+    public static final String SAVE_SYNTHETIC_DOCUMENT_ELEMENT = "SAVE_SYNTHETIC_DOCUMENT_ELEMENT";
+    public static final String SAVE_PRETTY_PRINT = "SAVE_PRETTY_PRINT";
+    public static final String SAVE_PRETTY_PRINT_INDENT = "SAVE_PRETTY_PRINT_INDENT";
+    public static final String SAVE_PRETTY_PRINT_OFFSET = "SAVE_PRETTY_PRINT_OFFSET";
+    public static final String SAVE_AGGRESSIVE_NAMESPACES = "SAVE_AGGRESSIVE_NAMESPACES";
+    public static final String SAVE_USE_DEFAULT_NAMESPACE = "SAVE_USE_DEFAULT_NAMESPACE";
+    public static final String SAVE_IMPLICIT_NAMESPACES = "SAVE_IMPLICIT_NAMESPACES";
+    public static final String SAVE_SUGGESTED_PREFIXES = "SAVE_SUGGESTED_PREFIXES";
+    public static final String SAVE_FILTER_PROCINST = "SAVE_FILTER_PROCINST";
+    public static final String SAVE_USE_OPEN_FRAGMENT = "SAVE_USE_OPEN_FRAGMENT";
+    public static final String SAVE_OUTER = "SAVE_OUTER";
+    public static final String SAVE_INNER = "SAVE_INNER";
+    public static final String SAVE_NO_XML_DECL = "SAVE_NO_XML_DECL";
+    public static final String SAVE_SUBSTITUTE_CHARACTERS = "SAVE_SUBSTITUTE_CHARACTERS";
+    public static final String SAVE_OPTIMIZE_FOR_SPEED = "SAVE_OPTIMIZE_FOR_SPEED";
+    public static final String SAVE_CDATA_LENGTH_THRESHOLD = "SAVE_CDATA_LENGTH_THRESHOLD";
+    public static final String SAVE_CDATA_ENTITY_COUNT_THRESHOLD = "SAVE_CDATA_ENTITY_COUNT_THRESHOLD";
+    public static final String SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES = "SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES";
+    public static final String LOAD_REPLACE_DOCUMENT_ELEMENT = "LOAD_REPLACE_DOCUMENT_ELEMENT";
+    public static final String LOAD_STRIP_WHITESPACE = "LOAD_STRIP_WHITESPACE";
+    public static final String LOAD_STRIP_COMMENTS = "LOAD_STRIP_COMMENTS";
+    public static final String LOAD_STRIP_PROCINSTS = "LOAD_STRIP_PROCINSTS";
+    public static final String LOAD_LINE_NUMBERS = "LOAD_LINE_NUMBERS";
+    public static final String LOAD_LINE_NUMBERS_END_ELEMENT = "LOAD_LINE_NUMBERS_END_ELEMENT";
+    public static final String LOAD_SAVE_CDATA_BOOKMARKS = "LOAD_SAVE_CDATA_BOOKMARKS";
+    public static final String LOAD_SUBSTITUTE_NAMESPACES = "LOAD_SUBSTITUTE_NAMESPACES";
+    public static final String LOAD_TRIM_TEXT_BUFFER = "LOAD_TRIM_TEXT_BUFFER";
+    public static final String LOAD_ADDITIONAL_NAMESPACES = "LOAD_ADDITIONAL_NAMESPACES";
+    public static final String LOAD_MESSAGE_DIGEST = "LOAD_MESSAGE_DIGEST";
+    public static final String LOAD_USE_DEFAULT_RESOLVER = "LOAD_USE_DEFAULT_RESOLVER";
+    public static final String LOAD_USE_XMLREADER = "LOAD_USE_XMLREADER";
+    public static final String XQUERY_CURRENT_NODE_VAR = "XQUERY_CURRENT_NODE_VAR";
+    public static final String XQUERY_VARIABLE_MAP = "XQUERY_VARIABLE_MAP";
+    public static final String CHARACTER_ENCODING = "CHARACTER_ENCODING";
+    public static final String ERROR_LISTENER = "ERROR_LISTENER";
+    public static final String DOCUMENT_TYPE = "DOCUMENT_TYPE";
+    public static final String DOCUMENT_SOURCE_NAME = "DOCUMENT_SOURCE_NAME";
+    public static final String COMPILE_SUBSTITUTE_NAMES = "COMPILE_SUBSTITUTE_NAMES";
+    public static final String COMPILE_NO_VALIDATION = "COMPILE_NO_VALIDATION";
+    public static final String COMPILE_NO_UPA_RULE = "COMPILE_NO_UPA_RULE";
+    public static final String COMPILE_NO_PVR_RULE = "COMPILE_NO_PVR_RULE";
+    public static final String COMPILE_NO_ANNOTATIONS = "COMPILE_NO_ANNOTATIONS";
+    public static final String COMPILE_DOWNLOAD_URLS = "COMPILE_DOWNLOAD_URLS";
+    public static final String COMPILE_MDEF_NAMESPACES = "COMPILE_MDEF_NAMESPACES";
+    public static final String VALIDATE_ON_SET = "VALIDATE_ON_SET";
+    public static final String VALIDATE_TREAT_LAX_AS_SKIP = "VALIDATE_TREAT_LAX_AS_SKIP";
+    public static final String VALIDATE_STRICT = "VALIDATE_STRICT";
+    public static final String VALIDATE_TEXT_ONLY = "VALIDATE_TEXT_ONLY";
+    public static final String UNSYNCHRONIZED = "UNSYNCHRONIZED";
+    public static final String ENTITY_RESOLVER = "ENTITY_RESOLVER";
+    public static final String BASE_URI = "BASE_URI";
+    public static final String SCHEMA_CODE_PRINTER = "SCHEMA_CODE_PRINTER";
+    public static final String GENERATE_JAVA_VERSION = "GENERATE_JAVA_VERSION";
+    public static final String COPY_USE_NEW_SYNC_DOMAIN = "COPY_USE_NEW_LOCALE";
+    public static final String LOAD_ENTITY_BYTES_LIMIT = "LOAD_ENTITY_BYTES_LIMIT";
+    public static final String ENTITY_EXPANSION_LIMIT = "ENTITY_EXPANSION_LIMIT";
+    public static final String LOAD_DTD_GRAMMAR = "LOAD_DTD_GRAMMAR";
+    public static final String LOAD_EXTERNAL_DTD = "LOAD_EXTERNAL_DTD";
+
+    public static final int DEFAULT_ENTITY_EXPANSION_LIMIT = 2048;
+    public static final String GENERATE_JAVA_14 = "1.4";
+    public static final String GENERATE_JAVA_15 = "1.5";
+
+    private static final XmlOptions EMPTY_OPTIONS;
+
+    static {
+        EMPTY_OPTIONS = new XmlOptions();
+        EMPTY_OPTIONS._map = Collections.unmodifiableMap(EMPTY_OPTIONS._map);
+    }
+
+
     private static final long serialVersionUID = 1L;
-    
-    private Map _map = new HashMap();
+
+    private Map<String, Object> _map = new HashMap<>();
 
 
     /**
      * Construct a new blank XmlOptions.
      */
-    public XmlOptions ( ) { }
+    public XmlOptions() {
+    }
 
     /**
      * Construct a new XmlOptions, copying the options.
      */
-    public XmlOptions (XmlOptions other) {
-        if (other != null) _map.putAll(other._map);
+    public XmlOptions(XmlOptions other) {
+        if (other != null) {
+            _map.putAll(other._map);
+        }
     }
-            
+
     //
     // Handy-dandy helper methods for setting some options
     //
 
     /**
      * This option will cause the saver to save namespace attributes first.
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveNamespacesFirst() { 
-        return set( SAVE_NAMESPACES_FIRST ); 
+    public XmlOptions setSaveNamespacesFirst() {
+        return setSaveNamespacesFirst(true);
     }
+
+    public XmlOptions setSaveNamespacesFirst(boolean b) {
+        return set(SAVE_NAMESPACES_FIRST, b);
+    }
+
+    public boolean isSaveNamespacesFirst() {
+        return hasOption(SAVE_NAMESPACES_FIRST);
+    }
+
+
     /**
      * This option will cause the saver to reformat white space for easier reading.
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSavePrettyPrint() { 
-        return set( SAVE_PRETTY_PRINT ); 
+    public XmlOptions setSavePrettyPrint() {
+        return setSavePrettyPrint(true);
     }
 
+    public XmlOptions setSavePrettyPrint(boolean b) {
+        return set(SAVE_PRETTY_PRINT, b);
+    }
+
+    public boolean isSavePrettyPrint() {
+        return hasOption(SAVE_PRETTY_PRINT);
+    }
+
+
     /**
      * When used with <code>setSavePrettyPrint</code> this sets the indent
      * amount to use.
-     * 
+     *
      * @param indent the indent amount to use
      * @see #setSavePrettyPrint
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSavePrettyPrintIndent(int indent) { 
-        return set( SAVE_PRETTY_PRINT_INDENT, indent ); 
+    public XmlOptions setSavePrettyPrintIndent(int indent) {
+        return set(SAVE_PRETTY_PRINT_INDENT, indent);
+    }
+
+    public Integer getSavePrettyPrintIndent() {
+        return (Integer) get(SAVE_PRETTY_PRINT_INDENT);
     }
 
     /**
      * When used with <code>setSavePrettyPrint</code> this sets the offset
      * amount to use.
-     * 
+     *
      * @param offset the offset amount to use
      * @see #setSavePrettyPrint
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSavePrettyPrintOffset(int offset) { 
-        return set( SAVE_PRETTY_PRINT_OFFSET, offset ); 
+    public XmlOptions setSavePrettyPrintOffset(int offset) {
+        return set(SAVE_PRETTY_PRINT_OFFSET, offset);
+    }
+
+    public Integer getSavePrettyPrintOffset() {
+        return (Integer) get(SAVE_PRETTY_PRINT_OFFSET);
     }
 
     /**
      * When writing a document, this sets the character
      * encoding to use.
-     * 
+     *
      * @param encoding the character encoding
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      */
-    public XmlOptions setCharacterEncoding(String encoding) { 
-        return set( CHARACTER_ENCODING, encoding ); 
+    public XmlOptions setCharacterEncoding(String encoding) {
+        return set(CHARACTER_ENCODING, encoding);
+    }
+
+    public String getCharacterEncoding() {
+        return (String) get(CHARACTER_ENCODING);
     }
 
     /**
      * When parsing a document, this sets the type of the root
      * element. If this is set, the parser will not try to guess
      * the type based on the document's <code>QName</code>.
-     * 
+     *
      * @param type The root element's document type.
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
     public XmlOptions setDocumentType(SchemaType type) {
-        return set( DOCUMENT_TYPE, type ); 
+        return set(DOCUMENT_TYPE, type);
     }
 
+    public SchemaType getDocumentType() {
+        return (SchemaType) get(DOCUMENT_TYPE);
+    }
+
+
     /**
-     * <p>Sets a collection object for collecting {@link XmlError} objects 
-     * during parsing, validation, and compilation. When set, the collection 
+     * <p>Sets a collection object for collecting {@link XmlError} objects
+     * during parsing, validation, and compilation. When set, the collection
      * will contain all the errors after the operation takes place.  Notice that
      * the errors will only have line numbers if the document was
      * loaded with line numbers enabled.</p>
-     * 
+     *
      * <p>The following simple example illustrates using an error listener
      * during validation.</p>
-     * 
+     *
      * <pre>
      * // Create an XmlOptions instance and set the error listener.
      * XmlOptions validateOptions = new XmlOptions();
      * ArrayList errorList = new ArrayList();
      * validateOptions.setErrorListener(errorList);
-     * 
+     *
      * // Validate the XML.
      * boolean isValid = newEmp.validate(validateOptions);
-     * 
+     *
      * // If the XML isn't valid, loop through the listener's contents,
      * // printing contained messages.
      * if (!isValid)
@@ -201,26 +313,30 @@
      *      for (int i = 0; i < errorList.size(); i++)
      *      {
      *          XmlError error = (XmlError)errorList.get(i);
-     *          
+     *
      *          System.out.println("\n");
      *          System.out.println("Message: " + error.getMessage() + "\n");
-     *          System.out.println("Location of invalid XML: " + 
+     *          System.out.println("Location of invalid XML: " +
      *              error.getCursorLocation().xmlText() + "\n");
      *      }
      * }
      * </pre>
-     * 
-     * @param c A collection that will be filled with {@link XmlError} objects 
-     * via {@link Collection#add}
-     * 
+     *
+     * @param c A collection that will be filled with {@link XmlError} objects
+     *          via {@link Collection#add}
      * @see XmlError
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      * @see XmlObject#validate(XmlOptions)
      * @see XmlBeans#compileXsd
      * @see XmlOptions#setLoadLineNumbers
      */
-    public XmlOptions setErrorListener (Collection c) { 
-        return set( ERROR_LISTENER, c ); 
+    public XmlOptions setErrorListener(Collection<XmlError> c) {
+        return set(ERROR_LISTENER, c);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<XmlError> getErrorListener() {
+        return (Collection<XmlError>) get(ERROR_LISTENER);
     }
 
     /**
@@ -234,142 +350,203 @@
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
     public XmlOptions setSaveAggressiveNamespaces() {
-        return set( SAVE_AGGRESSIVE_NAMESPACES ); 
+        return setSaveAggressiveNamespaces(true);
     }
 
-    /**
-     * @deprecated replaced by {@link #setSaveAggressiveNamespaces}
-     */
-    public XmlOptions setSaveAggresiveNamespaces() { 
-        return setSaveAggressiveNamespaces(); 
+    public XmlOptions setSaveAggressiveNamespaces(boolean b) {
+        return set(SAVE_AGGRESSIVE_NAMESPACES, b);
     }
 
+    public boolean isSaveAggressiveNamespaces() {
+        return hasOption(SAVE_AGGRESSIVE_NAMESPACES);
+    }
+
+
     /**
      * This option causes the saver to wrap the current fragment in
      * an element with the given name.
-     * 
+     *
      * @param name the name to use for the top level element
-     * 
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveSyntheticDocumentElement (QName name) { 
-        return set( SAVE_SYNTHETIC_DOCUMENT_ELEMENT, name ); 
+    public XmlOptions setSaveSyntheticDocumentElement(QName name) {
+        return set(SAVE_SYNTHETIC_DOCUMENT_ELEMENT, name);
     }
 
+    public QName getSaveSyntheticDocumentElement() {
+        return (QName) get(SAVE_SYNTHETIC_DOCUMENT_ELEMENT);
+    }
+
+
     /**
      * If this option is set, the saver will try to use the default
      * namespace for the most commonly used URI. If it is not set
      * the saver will always created named prefixes.
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setUseDefaultNamespace () { 
-        return set( SAVE_USE_DEFAULT_NAMESPACE ); 
+    public XmlOptions setUseDefaultNamespace() {
+        return setUseDefaultNamespace(true);
+    }
+
+    public XmlOptions setUseDefaultNamespace(boolean b) {
+        return set(SAVE_USE_DEFAULT_NAMESPACE, b);
+    }
+
+    public boolean isUseDefaultNamespace() {
+        return hasOption(SAVE_USE_DEFAULT_NAMESPACE);
     }
 
     /**
      * If namespaces have already been declared outside the scope of the
      * fragment being saved, this allows those mappings to be passed
      * down to the saver, so the prefixes are not re-declared.
-     * 
+     *
      * @param implicitNamespaces a map of prefixes to uris that can be
-     *  used by the saver without being declared
-     * 
+     *                           used by the saver without being declared
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
-     */ 
-    public XmlOptions setSaveImplicitNamespaces (Map implicitNamespaces) { 
-        return set( SAVE_IMPLICIT_NAMESPACES, implicitNamespaces ); 
+     */
+    public XmlOptions setSaveImplicitNamespaces(Map<String, String> implicitNamespaces) {
+        return set(SAVE_IMPLICIT_NAMESPACES, implicitNamespaces);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getSaveImplicitNamespaces() {
+        return (Map<String, String>) get(SAVE_IMPLICIT_NAMESPACES);
     }
 
     /**
      * A map of hints to pass to the saver for which prefixes to use
      * for which namespace URI.
-     * 
+     *
      * @param suggestedPrefixes a map from URIs to prefixes
-     * 
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveSuggestedPrefixes (Map suggestedPrefixes) { 
-        return set( SAVE_SUGGESTED_PREFIXES, suggestedPrefixes ); 
+    public XmlOptions setSaveSuggestedPrefixes(Map<String, String> suggestedPrefixes) {
+        return set(SAVE_SUGGESTED_PREFIXES, suggestedPrefixes);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getSaveSuggestedPrefixes() {
+        return (Map<String, String>) get(SAVE_SUGGESTED_PREFIXES);
     }
 
     /**
      * This option causes the saver to filter a Processing Instruction
      * with the given target
-     * 
+     *
      * @param filterProcinst the name of a Processing Instruction to filter
-     *   on save
-     * 
+     *                       on save
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveFilterProcinst (String filterProcinst) { 
-        return set( SAVE_FILTER_PROCINST, filterProcinst ); 
+    public XmlOptions setSaveFilterProcinst(String filterProcinst) {
+        return set(SAVE_FILTER_PROCINST, filterProcinst);
+    }
+
+    public String getSaveFilterProcinst() {
+        return (String) get(SAVE_FILTER_PROCINST);
     }
 
     /**
      * This option causes the saver to replace characters with other values in
      * the output stream.  It is intended to be used for escaping non-standard
      * characters during output.
-     * 
+     *
      * @param characterReplacementMap is an XmlOptionCharEscapeMap containing
-     * the characters to be escaped.
-     * 
+     *                                the characters to be escaped.
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      * @see XmlOptionCharEscapeMap
      */
-    public XmlOptions setSaveSubstituteCharacters (
+    public XmlOptions setSaveSubstituteCharacters(
         XmlOptionCharEscapeMap characterReplacementMap) {
-        return set( SAVE_SUBSTITUTE_CHARACTERS, characterReplacementMap );
+        return set(SAVE_SUBSTITUTE_CHARACTERS, characterReplacementMap);
+    }
+
+    public XmlOptionCharEscapeMap getSaveSubstituteCharacters() {
+        return (XmlOptionCharEscapeMap) get(SAVE_SUBSTITUTE_CHARACTERS);
     }
 
     /**
      * When saving a fragment, this option changes the qname of the synthesized
      * root element.  Normally &lt;xml-fragment&gt; is used.
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveUseOpenFrag () { 
-        return set( SAVE_USE_OPEN_FRAGMENT ); 
+    public XmlOptions setSaveUseOpenFrag() {
+        return setSaveUseOpenFrag(true);
+    }
+
+    public XmlOptions setSaveUseOpenFrag(boolean b) {
+        return set(SAVE_USE_OPEN_FRAGMENT, b);
+    }
+
+    public boolean isSaveUseOpenFrag() {
+        return hasOption(SAVE_USE_OPEN_FRAGMENT);
     }
 
     /**
      * This option controls whether saving begins on the element or its contents
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveOuter () { 
-        return set( SAVE_OUTER ); 
+    public XmlOptions setSaveOuter() {
+        return setSaveOuter(true);
+    }
+
+    public XmlOptions setSaveOuter(boolean b) {
+        return set(SAVE_OUTER, b);
+    }
+
+    public boolean isSaveOuter() {
+        return hasOption(SAVE_OUTER);
     }
 
     /**
      * This option controls whether saving begins on the element or its contents
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveInner () { 
-        return set( SAVE_INNER ); 
+    public XmlOptions setSaveInner() {
+        return setSaveInner(true);
+    }
+
+    public XmlOptions setSaveInner(boolean b) {
+        return set(SAVE_INNER, b);
+    }
+
+    public boolean isSaveInner() {
+        return hasOption(SAVE_INNER);
     }
 
     /**
      * This option controls whether saving saves out the XML
      * declaration (<?xml ... ?>
-     * 
+     *
      * @see XmlTokenSource#save(java.io.File, XmlOptions)
      * @see XmlTokenSource#xmlText(XmlOptions)
      */
-    public XmlOptions setSaveNoXmlDecl () { 
-        return set( SAVE_NO_XML_DECL ); 
+    public XmlOptions setSaveNoXmlDecl() {
+        return setSaveNoXmlDecl(true);
     }
 
+    public XmlOptions setSaveNoXmlDecl(boolean b) {
+        return set(SAVE_NO_XML_DECL, b);
+    }
+
+    public boolean isSaveNoXmlDecl() {
+        return hasOption(SAVE_NO_XML_DECL);
+    }
+
+
     /**
      * This option controls when saving will use CDATA blocks.
      * CDATA will be used if the folowing condition is true:
@@ -385,12 +562,18 @@
      * <tr><td>Only text that has y entitazable chars is CDATA</td> <td>0</td> <td>y</td></tr>
      * <tr><td>Only text longer than x chars and has y entitazable chars is CDATA</td> <td>x</td> <td>y</td></tr>
      * </table>
+     *
      * @see XmlOptions#setSaveCDataEntityCountThreshold(int)
      */
-    public XmlOptions setSaveCDataLengthThreshold (int cdataLengthThreshold) {
-        return set( SAVE_CDATA_LENGTH_THRESHOLD, cdataLengthThreshold );
+    public XmlOptions setSaveCDataLengthThreshold(int cdataLengthThreshold) {
+        return set(SAVE_CDATA_LENGTH_THRESHOLD, cdataLengthThreshold);
     }
 
+    public Integer getSaveCDataLengthThreshold() {
+        return (Integer) get(SAVE_CDATA_LENGTH_THRESHOLD);
+    }
+
+
     /**
      * This option controls when saving will use CDATA blocks.
      * CDATA will be used if the folowing condition is true:
@@ -399,8 +582,12 @@
      *
      * @see XmlOptions#setSaveCDataLengthThreshold(int)
      */
-    public XmlOptions setSaveCDataEntityCountThreshold (int cdataEntityCountThreshold) {
-        return set( SAVE_CDATA_ENTITY_COUNT_THRESHOLD, cdataEntityCountThreshold );
+    public XmlOptions setSaveCDataEntityCountThreshold(int cdataEntityCountThreshold) {
+        return set(SAVE_CDATA_ENTITY_COUNT_THRESHOLD, cdataEntityCountThreshold);
+    }
+
+    public Integer getSaveCDataEntityCountThreshold() {
+        return (Integer) get(SAVE_CDATA_ENTITY_COUNT_THRESHOLD);
     }
 
     /**
@@ -426,32 +613,35 @@
      *
      * <p>Sample code:
      * <pre>
-        String xmlText = "&lt;a>\n" +
-                "&lt;a>&lt;![CDATA[cdata text]]>&lt;/a>\n" +
-                "&lt;b>&lt;![CDATA[cdata text]]> regular text&lt;/b>\n" +
-                "&lt;c>text &lt;![CDATA[cdata text]]>&lt;/c>\n" +
-                "&lt;/a>";
-        System.out.println(xmlText);
-
-        XmlOptions opts = new XmlOptions();
-        opts.setUseCDataBookmarks();
-
-        XmlObject xo = XmlObject.Factory.parse( xmlText , opts);
-
-        System.out.println("xo1:\n" + xo.xmlText(opts));
-        System.out.println("\n");
-
-        opts.setSavePrettyPrint();
-        System.out.println("xo2:\n" + xo.xmlText(opts));
+     * String xmlText = "&lt;a>\n" +
+     * "&lt;a>&lt;![CDATA[cdata text]]>&lt;/a>\n" +
+     * "&lt;b>&lt;![CDATA[cdata text]]> regular text&lt;/b>\n" +
+     * "&lt;c>text &lt;![CDATA[cdata text]]>&lt;/c>\n" +
+     * "&lt;/a>";
+     * System.out.println(xmlText);
+     *
+     * XmlOptions opts = new XmlOptions();
+     * opts.setUseCDataBookmarks();
+     *
+     * XmlObject xo = XmlObject.Factory.parse( xmlText , opts);
+     *
+     * System.out.println("xo1:\n" + xo.xmlText(opts));
+     * System.out.println("\n");
+     *
+     * opts.setSavePrettyPrint();
+     * System.out.println("xo2:\n" + xo.xmlText(opts));
      * </pre>
      * </p>
      *
      * @see CDataBookmark
      * @see CDataBookmark#CDATA_BOOKMARK
      */
-    public XmlOptions setUseCDataBookmarks()
-    {
-        return set( LOAD_SAVE_CDATA_BOOKMARKS );        
+    public XmlOptions setUseCDataBookmarks() {
+        return set(LOAD_SAVE_CDATA_BOOKMARKS);
+    }
+
+    public boolean isUseCDataBookmarks() {
+        return hasOption(LOAD_SAVE_CDATA_BOOKMARKS);
     }
 
     /**
@@ -459,50 +649,87 @@
      * startElement event. By default, up to and including XMLBeans 2.3.0 they were included, in
      * subsequent versions, they are no longer included.
      */
-    public XmlOptions setSaveSaxNoNSDeclsInAttributes () {
-        return set( SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES );
+    public XmlOptions setSaveSaxNoNSDeclsInAttributes() {
+        return setSaveSaxNoNSDeclsInAttributes(true);
     }
 
+    public XmlOptions setSaveSaxNoNSDeclsInAttributes(boolean b) {
+        return set(SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES, b);
+    }
+
+    public boolean isSaveSaxNoNSDeclsInAttributes() {
+        return hasOption(SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES);
+    }
+
+
     /**
      * If this option is set, the document element is replaced with the
      * given QName when parsing.  If null is supplied, the document element
      * is removed.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadReplaceDocumentElement ( QName replacement ) { 
-        return set( LOAD_REPLACE_DOCUMENT_ELEMENT, replacement ); 
+    public XmlOptions setLoadReplaceDocumentElement(QName replacement) {
+        return set(LOAD_REPLACE_DOCUMENT_ELEMENT, replacement);
+    }
+
+    public QName getLoadReplaceDocumentElement() {
+        return (QName) get(LOAD_REPLACE_DOCUMENT_ELEMENT);
     }
 
     /**
      * If this option is set, all insignificant whitespace is stripped
      * when parsing a document.  Can be used to save memory on large
      * documents when you know there is no mixed content.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadStripWhitespace () { 
-        return set( LOAD_STRIP_WHITESPACE); 
+    public XmlOptions setLoadStripWhitespace() {
+        return setLoadStripWhitespace(true);
+    }
+
+    public XmlOptions setLoadStripWhitespace(boolean b) {
+        return set(LOAD_STRIP_WHITESPACE, b);
+    }
+
+    public boolean isSetLoadStripWhitespace() {
+        return hasOption(LOAD_STRIP_WHITESPACE);
     }
 
     /**
      * If this option is set, all comments are stripped when parsing
      * a document.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
     public XmlOptions setLoadStripComments() {
-        return set( LOAD_STRIP_COMMENTS ); 
+        return setLoadStripComments(true);
+    }
+
+    public XmlOptions setLoadStripComments(boolean b) {
+        return set(LOAD_STRIP_COMMENTS, b);
+    }
+
+    public boolean isLoadStripComments() {
+        return hasOption(LOAD_STRIP_COMMENTS);
     }
 
     /**
-     * If this option is set, all processing instructions 
+     * If this option is set, all processing instructions
      * are stripped when parsing a document.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadStripProcinsts () { 
-        return set( LOAD_STRIP_PROCINSTS ); 
+    public XmlOptions setLoadStripProcinsts() {
+        return setLoadStripProcinsts(true);
+    }
+
+    public XmlOptions setLoadStripProcinsts(boolean b) {
+        return set(LOAD_STRIP_PROCINSTS, b);
+    }
+
+    public boolean isLoadStripProcinsts() {
+        return hasOption(LOAD_STRIP_PROCINSTS);
     }
 
     /**
@@ -512,30 +739,41 @@
      * line numbers.
      * <br/>Note: This adds line numbers info only for start tags.
      * For line number info on end tags use:
-     *   {@link XmlOptions#setLoadLineNumbers(java.lang.String)}
-     * <br/>Example: xmlOptions.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT)
-     * 
-     * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
-     * @see XmlError
-     */
-    public XmlOptions setLoadLineNumbers () { 
-        return set( LOAD_LINE_NUMBERS ); 
-    }
-
-     /**
-     * If this option is set, line number annotations are placed
-     * in the store when parsing a document.  This is particularly
-     * useful when you want {@link XmlError} objects to contain
-     * line numbers. Use the option to load line numbers at the end of an element.
-     * <br/>Example: xmlOptions.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT)
+     * {@link XmlOptions#setLoadLineNumbersEndElement()}
      *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      * @see XmlError
      */
-    public XmlOptions setLoadLineNumbers (String option) {
-        XmlOptions temp = setLoadLineNumbers();
-        temp = temp.set( option );
-        return temp;
+    public XmlOptions setLoadLineNumbers() {
+        return setLoadLineNumbers(true);
+    }
+
+    public XmlOptions setLoadLineNumbers(boolean b) {
+        return set(LOAD_LINE_NUMBERS, b);
+    }
+
+    public boolean isLoadLineNumbers() {
+        return hasOption(LOAD_LINE_NUMBERS);
+    }
+
+
+    /**
+     * If this option is set, line number annotations are placed
+     * in the store when parsing a document.  This is particularly
+     * useful when you want {@link XmlError} objects to contain
+     * line numbers. Use the option to load line numbers at the end of an element.
+     */
+    public XmlOptions setLoadLineNumbersEndElement() {
+        return setLoadLineNumbersEndElement(true);
+    }
+
+    public XmlOptions setLoadLineNumbersEndElement(boolean b) {
+        setLoadLineNumbers(true);
+        return set(LOAD_LINE_NUMBERS_END_ELEMENT, b);
+    }
+
+    public boolean isLoadLineNumbersEndElement() {
+        return hasOption(LOAD_LINE_NUMBERS_END_ELEMENT);
     }
 
     /**
@@ -553,13 +791,17 @@
      * to type the instance according to a schema in a nonempty namespace,
      * and therefore avoid the problematic practice of using schema
      * definitions without a target namespace.
-     * 
+     *
      * @param substNamespaces a map of document URIs to replacement URIs
-     * 
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadSubstituteNamespaces (Map substNamespaces) { 
-        return set( LOAD_SUBSTITUTE_NAMESPACES, substNamespaces ); 
+    public XmlOptions setLoadSubstituteNamespaces(Map<String, String> substNamespaces) {
+        return set(LOAD_SUBSTITUTE_NAMESPACES, substNamespaces);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getLoadSubstituteNamespaces() {
+        return (Map<String, String>) get(LOAD_SUBSTITUTE_NAMESPACES);
     }
 
     /**
@@ -567,23 +809,35 @@
      * immediately after parsing a document resulting in a smaller memory
      * footprint.  Use this option if you are loading a large number
      * of unchanging documents that will stay in memory for some time.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadTrimTextBuffer () { 
-        return set( LOAD_TRIM_TEXT_BUFFER ); 
+    public XmlOptions setLoadTrimTextBuffer() {
+        return setLoadTrimTextBuffer(true);
+    }
+
+    public XmlOptions setLoadTrimTextBuffer(boolean b) {
+        return set(LOAD_TRIM_TEXT_BUFFER, b);
+    }
+
+    public boolean isLoadTrimTextBuffer() {
+        return hasOption(LOAD_TRIM_TEXT_BUFFER);
     }
 
     /**
      * Set additional namespace mappings to be added when parsing
      * a document.
-     * 
+     *
      * @param nses additional namespace mappings
-     * 
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadAdditionalNamespaces (Map nses) { 
-        return set( LOAD_ADDITIONAL_NAMESPACES, nses ); 
+    public XmlOptions setLoadAdditionalNamespaces(Map<String, String> nses) {
+        return set(LOAD_ADDITIONAL_NAMESPACES, nses);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getLoadAdditionalNamespaces() {
+        return (Map<String, String>) get(LOAD_ADDITIONAL_NAMESPACES);
     }
 
     /**
@@ -594,24 +848,41 @@
      * <br>
      * The schema compiler uses message digests to detect and eliminate
      * duplicate imported xsd files.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadMessageDigest () { 
-        return set( LOAD_MESSAGE_DIGEST ); 
+    public XmlOptions setLoadMessageDigest() {
+        return setLoadMessageDigest(true);
+    }
+
+    public XmlOptions setLoadMessageDigest(boolean b) {
+        return set(LOAD_MESSAGE_DIGEST, b);
+    }
+
+    public boolean isLoadMessageDigest() {
+        return hasOption(LOAD_MESSAGE_DIGEST);
     }
 
     /**
      * By default, XmlBeans does not resolve entities when parsing xml
      * documents (unless an explicit entity resolver is specified).
      * Use this option to turn on entity resolving by default.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadUseDefaultResolver () { 
-        return set( LOAD_USE_DEFAULT_RESOLVER ); 
+    public XmlOptions setLoadUseDefaultResolver() {
+        return setLoadUseDefaultResolver(true);
     }
 
+    public XmlOptions setLoadUseDefaultResolver(boolean b) {
+        return set(LOAD_USE_DEFAULT_RESOLVER, b);
+    }
+
+    public boolean isLoadUseDefaultResolver() {
+        return hasOption(LOAD_USE_DEFAULT_RESOLVER);
+    }
+
+
     /**
      * By default, XmlBeans creates a JAXP parser,
      * other parsers can be used by providing an XMLReader.
@@ -620,21 +891,28 @@
      *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
-    public XmlOptions setLoadUseXMLReader (XMLReader xmlReader) {
-        return set( LOAD_USE_XMLREADER, xmlReader );
+    public XmlOptions setLoadUseXMLReader(XMLReader xmlReader) {
+        return set(LOAD_USE_XMLREADER, xmlReader);
+    }
+
+    public XMLReader getLoadUseXMLReader() {
+        return (XMLReader) get(LOAD_USE_XMLREADER);
     }
 
     /**
      * Sets the name of the variable that represents
      * the current node in a query expression.
-     * 
+     *
      * @param varName The new variable name to use for the query.
-     * 
      * @see XmlObject#execQuery
      * @see XmlCursor#execQuery
      */
-    public XmlOptions setXqueryCurrentNodeVar (String varName) { 
-        return set( XQUERY_CURRENT_NODE_VAR, varName ); 
+    public XmlOptions setXqueryCurrentNodeVar(String varName) {
+        return set(XQUERY_CURRENT_NODE_VAR, varName);
+    }
+
+    public String getXqueryCurrentNodeVar() {
+        return (String) get(XQUERY_CURRENT_NODE_VAR);
     }
 
     /**
@@ -646,12 +924,16 @@
      * xquery and has no effect on xpath expressions.
      *
      * @param varMap a map from Strings to variable instances.
-     *
      * @see XmlObject#execQuery
      * @see XmlCursor#execQuery
      */
-    public XmlOptions setXqueryVariables (Map varMap) {
-        return set( XQUERY_VARIABLE_MAP, varMap );
+    public XmlOptions setXqueryVariables(Map<String, Object> varMap) {
+        return set(XQUERY_VARIABLE_MAP, varMap);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map<String, Object> getXqueryVariables() {
+        return (Map<String, Object>) get(XQUERY_VARIABLE_MAP);
     }
 
     /**
@@ -659,33 +941,45 @@
      * when parsing a document.  If a document is parsed from a
      * File or URI, it is automatically set to the URI of the
      * source; otherwise, for example, when parsing a String,
-     * you can use this option to specify the source name yourself. 
-     * 
+     * you can use this option to specify the source name yourself.
+     *
      * @see XmlObject.Factory#parse(java.lang.String, XmlOptions)
      */
-    public XmlOptions setDocumentSourceName (String documentSourceName) { 
-        return set( DOCUMENT_SOURCE_NAME, documentSourceName ); 
+    public XmlOptions setDocumentSourceName(String documentSourceName) {
+        return set(DOCUMENT_SOURCE_NAME, documentSourceName);
+    }
+
+    public String getDocumentSourceName() {
+        return (String) get(DOCUMENT_SOURCE_NAME);
     }
 
     /**
      * This option allows for <code>QName</code> substitution during schema compilation.
-     * 
+     *
      * @param nameMap a map from <code>QName</code>s to substitute <code>QName</code>s.
-     * 
      * @see XmlBeans#compileXsd
      */
-    public XmlOptions setCompileSubstituteNames (Map nameMap) { 
-        return set( COMPILE_SUBSTITUTE_NAMES, nameMap ); 
+    public XmlOptions setCompileSubstituteNames(Map<QName, QName> nameMap) {
+        return set(COMPILE_SUBSTITUTE_NAMES, nameMap);
     }
-    
+
+    @SuppressWarnings("unchecked")
+    public Map<QName, QName> getCompileSubstituteNames() {
+        return (Map<QName, QName>) get(COMPILE_SUBSTITUTE_NAMES);
+    }
+
     /**
      * If this option is set, validation is not done on the Schema XmlBeans
      * when building a <code>SchemaTypeSystem</code>
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
-    public XmlOptions setCompileNoValidation () { 
-        return set( COMPILE_NO_VALIDATION ); 
+    public XmlOptions setCompileNoValidation() {
+        return set(COMPILE_NO_VALIDATION);
+    }
+
+    public boolean isCompileNoValidation() {
+        return hasOption(COMPILE_NO_VALIDATION);
     }
 
     /**
@@ -693,59 +987,94 @@
      * enforced when building a <code>SchemaTypeSystem</code>. See
      * <a target="_blank" href="http://www.w3.org/TR/xmlschema-1/#non-ambig">Appendix H of the XML Schema specification</a>
      * for information on the UPA rule.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
-    public XmlOptions setCompileNoUpaRule () { 
-        return set( COMPILE_NO_UPA_RULE ); 
+    public XmlOptions setCompileNoUpaRule() {
+        return setCompileNoUpaRule(true);
     }
-    
+
+    public XmlOptions setCompileNoUpaRule(boolean b) {
+        return set(COMPILE_NO_UPA_RULE, b);
+    }
+
+    public boolean isCompileNoUpaRule() {
+        return hasOption(COMPILE_NO_UPA_RULE);
+    }
+
     /**
      * If this option is set, the particle valid (restriciton) rule is not
      * enforced when building a <code>SchemaTypeSystem</code>. See
      * <a target="_blank" href="http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict">Section 3.9.6 of the XML Schema specification</a>
      * for information on the PVR rule.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
-    public XmlOptions setCompileNoPvrRule () { 
-        return set( COMPILE_NO_PVR_RULE ); 
+    public XmlOptions setCompileNoPvrRule() {
+        return setCompileNoPvrRule(true);
+    }
+
+    public XmlOptions setCompileNoPvrRule(boolean b) {
+        return set(COMPILE_NO_PVR_RULE, b);
+    }
+
+    public boolean isCompileNoPvrRule() {
+        return hasOption(COMPILE_NO_PVR_RULE);
     }
 
     /**
      * if this option is set, the schema compiler will skip annotations when
      * processing Schema components.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
     public XmlOptions setCompileNoAnnotations() {
-        return set( COMPILE_NO_ANNOTATIONS );
+        return setCompileNoAnnotations(true);
+    }
+
+    public XmlOptions setCompileNoAnnotations(boolean b) {
+        return set(COMPILE_NO_ANNOTATIONS, b);
+    }
+
+    public boolean isCompileNoAnnotations() {
+        return hasOption(COMPILE_NO_ANNOTATIONS);
     }
 
     /**
      * If this option is set, then the schema compiler will try to download
      * schemas that appear in imports and includes from network based URLs.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
-    public XmlOptions setCompileDownloadUrls () { 
-        return set( COMPILE_DOWNLOAD_URLS); 
+    public XmlOptions setCompileDownloadUrls() {
+        return setCompileDownloadUrls(true);
     }
-    
+
+    public XmlOptions setCompileDownloadUrls(boolean b) {
+        return set(COMPILE_DOWNLOAD_URLS, b);
+    }
+
+    public boolean isCompileDownloadUrls() {
+        return hasOption(COMPILE_DOWNLOAD_URLS);
+    }
+
     /**
      * If this option is set, then the schema compiler will permit and
      * ignore multiple definitions of the same component (element, attribute,
      * type, etc) names in the given namespaces.  If multiple definitions
      * with the same name appear, the definitions that happen to be processed
      * last will be ignored.
-     * 
+     *
      * @param mdefNamespaces a set of namespace URIs as Strings
-     * 
      * @see XmlBeans#compileXsd
-     */ 
-    public XmlOptions setCompileMdefNamespaces(Set mdefNamespaces)
-    {
-        return set( COMPILE_MDEF_NAMESPACES, mdefNamespaces );
+     */
+    public XmlOptions setCompileMdefNamespaces(Set<String> mdefNamespaces) {
+        return set(COMPILE_MDEF_NAMESPACES, mdefNamespaces);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Set<String> getCompileMdefNamespaces() {
+        return (Set<String>) get(COMPILE_MDEF_NAMESPACES);
     }
 
     /**
@@ -756,11 +1085,19 @@
      * thrown immediately.  This option is useful for finding code that
      * is introducing invalid values in an XML document, but it
      * slows performance.
-     * 
+     *
      * @see XmlObject.Factory#parse(java.io.File, XmlOptions)
      */
     public XmlOptions setValidateOnSet() {
-        return set( VALIDATE_ON_SET );
+        return setValidateOnSet(true);
+    }
+
+    public XmlOptions setValidateOnSet(boolean b) {
+        return set(VALIDATE_ON_SET, b);
+    }
+
+    public boolean isValidateOnSet() {
+        return hasOption(VALIDATE_ON_SET);
     }
 
     /**
@@ -770,7 +1107,15 @@
      * classpath that the document author did not anticipate.
      */
     public XmlOptions setValidateTreatLaxAsSkip() {
-        return set ( VALIDATE_TREAT_LAX_AS_SKIP );
+        return setValidateTreatLaxAsSkip(true);
+    }
+
+    public XmlOptions setValidateTreatLaxAsSkip(boolean b) {
+        return set(VALIDATE_TREAT_LAX_AS_SKIP, b);
+    }
+
+    public boolean isValidateTreatLaxAsSkip() {
+        return hasOption(VALIDATE_TREAT_LAX_AS_SKIP);
     }
 
     /**
@@ -778,9 +1123,30 @@
      * default for better compatibility.
      */
     public XmlOptions setValidateStrict() {
-        return set ( VALIDATE_STRICT );
+        return setValidateStrict(true);
     }
 
+    public XmlOptions setValidateStrict(boolean b) {
+        return set(VALIDATE_STRICT, b);
+    }
+
+    public boolean isValidateStrict() {
+        return hasOption(VALIDATE_STRICT);
+    }
+
+    public XmlOptions setValidateTextOnly() {
+        return setValidateTextOnly(true);
+    }
+
+    public XmlOptions setValidateTextOnly(boolean b) {
+        return set(VALIDATE_TEXT_ONLY, b);
+    }
+
+    public boolean isValidateTextOnly() {
+        return hasOption(VALIDATE_TEXT_ONLY);
+    }
+
+
     /**
      * This option controls whether or not operations on XmlBeans are
      * thread safe.  When not on, all XmlBean operations will be syncronized.
@@ -788,46 +1154,66 @@
      * XmlBeans simultainously, but has a perf impact.  If set, then
      * only one thread may access an XmlBean.
      */
-    public XmlOptions setUnsynchronized ( )
-    {
-        return set( UNSYNCHRONIZED );
+    public XmlOptions setUnsynchronized() {
+        return setUnsynchronized(true);
+    }
+
+    public XmlOptions setUnsynchronized(boolean b) {
+        return set(UNSYNCHRONIZED, b);
+    }
+
+    public boolean isUnsynchronized() {
+        return hasOption(UNSYNCHRONIZED);
     }
 
     /**
      * If this option is set when compiling a schema, then the given
      * EntityResolver will be consulted in order to resolve any
      * URIs while downloading imported schemas.
-     *
+     * <p>
      * EntityResolvers are currently only used by compileXsd; they
      * are not consulted by other functions, for example, parse.
      * This will likely change in the future.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
     public XmlOptions setEntityResolver(EntityResolver resolver) {
-        return set( ENTITY_RESOLVER, resolver );
+        return set(ENTITY_RESOLVER, resolver);
+    }
+
+    public EntityResolver getEntityResolver() {
+        return (EntityResolver) get(ENTITY_RESOLVER);
     }
 
     /**
      * If this option is set when compiling a schema, then the given
      * URI will be considered as base URI when deciding the directory
      * structure for saving the sources inside the generated JAR file.
+     *
      * @param baseURI the URI to be considered as "base"
      * @see XmlBeans#compileXsd
      */
     public XmlOptions setBaseURI(URI baseURI) {
-        return set( BASE_URI, baseURI );
+        return set(BASE_URI, baseURI);
+    }
+
+    public URI getBaseURI() {
+        return (URI) get(BASE_URI);
     }
 
     /**
      * If this option is set when compiling a schema, then the given
      * SchemaTypeCodePrinter.Printer will be used to generate the
      * Java code.
-     * 
+     *
      * @see XmlBeans#compileXsd
      */
     public XmlOptions setSchemaCodePrinter(SchemaCodePrinter printer) {
-        return set( SCHEMA_CODE_PRINTER, printer );
+        return set(SCHEMA_CODE_PRINTER, printer);
+    }
+
+    public SchemaCodePrinter getSchemaCodePrinter() {
+        return (SchemaCodePrinter) get(SCHEMA_CODE_PRINTER);
     }
 
     /**
@@ -837,13 +1223,16 @@
      * supported.
      *
      * @param source A Java version number
-     *
      * @see #GENERATE_JAVA_14
      * @see #GENERATE_JAVA_15
      * @see XmlBeans#compileXmlBeans
      */
-    public XmlOptions setGenerateJavaVersion (String source) {
-        return set( GENERATE_JAVA_VERSION, source );
+    public XmlOptions setGenerateJavaVersion(String source) {
+        return set(GENERATE_JAVA_VERSION, source);
+    }
+
+    public String getGenerateJavaVersion() {
+        return (String) get(GENERATE_JAVA_VERSION);
     }
 
     /**
@@ -852,227 +1241,169 @@
      * will share the same synchronization domain, requiring explicit synchronization
      * when concurent accessing the two objects.
      *
-     * @param useNewSyncDomain  A flag representing the usage of new domain
-     *
+     * @param useNewSyncDomain A flag representing the usage of new domain
      * @see XmlObject#copy()
      */
-    public XmlOptions setCopyUseNewSynchronizationDomain (boolean useNewSyncDomain)
-    {
+    public XmlOptions setCopyUseNewSynchronizationDomain(boolean useNewSyncDomain) {
         return set(COPY_USE_NEW_SYNC_DOMAIN, useNewSyncDomain);
     }
 
+    public boolean isCopyUseNewSynchronizationDomain() {
+        Boolean flag = (Boolean)get(COPY_USE_NEW_SYNC_DOMAIN);
+        return flag != null && flag;
+    }
+
     /**
      * Sets the maximum number of bytes allowed when an Entity is expanded during parsing.
      * The default value is 10240 bytes.
-     * @param entityBytesLimit
-     * @return
+     *
+     * @param entityBytesLimit the maximum number of bytes allowed when an Entity is expanded during parsing
+     * @return this
      */
-    public XmlOptions setLoadEntityBytesLimit (int entityBytesLimit)
-    {
-        return set(LOAD_ENTITY_BYTES_LIMIT,entityBytesLimit);
+    public XmlOptions setLoadEntityBytesLimit(int entityBytesLimit) {
+        return set(LOAD_ENTITY_BYTES_LIMIT, entityBytesLimit);
     }
 
+    public Integer getLoadEntityBytesLimit() {
+        return (Integer) get(LOAD_ENTITY_BYTES_LIMIT);
+    }
+
+
     /**
      * Sets the maximum number of entity expansions allowed during parsing.
      * The default value is 2048.
-     * @param entityExpansionLimit
+     *
+     * @param entityExpansionLimit the maximum number of entity expansions allowed during parsing
      * @return this
      */
-    public XmlOptions setEntityExpansionLimit (int entityExpansionLimit)
-    {
+    public XmlOptions setEntityExpansionLimit(int entityExpansionLimit) {
         return set(ENTITY_EXPANSION_LIMIT, entityExpansionLimit);
     }
 
+    public int getEntityExpansionLimit() {
+        Integer limit = (Integer) get(ENTITY_EXPANSION_LIMIT);
+        return limit == null ? DEFAULT_ENTITY_EXPANSION_LIMIT : limit;
+    }
+
     /**
      * Controls whether DTD grammar is loaded during parsing.
      * The default value is false.
      *
-     * @param loadDTDGrammar
+     * @param loadDTDGrammar {@code true}, if DTD grammar is loaded during parsing
      * @return this
      */
-    public XmlOptions setLoadDTDGrammar (boolean loadDTDGrammar)
-    {
+    public XmlOptions setLoadDTDGrammar(boolean loadDTDGrammar) {
         return set(LOAD_DTD_GRAMMAR, loadDTDGrammar);
     }
 
+    public boolean isLoadDTDGrammar() {
+        Boolean flag = (Boolean) get(LOAD_DTD_GRAMMAR);
+        return flag != null && flag;
+    }
+
     /**
      * Controls whether external DTDs are loaded during parsing.
      * The default value is false.
      *
-     * @param loadExternalDTD
+     * @param loadExternalDTD {@code true}, if external DTDs are loaded during parsing
      * @return this
      */
-    public XmlOptions setLoadExternalDTD (boolean loadExternalDTD)
-    {
+    public XmlOptions setLoadExternalDTD(boolean loadExternalDTD) {
         return set(LOAD_EXTERNAL_DTD, loadExternalDTD);
     }
 
-    public static final String GENERATE_JAVA_14 = "1.4";
-    public static final String GENERATE_JAVA_15 = "1.5";
-
-
-    //
-    // Complete set of XmlOption's
-    //
-            
-    // TODO - Add selectPath option to track the seletion (deault is to clean selections fast). 
-    
-    /** @exclude */
-    public static final String SAVE_NAMESPACES_FIRST           = "SAVE_NAMESPACES_FIRST";
-    /** @exclude */
-    public static final String SAVE_SYNTHETIC_DOCUMENT_ELEMENT = "SAVE_SYNTHETIC_DOCUMENT_ELEMENT";
-    /** @exclude */
-    public static final String SAVE_PRETTY_PRINT               = "SAVE_PRETTY_PRINT";
-    /** @exclude */
-    public static final String SAVE_PRETTY_PRINT_INDENT        = "SAVE_PRETTY_PRINT_INDENT";
-    /** @exclude */
-    public static final String SAVE_PRETTY_PRINT_OFFSET        = "SAVE_PRETTY_PRINT_OFFSET";
-    /** @exclude */
-    public static final String SAVE_AGGRESSIVE_NAMESPACES      = "SAVE_AGGRESSIVE_NAMESPACES";
-    /** @exclude */
-    public static final String SAVE_USE_DEFAULT_NAMESPACE      = "SAVE_USE_DEFAULT_NAMESPACE";
-    /** @exclude */
-    public static final String SAVE_IMPLICIT_NAMESPACES        = "SAVE_IMPLICIT_NAMESPACES";
-    /** @exclude */
-    public static final String SAVE_SUGGESTED_PREFIXES         = "SAVE_SUGGESTED_PREFIXES";
-    /** @exclude */
-    public static final String SAVE_FILTER_PROCINST            = "SAVE_FILTER_PROCINST";
-    /** @exclude */
-    public static final String SAVE_USE_OPEN_FRAGMENT          = "SAVE_USE_OPEN_FRAGMENT";
-    /** @exclude */
-    public static final String SAVE_OUTER                      = "SAVE_OUTER";
-    /** @exclude */
-    public static final String SAVE_INNER                      = "SAVE_INNER";
-    /** @exclude */
-    public static final String SAVE_NO_XML_DECL                = "SAVE_NO_XML_DECL";
-    /** @exclude */
-    public static final String SAVE_SUBSTITUTE_CHARACTERS      = "SAVE_SUBSTITUTE_CHARACTERS";
-    /** @exclude */
-    public static final String SAVE_OPTIMIZE_FOR_SPEED         = "SAVE_OPTIMIZE_FOR_SPEED";
-    /** @exclude */
-    public static final String SAVE_CDATA_LENGTH_THRESHOLD     = "SAVE_CDATA_LENGTH_THRESHOLD";
-    /** @exclude */
-    public static final String SAVE_CDATA_ENTITY_COUNT_THRESHOLD = "SAVE_CDATA_ENTITY_COUNT_THRESHOLD";
-    /** @exclude */
-    public static final String SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES = "SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES";
-    /** @exclude */
-    public static final String LOAD_REPLACE_DOCUMENT_ELEMENT   = "LOAD_REPLACE_DOCUMENT_ELEMENT";
-    /** @exclude */
-    public static final String LOAD_STRIP_WHITESPACE           = "LOAD_STRIP_WHITESPACE";
-    /** @exclude */
-    public static final String LOAD_STRIP_COMMENTS             = "LOAD_STRIP_COMMENTS";
-    /** @exclude */
-    public static final String LOAD_STRIP_PROCINSTS            = "LOAD_STRIP_PROCINSTS";
-    /** @exclude */
-    public static final String LOAD_LINE_NUMBERS               = "LOAD_LINE_NUMBERS";
-    /** @exclude */
-    public static final String LOAD_LINE_NUMBERS_END_ELEMENT   = "LOAD_LINE_NUMBERS_END_ELEMENT";
-    /** @exclude */
-    public static final String LOAD_SAVE_CDATA_BOOKMARKS       = "LOAD_SAVE_CDATA_BOOKMARKS";
-    /** @exclude */
-    public static final String LOAD_SUBSTITUTE_NAMESPACES      = "LOAD_SUBSTITUTE_NAMESPACES";
-    /** @exclude */
-    public static final String LOAD_TRIM_TEXT_BUFFER           = "LOAD_TRIM_TEXT_BUFFER";
-    /** @exclude */
-    public static final String LOAD_ADDITIONAL_NAMESPACES      = "LOAD_ADDITIONAL_NAMESPACES";
-    /** @exclude */
-    public static final String LOAD_MESSAGE_DIGEST             = "LOAD_MESSAGE_DIGEST";
-    /** @exclude */
-    public static final String LOAD_USE_DEFAULT_RESOLVER       = "LOAD_USE_DEFAULT_RESOLVER";
-    /** @exclude */
-    public static final String LOAD_USE_XMLREADER              = "LOAD_USE_XMLREADER";
-
-    /** @exclude */
-    public static final String XQUERY_CURRENT_NODE_VAR         = "XQUERY_CURRENT_NODE_VAR";
-    /** @exclude */
-    public static final String XQUERY_VARIABLE_MAP             =  "XQUERY_VARIABLE_MAP";
-
-    /** @exclude */
-    public static final String CHARACTER_ENCODING              = "CHARACTER_ENCODING";
-    /** @exclude */
-    public static final String ERROR_LISTENER                  = "ERROR_LISTENER";
-    /** @exclude */
-    public static final String DOCUMENT_TYPE                   = "DOCUMENT_TYPE";
-    /** @exclude */
-    public static final String DOCUMENT_SOURCE_NAME            = "DOCUMENT_SOURCE_NAME";
-    /** @exclude */
-    public static final String COMPILE_SUBSTITUTE_NAMES        = "COMPILE_SUBSTITUTE_NAMES";
-    /** @exclude */
-    public static final String COMPILE_NO_VALIDATION           = "COMPILE_NO_VALIDATION";
-    /** @exclude */
-    public static final String COMPILE_NO_UPA_RULE             = "COMPILE_NO_UPA_RULE";
-    /** @exclude */
-    public static final String COMPILE_NO_PVR_RULE             = "COMPILE_NO_PVR_RULE";
-    /** @exclude */
-    public static final String COMPILE_NO_ANNOTATIONS          = "COMPILE_NO_ANNOTATIONS";
-    /** @exclude */
-    public static final String COMPILE_DOWNLOAD_URLS           = "COMPILE_DOWNLOAD_URLS";
-    /** @exclude */
-    public static final String COMPILE_MDEF_NAMESPACES         = "COMPILE_MDEF_NAMESPACES";
-    /** @exclude */
-    public static final String VALIDATE_ON_SET                 = "VALIDATE_ON_SET";
-    /** @exclude */
-    public static final String VALIDATE_TREAT_LAX_AS_SKIP      = "VALIDATE_TREAT_LAX_AS_SKIP";
-    /** @exclude */
-    public static final String VALIDATE_STRICT                 = "VALIDATE_STRICT";
-    /** @exclude */
-    public static final String VALIDATE_TEXT_ONLY              = "VALIDATE_TEXT_ONLY";
-    /** @exclude */
-    public static final String UNSYNCHRONIZED                  = "UNSYNCHRONIZED";
-    /** @exclude */
-    public static final String ENTITY_RESOLVER                 = "ENTITY_RESOLVER";
-    /** @exclude */
-    public static final String BASE_URI                        = "BASE_URI";
-    /** @exclude */
-    public static final String SCHEMA_CODE_PRINTER             = "SCHEMA_CODE_PRINTER";
-    /** @exclude */
-    public static final String GENERATE_JAVA_VERSION           = "GENERATE_JAVA_VERSION";
-    /** @exclude */
-    public static final String COPY_USE_NEW_SYNC_DOMAIN        = "COPY_USE_NEW_LOCALE";
-    /** @exclude */
-    public static final String LOAD_ENTITY_BYTES_LIMIT         = "LOAD_ENTITY_BYTES_LIMIT";
-    /** @exclude */
-    public static final String ENTITY_EXPANSION_LIMIT          = "ENTITY_EXPANSION_LIMIT";
-    /** @exclude */
-    public static final String LOAD_DTD_GRAMMAR                = "LOAD_DTD_GRAMMAR";
-    /** @exclude */
-    public static final String LOAD_EXTERNAL_DTD               = "LOAD_EXTERNAL_DTD";
-
-    public static final int DEFAULT_ENTITY_EXPANSION_LIMIT = 2048;
-
-    private static final XmlOptions EMPTY_OPTIONS;
-    static {
-        EMPTY_OPTIONS = new XmlOptions();
-        EMPTY_OPTIONS._map = Collections.unmodifiableMap(EMPTY_OPTIONS._map);
+    public boolean isLoadExternalDTD() {
+        Boolean flag = (Boolean) get(LOAD_EXTERNAL_DTD);
+        return flag != null && flag;
     }
 
-    /** If passed null, returns an empty options object.  Otherwise, returns its argument. */
+    public XmlOptions setSaveOptimizeForSpeed(boolean saveOptimizeForSpeed) {
+        return set(SAVE_OPTIMIZE_FOR_SPEED, saveOptimizeForSpeed);
+    }
+
+    public boolean isSaveOptimizeForSpeed() {
+        Boolean flag = (Boolean) get(SAVE_OPTIMIZE_FOR_SPEED);
+        return flag != null && flag;
+    }
+
+
+    /**
+     * If passed null, returns an empty options object.  Otherwise, returns its argument.
+     */
     public static XmlOptions maskNull(XmlOptions o) {
         return (o == null) ? EMPTY_OPTIONS : o;
     }
 
-    
-    /** Used to set a generic option */
-    public void  put ( Object option               ) { put( option, null ); }
-    /** Used to set a generic option */
-    public void  put ( Object option, Object value ) { _map.put(option, value); }
-    /** Used to set a generic option */
-    public void put  ( Object option, int value    ) { put( option, new Integer( value ) ); }
 
-    private XmlOptions set(Object option)               { return set(option, null); }
-    private XmlOptions set(Object option, Object value) { _map.put(option, value); return this;}
-    private XmlOptions set(Object option, int value)    { return set(option, new Integer(value)); }
+    /**
+     * Used to set a generic option
+     */
+    public void put(String option) {
+        put(option, null);
+    }
 
-    /** Used to test a generic option */
-    public boolean hasOption   ( Object option ) { return _map.containsKey( option ); }
-    public static boolean hasOption ( XmlOptions options, Object option ) { return options == null ? false : options.hasOption( option ); }
-    
-    /** Used to get a generic option */
-    public Object  get         ( Object option ) { return _map.get( option ); }
-    public void    remove      ( Object option ) { _map.remove( option ); }
+    /**
+     * Used to set a generic option
+     */
+    public void put(String option, Object value) {
+        _map.put(option, value);
+    }
 
-    /** Used to test a generic option on an options object that may be null */
-    public static Object safeGet(XmlOptions o, Object option) {
+    /**
+     * Used to set a generic option
+     */
+    public void put(String option, int value) {
+        put(option, new Integer(value));
+    }
+
+    private XmlOptions set(String option) {
+        return set(option, null);
+    }
+
+    private XmlOptions set(String option, Object value) {
+        _map.put(option, value);
+        return this;
+    }
+
+    private XmlOptions set(String option, int value) {
+        return set(option, new Integer(value));
+    }
+
+    private XmlOptions set(String option, boolean value) {
+        if (value) {
+            set(option, Boolean.TRUE);
+        } else {
+            remove(option);
+        }
+        return this;
+    }
+
+    /**
+     * Used to test a generic option
+     */
+    public boolean hasOption(String option) {
+        return _map.containsKey(option);
+    }
+
+    public static boolean hasOption(XmlOptions options, String option) {
+        return options != null && options.hasOption(option);
+    }
+
+    /**
+     * Used to get a generic option
+     */
+    public Object get(String option) {
+        return _map.get(option);
+    }
+
+    public void remove(String option) {
+        _map.remove(option);
+    }
+
+    /**
+     * Used to test a generic option on an options object that may be null
+     */
+    public static Object safeGet(XmlOptions o, String option) {
         return o == null ? null : o.get(option);
     }
 
diff --git a/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java b/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java
index a148758..7ab1a51 100644
--- a/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java
+++ b/src/main/java/org/apache/xmlbeans/XmlOptionsBean.java
@@ -15,464 +15,25 @@
 
 package org.apache.xmlbeans;
 
-import org.xml.sax.XMLReader;
-import org.xml.sax.EntityResolver;
-
-import javax.xml.namespace.QName;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Same as {@link XmlOptions} but adhering to JavaBean conventions
+ *
+ * @deprecated use XmlOptions instead
  */
-public class XmlOptionsBean extends XmlOptions
-{
+@Deprecated
+public class XmlOptionsBean extends XmlOptions {
     /**
      * Construct a new blank XmlOptions.
      */
-    public XmlOptionsBean ( ) { }
+    public XmlOptionsBean() {
+    }
 
     /**
      * Construct a new XmlOptions, copying the options.
+     *
      * @param other the source <code>XmlOptions</code> object
      */
-    public XmlOptionsBean (XmlOptions other) {
-        super( other );
-    }
-
-
-    public void setSaveNamespacesFirst(boolean b)
-    {
-        if (b)
-            super.setSaveNamespacesFirst();
-        else
-            remove( SAVE_NAMESPACES_FIRST );
-    }
-
-    public boolean isSaveNamespacesFirst()
-    {
-        return hasOption( SAVE_NAMESPACES_FIRST );
-    }
-
-    public void setSavePrettyPrint(boolean b)
-    {
-        if (b)
-            super.setSavePrettyPrint();
-        else
-            remove( SAVE_PRETTY_PRINT );
-    }
-
-    public boolean isSavePrettyPrint()
-    {
-        return hasOption( SAVE_PRETTY_PRINT );
-    }
-
-    public Integer getSavePrettyPrintIndent()
-    {
-        return (Integer) get( SAVE_PRETTY_PRINT_INDENT );
-    }
-
-    public Integer getSavePrettyPrintOffset()
-    {
-        return (Integer) get( SAVE_PRETTY_PRINT_OFFSET );
-    }
-
-    public String getCharacterEncoding()
-    {
-        return (String) get( CHARACTER_ENCODING );
-    }
-
-    public SchemaType getDocumentType()
-    {
-        return (SchemaType) get ( DOCUMENT_TYPE );
-    }
-
-    public void setSaveAggressiveNamespaces(boolean b)
-    {
-        if (b)
-            super.setSaveAggressiveNamespaces();
-        else
-            remove( SAVE_AGGRESSIVE_NAMESPACES );
-    }
-
-    public boolean isSaveAggressiveNamespaces()
-    {
-        return hasOption( SAVE_AGGRESSIVE_NAMESPACES );
-    }
-
-    public QName getSaveSyntheticDocumentElement()
-    {
-        return (QName) get( SAVE_SYNTHETIC_DOCUMENT_ELEMENT );
-    }
-
-    public void setUseDefaultNamespace(boolean b)
-    {
-        if (b)
-            super.setUseDefaultNamespace();
-        else
-            remove( SAVE_USE_DEFAULT_NAMESPACE );
-    }
-
-    public boolean isUseDefaultNamespace()
-    {
-        return hasOption( SAVE_USE_DEFAULT_NAMESPACE );
-    }
-
-    public Map getSaveImplicitNamespaces()
-    {
-        return (Map) get( SAVE_IMPLICIT_NAMESPACES );
-    }
-
-    public Map getSaveSuggestedPrefixes()
-    {
-        return (Map) get( SAVE_SUGGESTED_PREFIXES );
-    }
-
-    public String getSaveFilterProcinst()
-    {
-        return (String) get( SAVE_FILTER_PROCINST );
-    }
-
-    public XmlOptionCharEscapeMap getSaveSubstituteCharacters()
-    {
-        return (XmlOptionCharEscapeMap) get( SAVE_SUBSTITUTE_CHARACTERS );
-    }
-
-    public void setSaveUseOpenFrag(boolean b)
-    {
-        if (b)
-            super.setSaveUseOpenFrag();
-        else
-            remove( SAVE_USE_OPEN_FRAGMENT );
-    }
-
-    public boolean isSaveUseOpenFrag()
-    {
-        return hasOption( SAVE_USE_OPEN_FRAGMENT );
-    }
-
-    public void setSaveOuter(boolean b)
-    {
-        if (b)
-            super.setSaveOuter();
-        else
-            remove( SAVE_OUTER );
-    }
-
-    public boolean isSaveOuter()
-    {
-        return hasOption( SAVE_OUTER );
-    }
-
-    public void setSaveInner(boolean b)
-    {
-        if (b)
-            super.setSaveInner();
-        else
-            remove( SAVE_INNER );
-    }
-
-    public boolean isSaveInner()
-    {
-        return hasOption( SAVE_INNER );
-    }
-
-    public void setSaveNoXmlDecl(boolean b)
-    {
-        if (b)
-            super.setSaveNoXmlDecl();
-        else
-            remove( SAVE_NO_XML_DECL );
-    }
-
-    public boolean isSaveNoXmlDecl()
-    {
-        return hasOption( SAVE_NO_XML_DECL );
-    }
-
-    public Integer getSaveCDataLengthThreshold()
-    {
-        return (Integer) get( SAVE_CDATA_LENGTH_THRESHOLD );
-    }
-
-    public Integer getSaveCDataEntityCountThreshold()
-    {
-        return (Integer) get( SAVE_CDATA_ENTITY_COUNT_THRESHOLD );
-    }
-
-    public void setSaveSaxNoNSDeclsInAttributes(boolean b)
-    {
-        if (b)
-            super.setSaveSaxNoNSDeclsInAttributes();
-        else
-            remove( SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES );
-    }
-
-    public boolean isSaveSaxNoNSDeclsInAttributes()
-    {
-        return hasOption( SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES );
-    }
-
-    public QName getLoadReplaceDocumentElement()
-    {
-        return (QName) get( LOAD_REPLACE_DOCUMENT_ELEMENT );
-    }
-
-    public void setLoadStripWhitespace(boolean b)
-    {
-        if (b)
-            super.setLoadStripWhitespace();
-        else
-            remove( LOAD_STRIP_WHITESPACE );
-    }
-
-    public boolean isSetLoadStripWhitespace()
-    {
-        return hasOption( LOAD_STRIP_WHITESPACE );
-    }
-
-    public void setLoadStripComments(boolean b)
-    {
-        if (b)
-            super.setLoadStripComments();
-        else
-            remove( LOAD_STRIP_COMMENTS );
-    }
-
-    public boolean isLoadStripComments()
-    {
-        return hasOption( LOAD_STRIP_COMMENTS );
-    }
-
-    public void setLoadStripProcinsts(boolean b)
-    {
-        if (b)
-            super.setLoadStripProcinsts();
-        else
-            remove( LOAD_STRIP_PROCINSTS );
-    }
-
-    public boolean isLoadStripProcinsts()
-    {
-        return hasOption( LOAD_STRIP_PROCINSTS );
-    }
-
-    public void setLoadLineNumbers(boolean b)
-    {
-        if (b)
-            super.setLoadLineNumbers();
-        else
-            remove( LOAD_LINE_NUMBERS );
-    }
-
-    public boolean isLoadLineNumbers()
-    {
-        return hasOption( LOAD_LINE_NUMBERS );
-    }
-
-    public Map getLoadSubstituteNamespaces()
-    {
-        return (Map) get( LOAD_SUBSTITUTE_NAMESPACES );
-    }
-
-    public void setLoadTrimTextBuffer(boolean b)
-    {
-        if (b)
-            super.setLoadTrimTextBuffer();
-        else
-            remove( LOAD_TRIM_TEXT_BUFFER );
-    }
-
-    public boolean isLoadTrimTextBuffer()
-    {
-        return hasOption( LOAD_TRIM_TEXT_BUFFER );
-    }
-
-    public Map getLoadAdditionalNamespaces()
-    {
-        return (Map) get( LOAD_ADDITIONAL_NAMESPACES );
-    }
-
-    public void setLoadMessageDigest(boolean b)
-    {
-        if (b)
-            super.setLoadMessageDigest();
-        else
-            remove( LOAD_MESSAGE_DIGEST );
-    }
-
-    public boolean isLoadMessageDigest()
-    {
-        return hasOption( LOAD_MESSAGE_DIGEST );
-    }
-
-    public void setLoadUseDefaultResolver(boolean b)
-    {
-        if (b)
-            super.setLoadUseDefaultResolver();
-        else
-            remove( LOAD_USE_DEFAULT_RESOLVER );
-    }
-
-    public boolean isLoadUseDefaultResolver()
-    {
-        return hasOption( LOAD_USE_DEFAULT_RESOLVER );
-    }
-
-    public String getXqueryCurrentNodeVar()
-    {
-        return (String) get( XQUERY_CURRENT_NODE_VAR );
-    }
-
-    public Map getXqueryVariables()
-    {
-        return (Map) get( XQUERY_VARIABLE_MAP );
-    }
-
-    public String getDocumentSourceName()
-    {
-        return (String) get( DOCUMENT_SOURCE_NAME );
-    }
-
-    public Map getCompileSubstituteNames()
-    {
-        return (Map) get( COMPILE_SUBSTITUTE_NAMES );
-    }
-
-    public void setCompileNoUpaRule(boolean b)
-    {
-        if (b)
-            super.setCompileNoUpaRule();
-        else
-            remove( COMPILE_NO_UPA_RULE );
-    }
-
-    public boolean isCompileNoUpaRule()
-    {
-        return hasOption( COMPILE_NO_UPA_RULE );
-    }
-
-    public void setCompileNoPvrRule(boolean b)
-    {
-        if (b)
-            super.setCompileNoPvrRule();
-        else
-            remove( COMPILE_NO_PVR_RULE );
-    }
-
-    public boolean isCompileNoPvrRule()
-    {
-        return hasOption( COMPILE_NO_PVR_RULE );
-    }
-
-    public void setCompileNoAnnotations(boolean b)
-    {
-        if (b)
-            super.setCompileNoAnnotations();
-        else
-            remove( COMPILE_NO_ANNOTATIONS );
-    }
-
-    public boolean isCompileNoAnnotations()
-    {
-        return hasOption( COMPILE_NO_ANNOTATIONS );
-    }
-
-    public void setCompileDownloadUrls(boolean b)
-    {
-        if (b)
-            super.setCompileDownloadUrls();
-        else
-            remove( COMPILE_DOWNLOAD_URLS );
-    }
-
-    public boolean isCompileDownloadUrls()
-    {
-        return hasOption( COMPILE_DOWNLOAD_URLS );
-    }
-
-    public Set getCompileMdefNamespaces()
-    {
-        return (Set) get( COMPILE_MDEF_NAMESPACES );
-    }
-
-    public void setValidateOnSet(boolean b)
-    {
-        if (b)
-            super.setValidateOnSet();
-        else
-            remove( VALIDATE_ON_SET );
-    }
-
-    public boolean isValidateOnSet()
-    {
-        return hasOption( VALIDATE_ON_SET );
-    }
-
-    public void setValidateTreatLaxAsSkip(boolean b)
-    {
-        if (b)
-            super.setValidateTreatLaxAsSkip();
-        else
-            remove( VALIDATE_TREAT_LAX_AS_SKIP );
-    }
-
-    public boolean isValidateTreatLaxAsSkip()
-    {
-        return hasOption( VALIDATE_TREAT_LAX_AS_SKIP );
-    }
-
-    public void setValidateStrict(boolean b)
-    {
-        if (b)
-            super.setValidateStrict();
-        else
-            remove( VALIDATE_STRICT );
-    }
-
-    public boolean isValidateStrict()
-    {
-        return hasOption( VALIDATE_STRICT );
-    }
-
-    public void setUnsynchronized(boolean b)
-    {
-        if (b)
-            super.setUnsynchronized();
-        else
-            remove( UNSYNCHRONIZED );
-    }
-
-    public boolean isUnsynchronized()
-    {
-        return hasOption( UNSYNCHRONIZED );
-    }
-
-    public EntityResolver getEntityResolver()
-    {
-        return (EntityResolver) get( ENTITY_RESOLVER );
-    }
-
-    public String getGenerateJavaVersion()
-    {
-        return (String) get( GENERATE_JAVA_VERSION );
-    }
-
-    public int getEntityExpansionLimit()
-    {
-        Integer limit = (Integer) get( ENTITY_EXPANSION_LIMIT );
-        return limit == null ? DEFAULT_ENTITY_EXPANSION_LIMIT : limit;
-    }
-
-    public boolean isLoadDTDGrammar()
-    {
-        Boolean flag = (Boolean) get( LOAD_DTD_GRAMMAR );
-        return flag == null ? false : flag;
-    }
-
-    public boolean isLoadExternalDTD()
-    {
-        Boolean flag = (Boolean) get( LOAD_EXTERNAL_DTD );
-        return flag == null ? false : flag;
+    public XmlOptionsBean(XmlOptions other) {
+        super(other);
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/XmlTokenSource.java b/src/main/java/org/apache/xmlbeans/XmlTokenSource.java
index 2c57fd1..0cf0c11 100644
--- a/src/main/java/org/apache/xmlbeans/XmlTokenSource.java
+++ b/src/main/java/org/apache/xmlbeans/XmlTokenSource.java
@@ -16,21 +16,13 @@
 package org.apache.xmlbeans;
 
 import org.apache.xmlbeans.xml.stream.XMLInputStream;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.io.File;
-import java.io.IOException;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
 
 import javax.xml.stream.XMLStreamReader;
-
-import org.w3c.dom.Node;
-
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.SAXException;
+import java.io.*;
 
 /**
  * Represents a holder of XML that can return an {@link XmlCursor}
@@ -39,12 +31,11 @@
  * Both {@link XmlObject}
  * (and thus all XML Beans) and {@link XmlCursor} are
  * XmlTokenSource implementations.
- * 
+ *
  * @see XmlObject
  * @see XmlCursor
- */ 
-public interface XmlTokenSource
-{
+ */
+public interface XmlTokenSource {
     /**
      * Returns the synchronization object for the document.  If concurrent
      * multithreaded access to a document is required, the access should should
@@ -52,7 +43,7 @@
      * monitor per XML document tree.
      */
     Object monitor();
-    
+
     /**
      * Returns the XmlDocumentProperties object for the document this token
      * source is associated with.
@@ -61,12 +52,12 @@
 
     /**
      * Returns a new XML cursor.
-     *
+     * <p>
      * A cursor provides random access to all the tokens in the XML
      * data, plus the ability to extract strongly-typed XmlObjects
      * for the data. If the data is not read-only, the XML cursor
      * also allows modifications to the data.
-     *
+     * <p>
      * Using a cursor for the first time typically forces the XML
      * document into memory.
      */
@@ -74,33 +65,34 @@
 
     /**
      * Returns a new XmlInputStream.
-     *
+     * <p>
      * The stream starts at the current begin-tag or begin-document
      * position and ends at the matching end-tag or end-document.
-     *
+     * <p>
      * This is a fail-fast stream, so if the underlying data is changed
      * while the stream is being read, the stream throws a
      * ConcurrentModificationException.
-     *
+     * <p>
      * Throws an IllegalStateException if the XmlTokenSource is not
      * positioned at begin-tag or begin-document (e.g., if it is at
      * an attribute).
+     *
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     XMLInputStream newXMLInputStream();
-    
+
     /**
      * Returns a new XMLStreamReader.
-     *
+     * <p>
      * The stream starts at the current begin-tag or begin-document
      * position and ends at the matching end-tag or end-document.
-     *
+     * <p>
      * This is a fail-fast stream, so if the underlying data is changed
      * while the stream is being read, the stream throws a
      * ConcurrentModificationException.
      */
     XMLStreamReader newXMLStreamReader();
-    
+
     /**
      * Returns standard XML text.
      * <p>
@@ -113,8 +105,8 @@
      * positioned at begin-tag or begin-document (e.g., if it is at
      * an attribute).
      * <p>
-     * Note that this method does not produce XML with the XML declaration, 
-     * including the encoding information. To save the XML declaration with 
+     * Note that this method does not produce XML with the XML declaration,
+     * including the encoding information. To save the XML declaration with
      * the XML, see {@link #save(OutputStream)} or {@link #save(OutputStream, XmlOptions)}.
      */
     String xmlText();
@@ -122,16 +114,16 @@
     /**
      * Returns a new stream containing standard XML text, encoded
      * according to the given encoding.
-     *
+     * <p>
      * The byte stream contains contents starting at the current
      * begin-tag or begin-document and ending at the matching
      * end-tag or end-document.  The specified encoding is used
      * and also emitted in a PI at the beginning of the stream.
-     *
+     * <p>
      * This is a fail-fast stream, so if the underlying data is changed
      * while the stream is being read, the stream throws a
      * ConcurrentModificationException.
-     *
+     * <p>
      * Throws an IllegalStateException if the XmlTokenSource is not
      * positioned at begin-tag or begin-document (e.g., if it is at
      * an attribute).
@@ -140,22 +132,22 @@
 
     /**
      * Returns a new character reader containing XML text.
-     *
+     * <p>
      * The contents of the reader represents the document contents
      * starting at the current begin-tag or begin-document and ending at
      * the matching end-tag or end-document.  No encoding annotation
      * will be made in the text itself.
-     *
+     * <p>
      * This is a fail-fast reader, so if the underlying data is changed
      * while the reader is being read, the reader throws a
      * ConcurrentModificationException.
-     *
+     * <p>
      * Throws an IllegalStateException if the XmlTokenSource is not
      * positioned at begin-tag or begin-document (e.g., if it is at
      * an attribute).
      */
     Reader newReader();
-    
+
     /**
      * Returns a W3C DOM Node containing the XML
      * represented by this source.  This is a copy of the XML, it is
@@ -177,38 +169,38 @@
     /**
      * Writes the XML represented by this source to the given SAX content and
      * lexical handlers.
-     * Note that this method does not save the XML declaration, including the encoding information. 
-     * To save the XML declaration with the XML, see {@link #save(OutputStream)}, 
+     * Note that this method does not save the XML declaration, including the encoding information.
+     * To save the XML declaration with the XML, see {@link #save(OutputStream)},
      * {@link #save(OutputStream, XmlOptions)}, {@link #save(File)} or {@link #save(File, XmlOptions)}.
      */
-    void save ( ContentHandler ch, LexicalHandler lh ) throws SAXException;
-    
+    void save(ContentHandler ch, LexicalHandler lh) throws SAXException;
+
     /**
      * Writes the XML represented by this source to the given File.
      * This method will save the XML declaration, including encoding information,
      * with the XML.
      */
-    void save ( File file ) throws IOException;
-    
+    void save(File file) throws IOException;
+
     /**
      * Writes the XML represented by this source to the given output stream.
      * This method will save the XML declaration, including encoding information,
      * with the XML.
      */
-    void save ( OutputStream os ) throws IOException;
+    void save(OutputStream os) throws IOException;
 
     /**
      * Writes the XML represented by this source to the given output.
-     * Note that this method does not save the XML declaration, including the encoding information. 
-     * To save the XML declaration with the XML, see {@link #save(OutputStream)}, 
+     * Note that this method does not save the XML declaration, including the encoding information.
+     * To save the XML declaration with the XML, see {@link #save(OutputStream)},
      * {@link #save(OutputStream, XmlOptions)}, {@link #save(File)} or {@link #save(File, XmlOptions)}.
      */
-    void save ( Writer w ) throws IOException;
+    void save(Writer w) throws IOException;
 
     /**
-     * <p>Just like newXMLInputStream() but with any of a number of options. Use the 
+     * <p>Just like newXMLInputStream() but with any of a number of options. Use the
      * <em>options</em> parameter to specify the following:</p>
-     * 
+     *
      * <table>
      * <tr><th>To specify this</th><th>Use this method</th></tr>
      * <tr>
@@ -219,8 +211,8 @@
      * <tr>
      *  <td>Prefix-to-namespace mappings that should be assumed
      *  when saving this XML. This is useful when the resulting
-     *  XML will be part of a larger XML document, ensuring that this 
-     *  inner document will take advantage of namespaces defined in 
+     *  XML will be part of a larger XML document, ensuring that this
+     *  inner document will take advantage of namespaces defined in
      *  the outer document.</td>
      *  <td>{@link XmlOptions#setSaveImplicitNamespaces}</td>
      * </tr>
@@ -235,12 +227,12 @@
      *  <td>{@link XmlOptions#setSaveNamespacesFirst}</td>
      * </tr>
      * <tr>
-     *  <td>The XML should be pretty printed when saved. Note that this 
+     *  <td>The XML should be pretty printed when saved. Note that this
      *  should only be used for debugging.</td>
      *  <td>{@link XmlOptions#setSavePrettyPrint}</td>
      * </tr>
      * <tr>
-     *  <td>The number of spaces to use when indenting for pretty printing. 
+     *  <td>The number of spaces to use when indenting for pretty printing.
      *  The default is 2.</td>
      *  <td>{@link XmlOptions#setSavePrettyPrintIndent}</td>
      * </tr>
@@ -250,14 +242,14 @@
      *  <td>{@link XmlOptions#setSavePrettyPrintOffset}</td>
      * </tr>
      * <tr>
-     *  <td>To minimize the number of namespace attributes generated for the 
+     *  <td>To minimize the number of namespace attributes generated for the
      *  saved XML. Note that this can reduce performance significantly.</td>
-     *  <td>{@link XmlOptions#setSaveAggresiveNamespaces}</td>
+     *  <td>{@link XmlOptions#setSaveAggressiveNamespaces}</td>
      * </tr>
      * <tr>
      *  <td>To reduce the size of the saved document
-     *  by allowing the use of the default namespace. Note that this can 
-     *  potentially change the semantic meaning of the XML if unprefixed QNames are 
+     *  by allowing the use of the default namespace. Note that this can
+     *  potentially change the semantic meaning of the XML if unprefixed QNames are
      *  present as the value of an attribute or element.</td>
      *  <td>{@link XmlOptions#setUseDefaultNamespace}</td>
      * </tr>
@@ -266,8 +258,8 @@
      *  <td>{@link XmlOptions#setSaveFilterProcinst}</td>
      * </tr>
      * <tr>
-     *  <td>Change the QName of the synthesized root element when saving. This 
-     *  replaces "xml-fragment" with "fragment" in the namespace 
+     *  <td>Change the QName of the synthesized root element when saving. This
+     *  replaces "xml-fragment" with "fragment" in the namespace
      *  http://www.openuri.org/fragment</td>
      *  <td>{@link XmlOptions#setSaveUseOpenFrag}</td>
      * </tr>
@@ -285,11 +277,10 @@
      *  <td>{@link XmlOptions#setSaveSyntheticDocumentElement}</td>
      * </tr>
      * </table>
-     * 
-     * @see XmlOptions
-     * 
+     *
      * @param options Any of the described options.
      * @return A new validating XMLInputStream.
+     * @see XmlOptions
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     XMLInputStream newXMLInputStream(XmlOptions options);
@@ -297,75 +288,78 @@
     /**
      * Just like newXMLInputStream() but with options.
      * Options map may be null.
+     *
      * @see XmlOptions
      */
     XMLStreamReader newXMLStreamReader(XmlOptions options);
-    
+
     /**
      * Just like xmlText() but with options.
      * Options map may be null.
      * <p>
-     * Note that this method does not produce XML with the XML declaration, 
-     * including the encoding information. To save the XML declaration with 
+     * Note that this method does not produce XML with the XML declaration,
+     * including the encoding information. To save the XML declaration with
      * the XML, see {@link #save(OutputStream)} or {@link #save(OutputStream, XmlOptions)}.
      *
      * @see XmlOptions
      */
     String xmlText(XmlOptions options);
-    
+
     /**
-     *
      * Just like newInputStream(String encoding) but with options.
      * Options map may be null.
+     *
      * @see XmlOptions
      */
     InputStream newInputStream(XmlOptions options);
-    
+
     /**
      * Just like newReader() but with options.
      * Options map may be null.
+     *
      * @see XmlOptions
      */
     Reader newReader(XmlOptions options);
-    
+
     /**
      * Just like newDomNode() but with options.
      * Options map may be null.
+     *
      * @see XmlOptions
      */
 
     Node newDomNode(XmlOptions options);
-    
+
     /**
      * Writes the XML represented by this source to the given SAX content and
      * lexical handlers.
-     * Note that this method does not save the XML declaration, including the encoding information. 
-     * To save the XML declaration with the XML, see {@link #save(OutputStream)}, 
+     * Note that this method does not save the XML declaration, including the encoding information.
+     * To save the XML declaration with the XML, see {@link #save(OutputStream)},
      * {@link #save(OutputStream, XmlOptions)}, {@link #save(File)} or {@link #save(File, XmlOptions)}.
      */
-    void save ( ContentHandler ch, LexicalHandler lh, XmlOptions options ) throws SAXException;
-    
+    void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException;
+
     /**
      * Writes the XML represented by this source to the given File.
      * This method will save the XML declaration, including encoding information,
      * with the XML.
      */
-    void save ( File file, XmlOptions options ) throws IOException;
-    
+    void save(File file, XmlOptions options) throws IOException;
+
     /**
      * Writes the XML represented by this source to the given output stream.
      * This method will save the XML declaration, including encoding information,
      * with the XML.
      */
-    void save ( OutputStream os, XmlOptions options ) throws IOException;
+    void save(OutputStream os, XmlOptions options) throws IOException;
 
     /**
      * Writes the XML represented by this source to the given output.
-     * Note that this method does not save the XML declaration, including the encoding information. 
-     * To save the XML declaration with the XML, see {@link #save(OutputStream)}, 
+     * Note that this method does not save the XML declaration, including the encoding information.
+     * To save the XML declaration with the XML, see {@link #save(OutputStream)},
      * {@link #save(OutputStream, XmlOptions)}, {@link #save(File)} or {@link #save(File, XmlOptions)}.
      */
-    void save ( Writer w, XmlOptions options ) throws IOException;
+    void save(Writer w, XmlOptions options) throws IOException;
 
     /**
      * Prints to stdout the state of the document in which this token source is positioned.
@@ -374,5 +368,5 @@
      * XML text which only approximates the actual state of the document.
      */
 
-    void dump ( );
+    void dump();
 }
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 e3040c9..a66f293 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/SAXHelper.java
@@ -15,21 +15,21 @@
 
 package org.apache.xmlbeans.impl.common;
 
-import java.io.IOException;
-import java.io.StringReader;
-import java.lang.reflect.Method;
-import java.util.concurrent.TimeUnit;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParserFactory;
-
+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;
 import org.xml.sax.XMLReader;
 
+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;
+
 /**
  * Provides handy methods for working with SAX parsers and readers
  */
@@ -37,23 +37,24 @@
     private static final XBLogger logger = XBLogFactory.getLogger(SAXHelper.class);
     private static long lastLog;
 
-    private SAXHelper() {}
+    private SAXHelper() {
+    }
 
     /**
      * Creates a new SAX XMLReader, with sensible defaults
      */
-    public static XMLReader newXMLReader(XmlOptionsBean options) throws SAXException, ParserConfigurationException {
+    public static XMLReader newXMLReader(XmlOptions options) throws SAXException, ParserConfigurationException {
         XMLReader xmlReader = saxFactory(options).newSAXParser().getXMLReader();
         xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER);
         trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING);
         trySetXercesSecurityManager(xmlReader, options);
         return xmlReader;
     }
-    
+
     public static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
         @Override
         public InputSource resolveEntity(String publicId, String systemId)
-                throws SAXException, IOException {
+            throws SAXException, IOException {
             return new InputSource(new StringReader(""));
         }
     };
@@ -62,7 +63,7 @@
         return saxFactory(new XmlOptionsBean());
     }
 
-    static SAXParserFactory saxFactory(XmlOptionsBean options) {
+    static SAXParserFactory saxFactory(XmlOptions options) {
         SAXParserFactory saxFactory = SAXParserFactory.newInstance();
         saxFactory.setValidating(false);
         saxFactory.setNamespaceAware(true);
@@ -91,12 +92,12 @@
             logger.log(XBLogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
         }
     }
-    
-    private static void trySetXercesSecurityManager(XMLReader xmlReader, XmlOptionsBean options) {
+
+    private static void trySetXercesSecurityManager(XMLReader xmlReader, XmlOptions options) {
         // Try built-in JVM one first, standalone if not
-        for (String securityManagerClassName : new String[] {
-                //"com.sun.org.apache.xerces.internal.util.SecurityManager",
-                "org.apache.xerces.util.SecurityManager"
+        for (String securityManagerClassName : new String[]{
+            //"com.sun.org.apache.xerces.internal.util.SecurityManager",
+            "org.apache.xerces.util.SecurityManager"
         }) {
             try {
                 Object mgr = Class.forName(securityManagerClassName).newInstance();
@@ -107,7 +108,7 @@
                 return;
             } catch (Throwable e) {     // NOSONAR - also catch things like NoClassDefError here
                 // throttle the log somewhat as it can spam the log otherwise
-                if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
+                if (System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
                     logger.log(XBLogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
                     lastLog = System.currentTimeMillis();
                 }
@@ -119,7 +120,7 @@
             xmlReader.setProperty(XMLBeansConstants.ENTITY_EXPANSION_LIMIT, options.getEntityExpansionLimit());
         } catch (SAXException e) {     // NOSONAR - also catch things like NoClassDefError here
             // throttle the log somewhat as it can spam the log otherwise
-            if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
+            if (System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
                 logger.log(XBLogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
                 lastLog = System.currentTimeMillis();
             }
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java b/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java
index eae88ac..2183252 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java
@@ -17,43 +17,37 @@
 
 import org.apache.xmlbeans.XmlError;
 
-import java.util.AbstractCollection;
-import java.util.Iterator;
-import java.util.Collections;
 import java.net.URI;
+import java.util.AbstractCollection;
+import java.util.Collections;
+import java.util.Iterator;
 
-public class XmlErrorPrinter extends AbstractCollection
-{
-    private boolean _noisy;
-    private URI _baseURI;
+public class XmlErrorPrinter extends AbstractCollection<XmlError> {
+    private final boolean _noisy;
+    private final URI _baseURI;
 
-    public XmlErrorPrinter(boolean noisy, URI baseURI)
-    {
+    public XmlErrorPrinter(boolean noisy, URI baseURI) {
         _noisy = noisy;
         _baseURI = baseURI;
     }
 
-    public boolean add(Object o)
-    {
-        if (o instanceof XmlError)
-        {
-            XmlError err = (XmlError)o;
+    public boolean add(XmlError err) {
+        if (err != null) {
             if (err.getSeverity() == XmlError.SEVERITY_ERROR ||
-                err.getSeverity() == XmlError.SEVERITY_WARNING)
+                err.getSeverity() == XmlError.SEVERITY_WARNING) {
                 System.err.println(err.toString(_baseURI));
-            else if (_noisy)
+            } else if (_noisy) {
                 System.out.println(err.toString(_baseURI));
+            }
         }
         return false;
     }
 
-    public Iterator iterator()
-    {
-        return Collections.EMPTY_LIST.iterator();
+    public Iterator<XmlError> iterator() {
+        return Collections.emptyIterator();
     }
 
-    public int size()
-    {
+    public int size() {
         return 0;
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java b/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java
index d802590..b13ab5e 100644
--- a/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java
+++ b/src/main/java/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java
@@ -19,51 +19,48 @@
 
 import java.util.AbstractCollection;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.Collections;
+import java.util.Iterator;
 
-public class XmlErrorWatcher extends AbstractCollection
-{
-    private Collection _underlying;
+public class XmlErrorWatcher extends AbstractCollection<XmlError> {
+    private final Collection<XmlError> _underlying;
     private XmlError _firstError;
 
-    public XmlErrorWatcher(Collection underlying)
-    {
+    public XmlErrorWatcher(Collection<XmlError> underlying) {
         _underlying = underlying;
     }
 
-    public boolean add(Object o)
-    {
-        if (_firstError == null && o instanceof XmlError && ((XmlError)o).getSeverity() == XmlError.SEVERITY_ERROR)
-            _firstError = (XmlError)o;
-        if (_underlying == null)
+    public boolean add(XmlError o) {
+        if (_firstError == null && o != null && o.getSeverity() == XmlError.SEVERITY_ERROR) {
+            _firstError = o;
+        }
+        if (_underlying == null) {
             return false;
+        }
         return _underlying.add(o);
     }
 
-    public Iterator iterator()
-    {
-        if (_underlying == null)
-            return Collections.EMPTY_LIST.iterator();
+    public Iterator<XmlError> iterator() {
+        if (_underlying == null) {
+            return Collections.emptyIterator();
+        }
 
         return _underlying.iterator();
     }
 
-    public int size()
-    {
-        if (_underlying == null)
+    public int size() {
+        if (_underlying == null) {
             return 0;
+        }
 
         return _underlying.size();
     }
 
-    public boolean hasError()
-    {
+    public boolean hasError() {
         return _firstError != null;
     }
 
-    public XmlError firstError()
-    {
+    public XmlError firstError() {
         return _firstError;
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaDependencies.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaDependencies.java
index 3f4b6c7..2693b1d 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaDependencies.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaDependencies.java
@@ -15,51 +15,40 @@
 
 package org.apache.xmlbeans.impl.schema;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.stream.Collectors;
 
-public class SchemaDependencies
-{
+public class SchemaDependencies {
     // This class is NOT synchronized
 
-    void registerDependency(String source, String target)
-    {
-        Set depSet = (Set) _dependencies.get(target);
-        if (depSet == null)
-        {
-            depSet = new HashSet();
-            _dependencies.put(target, depSet);
-        }
-        depSet.add(source);
-    }
-
-    
+    /**
+     * Records the list of files associated to each namespace.
+     * This is needed so that we can return a list of files that
+     * need to be compiled once we get a set of altered namespaces
+     */
+    private final Map<String, List<String>> _contributions = new HashMap<>();
 
     /**
      * Records anti-dependencies. Keys are namespaces and values are
      * the lists of namespaces that depend on each key
      */
-    private Map/*<String,Set<String>>*/ _dependencies;
+    private final Map<String, Set<String>> _dependencies = new HashMap<>();
 
-    Set computeTransitiveClosure(List modifiedNamespaces)
-    {
-        List nsList = new ArrayList(modifiedNamespaces);
-        Set result = new HashSet(modifiedNamespaces);
-        for (int i = 0; i < nsList.size(); i++)
-        {
-            Set deps = (Set) _dependencies.get(nsList.get(i));
-            if (deps == null)
+    void registerDependency(String source, String target) {
+        _dependencies.computeIfAbsent(target, k -> new HashSet<>()).add(source);
+    }
+
+
+    Set<String> computeTransitiveClosure(List<String> modifiedNamespaces) {
+        List<String> nsList = new ArrayList<>(modifiedNamespaces);
+        Set<String> result = new HashSet<>(modifiedNamespaces);
+        for (int i = 0; i < nsList.size(); i++) {
+            Set<String> deps = _dependencies.get(nsList.get(i));
+            if (deps == null) {
                 continue;
-            for (Iterator it = deps.iterator(); it.hasNext(); )
-            {
-                String ns = (String) it.next();
-                if (!result.contains(ns))
-                {
+            }
+            for (String ns : deps) {
+                if (!result.contains(ns)) {
                     nsList.add(ns);
                     result.add(ns);
                 }
@@ -68,95 +57,52 @@
         return result;
     }
 
-    SchemaDependencies()
-    {
-        _dependencies = new HashMap();
-        _contributions = new HashMap();
+    SchemaDependencies() {
     }
 
-    SchemaDependencies(SchemaDependencies base, Set updatedNs)
-    {
-        _dependencies = new HashMap();
-        _contributions = new HashMap();
-        for (Iterator it = base._dependencies.keySet().iterator(); it.hasNext(); )
-        {
-            String target = (String) it.next();
-            if (updatedNs.contains(target))
+    SchemaDependencies(SchemaDependencies base, Set<String> updatedNs) {
+        for (String target : base._dependencies.keySet()) {
+            if (updatedNs.contains(target)) {
                 continue;
-            Set depSet = new HashSet();
+            }
+            Set<String> depSet = new HashSet<>();
             _dependencies.put(target, depSet);
-            Set baseDepSet = (Set) base._dependencies.get(target);
-            for (Iterator it2 = baseDepSet.iterator(); it2.hasNext(); )
-            {
-                String source = (String) it2.next();
-                if (updatedNs.contains(source))
+            Set<String> baseDepSet = base._dependencies.get(target);
+            for (String source : baseDepSet) {
+                if (updatedNs.contains(source)) {
                     continue;
+                }
                 depSet.add(source);
             }
         }
-        for (Iterator it = base._contributions.keySet().iterator(); it.hasNext(); )
-        {
-            String ns = (String) it.next();
-            if (updatedNs.contains(ns))
+        for (String ns : base._contributions.keySet()) {
+            if (updatedNs.contains(ns)) {
                 continue;
-            List fileList = new ArrayList();
+            }
+            List<String> fileList = new ArrayList<>();
             _contributions.put(ns, fileList);
-            List baseFileList = (List) base._contributions.get(ns);
-            for (Iterator it2 = baseFileList.iterator(); it2.hasNext(); )
-                fileList.add(it2.next());
+            fileList.addAll(base._contributions.get(ns));
         }
     }
 
-    /**
-     * Records the list of files associated to each namespace.
-     * This is needed so that we can return a list of files that
-     * need to be compiled once we get a set of altered namespaces
-     */
-    private Map/*<String,List<String>>*/ _contributions;
-
-    void registerContribution(String ns, String fileURL)
-    {
-        List fileList = (List) _contributions.get(ns);
-        if (fileList == null)
-        {
-            fileList = new ArrayList();
-            _contributions.put(ns, fileList);
-        }
-        fileList.add(fileURL);
+    void registerContribution(String ns, String fileURL) {
+        _contributions.computeIfAbsent(ns, k -> new ArrayList<>()).add(fileURL);
     }
 
-    boolean isFileRepresented(String fileURL)
-    {
-        for (Iterator it = _contributions.values().iterator(); it.hasNext(); )
-        {
-            List fileList = (List) it.next();
-            if (fileList.contains(fileURL))
-                return true;
-        }
-        return false;
+    boolean isFileRepresented(String fileURL) {
+        return _contributions.values().stream().anyMatch(l -> l.contains(fileURL));
     }
 
-    List getFilesTouched(Set updatedNs)
-    {
-        List result = new ArrayList();
-        for (Iterator it = updatedNs.iterator(); it.hasNext(); )
-        {
-            result.addAll((List) _contributions.get(it.next()));
-        }
-        return result;
+    List<String> getFilesTouched(Set<String> updatedNs) {
+        return updatedNs.stream().map(_contributions::get).
+            filter(Objects::nonNull).flatMap(List::stream).
+            collect(Collectors.toList());
     }
 
-    List getNamespacesTouched(Set modifiedFiles)
-    {
-        List result = new ArrayList();
-        for (Iterator it = _contributions.keySet().iterator(); it.hasNext(); )
-        {
-            String ns = (String) it.next();
-            List files = (List) _contributions.get(ns);
-            for (int i = 0; i < files.size(); i++)
-                if (modifiedFiles.contains(files.get(i)))
-                    result.add(ns);
-        }
-        return result;
+    List<String> getNamespacesTouched(Set<String> modifiedFiles) {
+        return _contributions.entrySet().stream().
+            filter(e -> e.getValue().stream().anyMatch(modifiedFiles::contains)).
+            map(Map.Entry::getKey).
+            collect(Collectors.toList());
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
index f548cf0..6793074 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java
@@ -57,32 +57,15 @@
         getPrinter(opt).printType(writer, sType);
     }
 
-    /**
-     * @deprecated
-     */
-    public static void printLoader(Writer writer, SchemaTypeSystem system,
-                                   XmlOptions opt)
-        throws IOException {
-        getPrinter(opt).printLoader(writer, system);
-    }
-
     private static SchemaCodePrinter getPrinter(XmlOptions opt) {
-        Object printer = XmlOptions.safeGet
-            (opt, XmlOptions.SCHEMA_CODE_PRINTER);
-        if (printer == null || !(printer instanceof SchemaCodePrinter)) {
-            printer = new SchemaTypeCodePrinter(opt);
-        }
-        return (SchemaCodePrinter) printer;
+        SchemaCodePrinter printer = opt == null ? null : opt.getSchemaCodePrinter();
+        return printer == null ? new SchemaTypeCodePrinter(opt) : printer;
     }
 
     public SchemaTypeCodePrinter(XmlOptions opt) {
         _indent = 0;
 
-        String genversion = null;
-
-        if (opt != null && XmlOptions.hasOption(opt, XmlOptions.GENERATE_JAVA_VERSION)) {
-            genversion = (String) opt.get(XmlOptions.GENERATE_JAVA_VERSION);
-        }
+        String genversion = (opt == null) ? null : opt.getGenerateJavaVersion();
 
         if (genversion == null) {
             genversion = XmlOptions.GENERATE_JAVA_14;
@@ -99,39 +82,6 @@
         _indent -= INDENT_INCREMENT;
     }
 
-    String encodeString(String s) {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append('"');
-
-        for (int i = 0; i < s.length(); i++) {
-            char ch = s.charAt(i);
-
-            if (ch == '"') {
-                sb.append('\\');
-                sb.append('\"');
-            } else if (ch == '\\') {
-                sb.append('\\');
-                sb.append('\\');
-            } else if (ch == '\r') {
-                sb.append('\\');
-                sb.append('r');
-            } else if (ch == '\n') {
-                sb.append('\\');
-                sb.append('n');
-            } else if (ch == '\t') {
-                sb.append('\\');
-                sb.append('t');
-            } else {
-                sb.append(ch);
-            }
-        }
-
-        sb.append('"');
-
-        return sb.toString();
-    }
-
     void emit(String s) throws IOException {
         int indent = _indent;
 
@@ -157,9 +107,6 @@
 
     private static String makeSafe(String s) {
         Charset charset = Charset.forName(System.getProperty("file.encoding"));
-        if (charset == null) {
-            throw new IllegalStateException("Default character set is null!");
-        }
         CharsetEncoder cEncoder = charset.newEncoder();
         StringBuilder result = new StringBuilder();
         int i;
@@ -174,7 +121,7 @@
             if (cEncoder.canEncode(c)) {
                 result.append(c);
             } else {
-                String hexValue = Integer.toHexString((int) c);
+                String hexValue = Integer.toHexString(c);
                 switch (hexValue.length()) {
                     case 1:
                         result.append("\\u000").append(hexValue);
@@ -269,8 +216,8 @@
             case SchemaType.UNION:
                 emit(" * This is a union type. Instances are of one of the following types:");
                 SchemaType[] members = sType.getUnionConstituentTypes();
-                for (int i = 0; i < members.length; i++) {
-                    emit(" *     " + members[i].getFullJavaName());
+                for (SchemaType member : members) {
+                    emit(" *     " + member.getFullJavaName());
                 }
                 break;
         }
@@ -310,26 +257,13 @@
         return name + "." + INDEX_CLASSNAME;
     }
 
-    static String shortIndexClassForSystem(SchemaTypeSystem system) {
-        return INDEX_CLASSNAME;
-    }
-
     void printStaticTypeDeclaration(SchemaType sType, SchemaTypeSystem system) throws IOException {
-        String interfaceShortName = sType.getShortJavaName();
         emit("public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)");
         indent();
         emit("Factory.getTypeLoader().resolveHandle(\"" + ((SchemaTypeSystemImpl) system).handleForType(sType) + "\");");
         outdent();
     }
 
-    /**
-     * @deprecated
-     */
-    public void printLoader(Writer writer, SchemaTypeSystem system)
-        throws IOException {
-        // deprecated
-    }
-
     void printInnerType(SchemaType sType, SchemaTypeSystem system) throws IOException {
         emit("");
 
@@ -350,9 +284,7 @@
 
             SchemaProperty[] props = getDerivedProperties(sType);
 
-            for (int i = 0; i < props.length; i++) {
-                SchemaProperty prop = props[i];
-
+            for (SchemaProperty prop : props) {
                 printPropertyGetters(
                     prop.getName(),
                     prop.isAttribute(),
@@ -549,11 +481,11 @@
                                sType.getName().equals(sType.getBaseType().getName());
         while (sType != null) {
             SchemaType[] anonTypes = sType.getAnonymousTypes();
-            for (int i = 0; i < anonTypes.length; i++) {
-                if (anonTypes[i].isSkippedAnonymousType()) {
-                    printNestedInnerTypes(anonTypes[i], system);
+            for (SchemaType anonType : anonTypes) {
+                if (anonType.isSkippedAnonymousType()) {
+                    printNestedInnerTypes(anonType, system);
                 } else {
-                    printInnerType(anonTypes[i], system);
+                    printInnerType(anonType, system);
                 }
             }
             // For redefinition other than by extension for complex types, go ahead and print
@@ -658,8 +590,8 @@
 
         InterfaceExtension[] exts = sImpl.getInterfaceExtensions();
         if (exts != null) {
-            for (int i = 0; i < exts.length; i++) {
-                sb.append(", " + exts[i].getInterface());
+            for (InterfaceExtension ext : exts) {
+                sb.append(", " + ext.getInterface());
             }
         }
 
@@ -808,10 +740,6 @@
         emit(" */");
     }
 
-    void printShortJavaDoc(String sentence) throws IOException {
-        emit("/** " + sentence + " */");
-    }
-
     public static String javaStringEscape(String str) {
         // forbidden: \n, \r, \", \\.
         test:
@@ -864,17 +792,17 @@
 
         emit("");
         SchemaStringEnumEntry[] entries = sType.getStringEnumEntries();
-        HashSet seenValues = new HashSet();
-        HashSet repeatValues = new HashSet();
-        for (int i = 0; i < entries.length; i++) {
-            String enumValue = entries[i].getString();
+        HashSet<String> seenValues = new HashSet<>();
+        HashSet<String> repeatValues = new HashSet<>();
+        for (SchemaStringEnumEntry entry : entries) {
+            String enumValue = entry.getString();
             if (seenValues.contains(enumValue)) {
                 repeatValues.add(enumValue);
                 continue;
             } else {
                 seenValues.add(enumValue);
             }
-            String constName = entries[i].getEnumName();
+            String constName = entry.getEnumName();
             if (hasBase) {
                 emit("static final " + baseEnumClass + ".Enum " + constName + " = " + baseEnumClass + "." + constName + ";");
             } else {
@@ -882,11 +810,11 @@
             }
         }
         emit("");
-        for (int i = 0; i < entries.length; i++) {
-            if (repeatValues.contains(entries[i].getString())) {
+        for (SchemaStringEnumEntry entry : entries) {
+            if (repeatValues.contains(entry.getString())) {
                 continue;
             }
-            String constName = "INT_" + entries[i].getEnumName();
+            String constName = "INT_" + entry.getEnumName();
             if (hasBase) {
                 emit("static final int " + constName + " = " + baseEnumClass + "." + constName + ";");
             } else {
@@ -929,9 +857,9 @@
             emit("private Enum(java.lang.String s, int i)");
             emit("    { super(s, i); }");
             emit("");
-            for (int i = 0; i < entries.length; i++) {
-                String constName = "INT_" + entries[i].getEnumName();
-                int intValue = entries[i].getIntValue();
+            for (SchemaStringEnumEntry entry : entries) {
+                String constName = "INT_" + entry.getEnumName();
+                int intValue = entry.getIntValue();
                 emit("static final int " + constName + " = " + intValue + ";");
             }
             emit("");
@@ -942,9 +870,9 @@
             emit("new Enum[]");
             emit("{");
             indent();
-            for (int i = 0; i < entries.length; i++) {
-                String enumValue = entries[i].getString();
-                String constName = "INT_" + entries[i].getEnumName();
+            for (SchemaStringEnumEntry entry : entries) {
+                String enumValue = entry.getString();
+                String constName = "INT_" + entry.getEnumName();
                 emit("new Enum(\"" + javaStringEscape(enumValue) + "\", " + constName + "),");
             }
             outdent();
@@ -984,8 +912,7 @@
     }
 
     static boolean isJavaPrimitive(int javaType) {
-        return (javaType < SchemaProperty.JAVA_FIRST_PRIMITIVE ? false :
-            (javaType > SchemaProperty.JAVA_LAST_PRIMITIVE ? false : true));
+        return (javaType >= SchemaProperty.JAVA_FIRST_PRIMITIVE && (javaType <= SchemaProperty.JAVA_LAST_PRIMITIVE));
     }
 
     /**
@@ -1356,8 +1283,8 @@
 
         if (sType.getSimpleVariety() == SchemaType.UNION) {
             SchemaType[] memberTypes = sType.getUnionMemberTypes();
-            for (int i = 0; i < memberTypes.length; i++) {
-                interfaces.append(", " + memberTypes[i].getFullJavaName().replace('$', '.'));
+            for (SchemaType memberType : memberTypes) {
+                interfaces.append(", " + memberType.getFullJavaName().replace('$', '.'));
             }
         }
 
@@ -1739,17 +1666,17 @@
         }
     }
 
-    String getIdentifier(Map qNameMap, QName qName) {
-        return ((String[]) qNameMap.get(qName))[0];
+    String getIdentifier(Map<QName, String[]> qNameMap, QName qName) {
+        return qNameMap.get(qName)[0];
     }
 
-    String getSetIdentifier(Map qNameMap, QName qName) {
-        String[] identifiers = (String[]) qNameMap.get(qName);
+    String getSetIdentifier(Map<QName, String[]> qNameMap, QName qName) {
+        String[] identifiers = qNameMap.get(qName);
         return identifiers[1] == null ? identifiers[0] : identifiers[1];
     }
 
-    Map printStaticFields(SchemaProperty[] properties) throws IOException {
-        final Map results = new HashMap();
+    Map<QName, String[]> printStaticFields(SchemaProperty[] properties) throws IOException {
+        final Map<QName, String[]> results = new HashMap<>();
 
         emit("");
         for (int i = 0; i < properties.length; i++) {
@@ -1777,9 +1704,9 @@
                     emit("private static final org.apache.xmlbeans.QNameSet " + identifiers[1] +
                          " = org.apache.xmlbeans.QNameSet.forArray( new javax.xml.namespace.QName[] { ");
                     indent();
-                    for (int j = 0; j < qnames.length; j++) {
-                        emit("new javax.xml.namespace.QName(\"" + qnames[j].getNamespaceURI() +
-                             "\", \"" + qnames[j].getLocalPart() + "\"),");
+                    for (QName qname : qnames) {
+                        emit("new javax.xml.namespace.QName(\"" + qname.getNamespaceURI() +
+                             "\", \"" + qname.getLocalPart() + "\"),");
                     }
 
                     outdent();
@@ -2499,21 +2426,6 @@
         }
     }
 
-    static void getTypeName(Class c, StringBuffer sb) {
-        int arrayCount = 0;
-        while (c.isArray()) {
-            c = c.getComponentType();
-            arrayCount++;
-        }
-
-        sb.append(c.getName());
-
-        for (int i = 0; i < arrayCount; i++) {
-            sb.append("[]");
-        }
-
-    }
-
     void printInnerTypeImpl(
         SchemaType sType, SchemaTypeSystem system, boolean isInner) throws IOException {
         String shortName = sType.getShortJavaImplName();
@@ -2538,16 +2450,16 @@
                 // but we still need to implement them because this class is supposed to
                 // also implement all the interfaces
                 SchemaType baseType = sType.getBaseType();
-                List extraProperties = null;
+                List<SchemaProperty> extraProperties = null;
                 while (!baseType.isSimpleType() && !baseType.isBuiltinType()) {
                     SchemaProperty[] baseProperties = baseType.getDerivedProperties();
-                    for (int i = 0; i < baseProperties.length; i++) {
-                        if (!(baseProperties[i].isAttribute() &&
-                              sType.getAttributeProperty(baseProperties[i].getName()) != null)) {
+                    for (SchemaProperty baseProperty : baseProperties) {
+                        if (!(baseProperty.isAttribute() &&
+                              sType.getAttributeProperty(baseProperty.getName()) != null)) {
                             if (extraProperties == null) {
-                                extraProperties = new ArrayList();
+                                extraProperties = new ArrayList<>();
                             }
-                            extraProperties.add(baseProperties[i]);
+                            extraProperties.add(baseProperty);
                         }
                     }
                     baseType = baseType.getBaseType();
@@ -2555,11 +2467,8 @@
 
                 properties = sType.getProperties();
                 if (extraProperties != null) {
-                    for (int i = 0; i < properties.length; i++) {
-                        extraProperties.add(properties[i]);
-                    }
-                    properties = (SchemaProperty[]) extraProperties.
-                        toArray(new SchemaProperty[extraProperties.size()]);
+                    Collections.addAll(extraProperties, properties);
+                    properties = extraProperties.toArray(new SchemaProperty[0]);
                 }
             } else {
                 // complex content type implementations derive from base type impls
@@ -2568,11 +2477,9 @@
                 properties = getDerivedProperties(sType);
             }
 
-            Map qNameMap = printStaticFields(properties);
+            Map<QName, String[]> qNameMap = printStaticFields(properties);
 
-            for (int i = 0; i < properties.length; i++) {
-                SchemaProperty prop = properties[i];
-
+            for (SchemaProperty prop : properties) {
                 QName name = prop.getName();
                 String xmlType = xmlTypeForProperty(prop);
 
@@ -2631,20 +2538,20 @@
             // not present in sType, because the redefined types do not
             // have a generated class to represent them
             SchemaProperty[] props = sType.getDerivedProperties();
-            Map propsByName = new LinkedHashMap();
-            for (int i = 0; i < props.length; i++) {
-                propsByName.put(props[i].getName(), props[i]);
+            Map<QName, SchemaProperty> propsByName = new LinkedHashMap<>();
+            for (SchemaProperty prop : props) {
+                propsByName.put(prop.getName(), prop);
             }
             while (sType2 != null && name.equals(sType2.getName())) {
                 props = sType2.getDerivedProperties();
-                for (int i = 0; i < props.length; i++) {
-                    if (!propsByName.containsKey(props[i].getName())) {
-                        propsByName.put(props[i].getName(), props[i]);
+                for (SchemaProperty prop : props) {
+                    if (!propsByName.containsKey(prop.getName())) {
+                        propsByName.put(prop.getName(), prop);
                     }
                 }
                 sType2 = sType2.getBaseType();
             }
-            return (SchemaProperty[]) propsByName.values().toArray(new SchemaProperty[0]);
+            return propsByName.values().toArray(new SchemaProperty[0]);
         } else {
             return sType.getDerivedProperties();
         }
@@ -2658,14 +2565,14 @@
 
         InterfaceExtension[] exts = sImpl.getInterfaceExtensions();
         if (exts != null) {
-            for (int i = 0; i < exts.length; i++) {
-                InterfaceExtension.MethodSignature[] methods = exts[i].getMethods();
+            for (InterfaceExtension ext : exts) {
+                InterfaceExtension.MethodSignature[] methods = ext.getMethods();
                 if (methods != null) {
-                    for (int j = 0; j < methods.length; j++) {
-                        printJavaDoc("Implementation method for interface " + exts[i].getStaticHandler());
-                        printInterfaceMethodDecl(methods[j]);
+                    for (InterfaceExtension.MethodSignature method : methods) {
+                        printJavaDoc("Implementation method for interface " + ext.getStaticHandler());
+                        printInterfaceMethodDecl(method);
                         startBlock();
-                        printInterfaceMethodImpl(exts[i].getStaticHandler(), methods[j]);
+                        printInterfaceMethodImpl(ext.getStaticHandler(), method);
                         endBlock();
                     }
                 }
@@ -2721,11 +2628,11 @@
                                sType.getName().equals(sType.getBaseType().getName());
         while (sType != null) {
             SchemaType[] anonTypes = sType.getAnonymousTypes();
-            for (int i = 0; i < anonTypes.length; i++) {
-                if (anonTypes[i].isSkippedAnonymousType()) {
-                    printNestedTypeImpls(anonTypes[i], system);
+            for (SchemaType anonType : anonTypes) {
+                if (anonType.isSkippedAnonymousType()) {
+                    printNestedTypeImpls(anonType, system);
                 } else {
-                    printInnerTypeImpl(anonTypes[i], system, true);
+                    printInnerTypeImpl(anonType, system, true);
                 }
             }
             // For redefinition by extension, go ahead and print the anonymous
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java
index d0c2b46..ff80dcb 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java
@@ -15,172 +15,134 @@
 
 package org.apache.xmlbeans.impl.schema;
 
+import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.QNameHelper;
-import org.apache.xmlbeans.impl.validator.ValidatingXMLInputStream;
-
 import org.apache.xmlbeans.impl.store.Locale;
-
-import org.apache.xmlbeans.SchemaAttributeGroup;
-import org.apache.xmlbeans.SchemaField;
-import org.apache.xmlbeans.SchemaGlobalAttribute;
-import org.apache.xmlbeans.SchemaGlobalElement;
-import org.apache.xmlbeans.SchemaModelGroup;
-import org.apache.xmlbeans.SchemaType;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlSaxHandler;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlFactoryHook;
-import org.apache.xmlbeans.XmlBeans;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.util.List;
-import java.util.ArrayList;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.HttpURLConnection;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.apache.xmlbeans.impl.validator.ValidatingXMLInputStream;
+import org.apache.xmlbeans.xml.stream.XMLInputStream;
+import org.apache.xmlbeans.xml.stream.XMLStreamException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Node;
 
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamReader;
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
 
-import org.w3c.dom.Node;
-import org.w3c.dom.DOMImplementation;
-
-import org.apache.xmlbeans.xml.stream.XMLInputStream;
-import org.apache.xmlbeans.xml.stream.XMLStreamException;
-
-public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader
-{
+public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader {
     private static final String USER_AGENT = "XMLBeans/" + XmlBeans.getVersion() + " (" + XmlBeans.getTitle() + ")";
 
-    private static final Method _pathCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "compilePath", new Class[] { String.class, XmlOptions.class } );
-    private static final Method _queryCompiler = getMethod( "org.apache.xmlbeans.impl.store.Query", "compileQuery", new Class[] { String.class, XmlOptions.class } );
+    private static final Method _pathCompiler = getMethod("org.apache.xmlbeans.impl.store.Path", "compilePath", new Class[]{String.class, XmlOptions.class});
+    private static final Method _queryCompiler = getMethod("org.apache.xmlbeans.impl.store.Query", "compileQuery", new Class[]{String.class, XmlOptions.class});
 
-    private static Method getMethod ( String className, String methodName, Class[] args )
-    {
-        try
-        {
+    private static Method getMethod(String className, String methodName, Class[] args) {
+        try {
             return
-                Class.forName( className ).
-                    getDeclaredMethod( methodName, args );
-        }
-        catch (Exception e)
-        {
+                Class.forName(className).
+                    getDeclaredMethod(methodName, args);
+        } catch (Exception e) {
             throw new IllegalStateException(
                 "Cannot find " + className + "." + methodName +
-                    ".  verify that xmlstore " +
-                        "(from xbean.jar) is on classpath" );
+                ".  verify that xmlstore " +
+                "(from xbean.jar) is on classpath");
         }
     }
 
-    private static Object invokeMethod ( Method method, Object[] args )
-    {
-        try
-        {
-            return method.invoke( method, args );
-        }
-        catch ( InvocationTargetException e )
-        {
+    private static Object invokeMethod(Method method, Object[] args) {
+        try {
+            return method.invoke(method, args);
+        } catch (InvocationTargetException e) {
             Throwable t = e.getCause();
-            IllegalStateException ise = new IllegalStateException( t.getMessage() );
-            ise.initCause( t ); // need initCause() to support Java1.4
-            throw ise;
-        }
-        catch ( Exception e )
-        {
-            IllegalStateException ise = new IllegalStateException( e.getMessage() );
-            ise.initCause( e );
-            throw ise;
+            throw new IllegalStateException(t.getMessage(), t);
+        } catch (Exception e) {
+            throw new IllegalStateException(e.getMessage(), e);
         }
     }
 
-    private static String doCompilePath ( String pathExpr, XmlOptions options )
-    {
-        return (String) invokeMethod( _pathCompiler, new Object[] { pathExpr, options } );
+    private static String doCompilePath(String pathExpr, XmlOptions options) {
+        return (String) invokeMethod(_pathCompiler, new Object[]{pathExpr, options});
     }
 
-    private static String doCompileQuery ( String queryExpr, XmlOptions options )
-    {
-        return (String) invokeMethod( _queryCompiler, new Object[] { queryExpr, options } );
+    private static String doCompileQuery(String queryExpr, XmlOptions options) {
+        return (String) invokeMethod(_queryCompiler, new Object[]{queryExpr, options});
     }
 
-    public SchemaType findType(QName name)
-    {
+    public SchemaType findType(QName name) {
         SchemaType.Ref ref = findTypeRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaType result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaType findDocumentType(QName name)
-    {
+    public SchemaType findDocumentType(QName name) {
         SchemaType.Ref ref = findDocumentTypeRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaType result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaType findAttributeType(QName name)
-    {
+    public SchemaType findAttributeType(QName name) {
         SchemaType.Ref ref = findAttributeTypeRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaType result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaModelGroup findModelGroup(QName name)
-    {
+    public SchemaModelGroup findModelGroup(QName name) {
         SchemaModelGroup.Ref ref = findModelGroupRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaModelGroup result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaAttributeGroup findAttributeGroup(QName name)
-    {
+    public SchemaAttributeGroup findAttributeGroup(QName name) {
         SchemaAttributeGroup.Ref ref = findAttributeGroupRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaAttributeGroup result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaGlobalElement findElement(QName name)
-    {
+    public SchemaGlobalElement findElement(QName name) {
         SchemaGlobalElement.Ref ref = findElementRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaGlobalElement result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
-    public SchemaGlobalAttribute findAttribute(QName name)
-    {
+    public SchemaGlobalAttribute findAttribute(QName name) {
         SchemaGlobalAttribute.Ref ref = findAttributeRef(name);
-        if (ref == null)
+        if (ref == null) {
             return null;
+        }
         SchemaGlobalAttribute result = ref.get();
-        assert(result != null);
+        assert (result != null);
         return result;
     }
 
@@ -188,264 +150,225 @@
     //
     //
 
-    public XmlObject newInstance ( SchemaType type, XmlOptions options )
-    {
+    public XmlObject newInstance(SchemaType type, XmlOptions options) {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.newInstance( this, type, options );
 
-        return Locale.newInstance( this, type, options );
+        if (hook != null) {
+            return hook.newInstance(this, type, options);
+        }
+
+        return Locale.newInstance(this, type, options);
     }
 
-    public XmlObject parse ( String xmlText, SchemaType type, XmlOptions options ) throws XmlException
-    {
+    public XmlObject parse(String xmlText, SchemaType type, XmlOptions options) throws XmlException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.parse( this, xmlText, type, options );
 
-        return Locale.parseToXmlObject( this, xmlText, type, options );
+        if (hook != null) {
+            return hook.parse(this, xmlText, type, options);
+        }
+
+        return Locale.parseToXmlObject(this, xmlText, type, options);
     }
 
     /**
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
-    public XmlObject parse ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
-    {
+    public XmlObject parse(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.parse( this, xis, type, options );
-        
-        return Locale.parseToXmlObject( this, xis, type, options );
+
+        if (hook != null) {
+            return hook.parse(this, xis, type, options);
+        }
+
+        return Locale.parseToXmlObject(this, xis, type, options);
     }
 
-    public XmlObject parse ( XMLStreamReader xsr, SchemaType type, XmlOptions options ) throws XmlException
-    {
+    public XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.parse( this, xsr, type, options );
 
-        return Locale.parseToXmlObject( this, xsr, type, options );
+        if (hook != null) {
+            return hook.parse(this, xsr, type, options);
+        }
+
+        return Locale.parseToXmlObject(this, xsr, type, options);
     }
-    
-    public XmlObject parse ( File file, SchemaType type, XmlOptions options ) throws XmlException, IOException
-    {
-        if (options == null)
-        {
+
+    public XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException {
+        String fileName = file.toURI().normalize().toString();
+        if (options == null) {
             options = new XmlOptions();
-            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() );
+            options.setDocumentSourceName(fileName);
+        } else if (options.getDocumentSourceName() == null) {
+            options = new XmlOptions(options);
+            options.setDocumentSourceName(fileName);
         }
 
-        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
-        {
-            options = new XmlOptions( options );
-            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() );
-        }
-
-        InputStream fis = new FileInputStream( file );
-
-        try
-        {
-            return parse( fis, type, options );
-        }
-        finally
-        {
-            fis.close();
+        try (InputStream fis = new FileInputStream(file)) {
+            return parse(fis, type, options);
         }
     }
 
-    public XmlObject parse ( URL url, SchemaType type, XmlOptions options ) throws XmlException, IOException
-    {
-        if (options == null)
-        {
+    public XmlObject parse(URL url, SchemaType type, XmlOptions options) throws XmlException, IOException {
+        if (options == null) {
             options = new XmlOptions();
-            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
+            options.setDocumentSourceName(url.toString());
+        } else if (options.getDocumentSourceName() == null) {
+            options = new XmlOptions(options);
+            options.setDocumentSourceName(url.toString());
         }
 
-        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
-        {
-            options = new XmlOptions( options );
-            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
-        }
 
-        URLConnection conn = null;
-        InputStream stream = null;
-        download: try
-        {
+        boolean redirected = false;
+        int count = 0;
+        URLConnection conn;
 
-            boolean redirected = false;
-            int count = 0;
+        do {
+            conn = url.openConnection();
+            conn.addRequestProperty("User-Agent", USER_AGENT);
+            conn.addRequestProperty("Accept", "application/xml, text/xml, */*");
+            if (conn instanceof HttpURLConnection) {
+                HttpURLConnection httpcon = (HttpURLConnection) conn;
+                int code = httpcon.getResponseCode();
+                redirected = (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP);
+                if (redirected && count > 5) {
+                    redirected = false;
+                }
 
-            do {
-                conn = url.openConnection();
-                conn.addRequestProperty("User-Agent", USER_AGENT);
-                conn.addRequestProperty("Accept", "application/xml, text/xml, */*");
-                if (conn instanceof HttpURLConnection)
-                {
-                    HttpURLConnection httpcon = (HttpURLConnection)conn;
-                    int code = httpcon.getResponseCode();
-                    redirected = (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP);
-                    if (redirected && count > 5)
+                if (redirected) {
+                    String newLocation = httpcon.getHeaderField("Location");
+                    if (newLocation == null) {
                         redirected = false;
-
-                    if (redirected)
-                    {
-                        String newLocation = httpcon.getHeaderField("Location");
-                        if (newLocation == null)
-                            redirected = false;
-                        else
-                        {
-                            url = new URL(newLocation);
-                            count ++;
-                        }
+                    } else {
+                        url = new URL(newLocation);
+                        count++;
                     }
                 }
-            } while (redirected);
+            }
+        } while (redirected);
 
-            stream = conn.getInputStream();
-            return parse( stream, type, options );
-        }
-        finally
-        {
-            if (stream != null)
-                stream.close();
+        try (InputStream stream = conn.getInputStream()) {
+            return parse(stream, type, options);
         }
     }
 
-    public XmlObject parse ( InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException
-    {
+    public XmlObject parse(InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
+
         DigestInputStream digestStream = null;
-        
+
         setupDigest:
-        if (options != null && options.hasOption( XmlOptions.LOAD_MESSAGE_DIGEST ))
-        {
+        if (options != null && options.isLoadMessageDigest()) {
             MessageDigest sha;
-            
-            try
-            {
+
+            try {
                 sha = MessageDigest.getInstance("SHA");
-            }
-            catch (NoSuchAlgorithmException e)
-            {
+            } catch (NoSuchAlgorithmException e) {
                 break setupDigest;
             }
 
-            digestStream = new DigestInputStream( jiois, sha );
+            digestStream = new DigestInputStream(jiois, sha);
             jiois = digestStream;
         }
 
-        if (hook != null)
-            return hook.parse( this, jiois, type, options );
+        if (hook != null) {
+            return hook.parse(this, jiois, type, options);
+        }
 
-        XmlObject result = Locale.parseToXmlObject( this, jiois, type, options );
+        XmlObject result = Locale.parseToXmlObject(this, jiois, type, options);
 
-        if (digestStream != null)
-            result.documentProperties().setMessageDigest( digestStream.getMessageDigest().digest() );
+        if (digestStream != null) {
+            result.documentProperties().setMessageDigest(digestStream.getMessageDigest().digest());
+        }
 
         return result;
     }
 
-    public XmlObject parse ( Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException
-    {
+    public XmlObject parse(Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.parse( this, jior, type, options );
 
-        return Locale.parseToXmlObject( this, jior, type, options );
+        if (hook != null) {
+            return hook.parse(this, jior, type, options);
+        }
+
+        return Locale.parseToXmlObject(this, jior, type, options);
     }
 
-    public XmlObject parse ( Node node, SchemaType type, XmlOptions options ) throws XmlException
-    {
+    public XmlObject parse(Node node, SchemaType type, XmlOptions options) throws XmlException {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.parse( this, node, type, options );
 
-        return Locale.parseToXmlObject( this, node, type, options );
+        if (hook != null) {
+            return hook.parse(this, node, type, options);
+        }
+
+        return Locale.parseToXmlObject(this, node, type, options);
     }
 
-    public XmlSaxHandler newXmlSaxHandler ( SchemaType type, XmlOptions options )
-    {
+    public XmlSaxHandler newXmlSaxHandler(SchemaType type, XmlOptions options) {
         XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
-        
-        if (hook != null)
-            return hook.newXmlSaxHandler( this, type, options );
 
-        return Locale.newSaxHandler( this, type, options );
+        if (hook != null) {
+            return hook.newXmlSaxHandler(this, type, options);
+        }
+
+        return Locale.newSaxHandler(this, type, options);
     }
 
-    public DOMImplementation newDomImplementation ( XmlOptions options )
-    {
-        return Locale.newDomImplementation( this, options );
+    public DOMImplementation newDomImplementation(XmlOptions options) {
+        return Locale.newDomImplementation(this, options);
     }
 
     /**
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
-    public XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
-    {
-        return new ValidatingXMLInputStream( xis, this, type, options );
+    public XMLInputStream newValidatingXMLInputStream(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException {
+        return new ValidatingXMLInputStream(xis, this, type, options);
     }
 
     //
     //
     //
 
-    public String compilePath ( String pathExpr )
-    {
-        return compilePath( pathExpr, null );
+    public String compilePath(String pathExpr) {
+        return compilePath(pathExpr, null);
     }
 
-    public String compilePath ( String pathExpr, XmlOptions options )
-    {
-        return doCompilePath( pathExpr, options );
+    public String compilePath(String pathExpr, XmlOptions options) {
+        return doCompilePath(pathExpr, options);
     }
 
-    public String compileQuery ( String queryExpr )
-    {
-        return compileQuery( queryExpr, null );
+    public String compileQuery(String queryExpr) {
+        return compileQuery(queryExpr, null);
     }
 
-    public String compileQuery ( String queryExpr, XmlOptions options )
-    {
-        return doCompileQuery( queryExpr, options );
+    public String compileQuery(String queryExpr, XmlOptions options) {
+        return doCompileQuery(queryExpr, options);
     }
 
     /**
      * Utility function to load a type from a signature.
-     *
+     * <p>
      * A signature is the string you get from type.toString().
      */
-    public SchemaType typeForSignature(String signature)
-    {
+    public SchemaType typeForSignature(String signature) {
         int end = signature.indexOf('@');
         String uri;
 
-        if (end < 0)
-        {
+        if (end < 0) {
             uri = "";
             end = signature.length();
-        }
-        else
-        {
+        } else {
             uri = signature.substring(end + 1);
         }
 
-        List parts = new ArrayList();
+        List<String> parts = new ArrayList<>();
 
-        for (int index = 0; index < end; )
-        {
+        for (int index = 0; index < end; ) {
             int nextc = signature.indexOf(':', index);
             int nextd = signature.indexOf('|', index);
-            int next = (nextc < 0 ? nextd : nextd < 0 ? nextc : nextc < nextd ? nextc : nextd);
-            if (next < 0 || next > end)
+            int next = (nextc < 0 ? nextd : nextd < 0 ? nextc : Math.min(nextc, nextd));
+            if (next < 0 || next > end) {
                 next = end;
+            }
             String part = signature.substring(index, next);
             parts.add(part);
             index = next + 1;
@@ -453,149 +376,143 @@
 
         SchemaType curType = null;
 
-        outer: for (int i = parts.size() - 1; i >= 0; i -= 1)
-        {
-            String part = (String)parts.get(i);
-            if (part.length() < 1)
+        for (int i = parts.size() - 1; i >= 0; i -= 1) {
+            String part = parts.get(i);
+            if (part.length() < 1) {
                 throw new IllegalArgumentException();
+            }
             int offset = (part.length() >= 2 && part.charAt(1) == '=') ? 2 : 1;
-            cases: switch (part.charAt(0))
-            {
+            cases:
+            switch (part.charAt(0)) {
                 case 'T':
-                    if (curType != null)
+                    if (curType != null) {
                         throw new IllegalArgumentException();
+                    }
                     curType = findType(QNameHelper.forLNS(part.substring(offset), uri));
-                    if (curType == null)
+                    if (curType == null) {
                         return null;
+                    }
                     break;
 
                 case 'D':
-                    if (curType != null)
+                    if (curType != null) {
                         throw new IllegalArgumentException();
+                    }
                     curType = findDocumentType(QNameHelper.forLNS(part.substring(offset), uri));
-                    if (curType == null)
+                    if (curType == null) {
                         return null;
+                    }
                     break;
 
                 case 'C': // deprecated
                 case 'R': // current
-                    if (curType != null)
+                    if (curType != null) {
                         throw new IllegalArgumentException();
+                    }
                     curType = findAttributeType(QNameHelper.forLNS(part.substring(offset), uri));
-                    if (curType == null)
+                    if (curType == null) {
                         return null;
+                    }
                     break;
 
                 case 'E':
                 case 'U': // distinguish qualified/unqualified TBD
-                    if (curType != null)
-                    {
-                        if (curType.getContentType() < SchemaType.ELEMENT_CONTENT)
+                    if (curType != null) {
+                        if (curType.getContentType() < SchemaType.ELEMENT_CONTENT) {
                             return null;
+                        }
                         SchemaType[] subTypes = curType.getAnonymousTypes();
                         String localName = part.substring(offset);
-                        for (int j = 0; j < subTypes.length; j++)
-                        {
-                            SchemaField field = subTypes[j].getContainerField();
-                            if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName))
-                            {
-                                curType = subTypes[j];
+                        for (SchemaType subType : subTypes) {
+                            SchemaField field = subType.getContainerField();
+                            if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName)) {
+                                curType = subType;
                                 break cases;
                             }
                         }
                         return null;
-                    }
-                    else
-                    {
+                    } else {
                         SchemaGlobalElement elt = findElement(QNameHelper.forLNS(part.substring(offset), uri));
-                        if (elt == null)
+                        if (elt == null) {
                             return null;
+                        }
                         curType = elt.getType();
                     }
                     break;
 
                 case 'A':
                 case 'Q': // distinguish qualified/unqualified TBD
-                    if (curType != null)
-                    {
-                        if (curType.isSimpleType())
+                    if (curType != null) {
+                        if (curType.isSimpleType()) {
                             return null;
+                        }
                         SchemaType[] subTypes = curType.getAnonymousTypes();
                         String localName = part.substring(offset);
-                        for (int j = 0; j < subTypes.length; j++)
-                        {
-                            SchemaField field = subTypes[j].getContainerField();
-                            if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName))
-                            {
-                                curType = subTypes[j];
+                        for (SchemaType subType : subTypes) {
+                            SchemaField field = subType.getContainerField();
+                            if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName)) {
+                                curType = subType;
                                 break cases;
                             }
                         }
                         return null;
-                    }
-                    else
-                    {
+                    } else {
                         SchemaGlobalAttribute attr = findAttribute(QNameHelper.forLNS(part.substring(offset), uri));
-                        if (attr == null)
+                        if (attr == null) {
                             return null;
+                        }
                         curType = attr.getType();
                     }
                     break;
 
                 case 'B':
-                    if (curType == null)
-                    {
+                    if (curType == null) {
                         throw new IllegalArgumentException();
-                    }
-                    else
-                    {
-                        if (curType.getSimpleVariety() != SchemaType.ATOMIC)
+                    } else {
+                        if (curType.getSimpleVariety() != SchemaType.ATOMIC) {
                             return null;
+                        }
                         SchemaType[] subTypes = curType.getAnonymousTypes();
-                        if (subTypes.length != 1)
+                        if (subTypes.length != 1) {
                             return null;
+                        }
                         curType = subTypes[0];
                     }
                     break;
 
                 case 'I':
-                    if (curType == null)
-                    {
+                    if (curType == null) {
                         throw new IllegalArgumentException();
-                    }
-                    else
-                    {
-                        if (curType.getSimpleVariety() != SchemaType.LIST)
+                    } else {
+                        if (curType.getSimpleVariety() != SchemaType.LIST) {
                             return null;
+                        }
                         SchemaType[] subTypes = curType.getAnonymousTypes();
-                        if (subTypes.length != 1)
+                        if (subTypes.length != 1) {
                             return null;
+                        }
                         curType = subTypes[0];
                     }
                     break;
 
                 case 'M':
-                    if (curType == null)
-                    {
+                    if (curType == null) {
                         throw new IllegalArgumentException();
-                    }
-                    else
-                    {
+                    } else {
                         int index;
-                        try
-                        {
+                        try {
                             index = Integer.parseInt(part.substring(offset));
-                        }
-                        catch (Exception e)
-                        {
+                        } catch (Exception e) {
                             throw new IllegalArgumentException();
                         }
 
-                        if (curType.getSimpleVariety() != SchemaType.UNION)
+                        if (curType.getSimpleVariety() != SchemaType.UNION) {
                             return null;
+                        }
                         SchemaType[] subTypes = curType.getAnonymousTypes();
-                        if (subTypes.length <= index)
+                        if (subTypes.length <= index) {
                             return null;
+                        }
                         curType = subTypes[index];
                     }
                     break;
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java
index eaaca47..a6673cd 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java
@@ -34,10 +34,10 @@
         private BindingConfig config;
         private SchemaTypeLoader linkTo;
         private XmlOptions options;
-        private Collection errorListener;
+        private Collection<XmlError> errorListener;
         private boolean javaize;
         private URI baseURI;
-        private Map sourcesToCopyMap;
+        private Map<String, String> sourcesToCopyMap;
         private File schemasDir;
 
         public SchemaTypeSystem getExistingTypeSystem() {
@@ -88,11 +88,11 @@
             this.options = options;
         }
 
-        public Collection getErrorListener() {
+        public Collection<XmlError> getErrorListener() {
             return errorListener;
         }
 
-        public void setErrorListener(Collection errorListener) {
+        public void setErrorListener(Collection<XmlError> errorListener) {
             this.errorListener = errorListener;
         }
 
@@ -112,11 +112,11 @@
             this.baseURI = baseURI;
         }
 
-        public Map getSourcesToCopyMap() {
+        public Map<String, String> getSourcesToCopyMap() {
             return sourcesToCopyMap;
         }
 
-        public void setSourcesToCopyMap(Map sourcesToCopyMap) {
+        public void setSourcesToCopyMap(Map<String, String> sourcesToCopyMap) {
             this.sourcesToCopyMap = sourcesToCopyMap;
         }
 
@@ -152,12 +152,12 @@
                                                XmlObject[] input, BindingConfig config, SchemaTypeLoader linkTo, Filer filer, XmlOptions options)
         throws XmlException {
         options = XmlOptions.maskNull(options);
-        ArrayList schemas = new ArrayList();
+        ArrayList<Schema> schemas = new ArrayList<>();
 
         if (input != null) {
             for (int i = 0; i < input.length; i++) {
                 if (input[i] instanceof Schema) {
-                    schemas.add(input[i]);
+                    schemas.add((Schema) input[i]);
                 } else if (input[i] instanceof SchemaDocument && ((SchemaDocument) input[i]).getSchema() != null) {
                     schemas.add(((SchemaDocument) input[i]).getSchema());
                 } else {
@@ -166,12 +166,12 @@
             }
         }
 
-        Collection userErrors = (Collection) options.get(XmlOptions.ERROR_LISTENER);
+        Collection<XmlError> userErrors = options.getErrorListener();
         XmlErrorWatcher errorWatcher = new XmlErrorWatcher(userErrors);
 
         SchemaTypeSystemImpl stsi = compileImpl(existingSTS, name,
-            (Schema[]) schemas.toArray(new Schema[schemas.size()]),
-            config, linkTo, options, errorWatcher, filer != null, (URI) options.get(XmlOptions.BASE_URI),
+            schemas.toArray(new Schema[0]),
+            config, linkTo, options, errorWatcher, filer != null, options.getBaseURI(),
             null, null);
 
         // if there is an error and compile didn't recover (stsi==null), throw exception
@@ -193,8 +193,8 @@
     /* package */
     static SchemaTypeSystemImpl compileImpl(SchemaTypeSystem system, String name,
                                             Schema[] schemas, BindingConfig config, SchemaTypeLoader linkTo,
-                                            XmlOptions options, Collection outsideErrors, boolean javaize,
-                                            URI baseURI, Map sourcesToCopyMap, File schemasDir) {
+                                            XmlOptions options, Collection<XmlError> outsideErrors, boolean javaize,
+                                            URI baseURI, Map<String, String> sourcesToCopyMap, File schemasDir) {
         if (linkTo == null) {
             throw new IllegalArgumentException("Must supply linkTo");
         }
@@ -204,7 +204,7 @@
 
         // construct the state
         StscState state = StscState.start();
-        boolean validate = (options == null || !options.hasOption(XmlOptions.COMPILE_NO_VALIDATION));
+        boolean validate = (options == null || !options.isCompileNoValidation());
         try {
             state.setErrorListener(errorWatcher);
             state.setBindingConfig(config);
@@ -219,27 +219,27 @@
             linkTo = SchemaTypeLoaderImpl.build(new SchemaTypeLoader[]{BuiltinSchemaTypeSystem.get(), linkTo}, null, null);
             state.setImportingTypeLoader(linkTo);
 
-            List validSchemas = new ArrayList(schemas.length);
+            List<Schema> validSchemas = new ArrayList<>(schemas.length);
 
             // load all the xsd files into it
             if (validate) {
                 XmlOptions validateOptions = new XmlOptions().setErrorListener(errorWatcher);
-                if (options.hasOption(XmlOptions.VALIDATE_TREAT_LAX_AS_SKIP)) {
+                if (options != null && options.isValidateTreatLaxAsSkip()) {
                     validateOptions.setValidateTreatLaxAsSkip();
                 }
-                for (int i = 0; i < schemas.length; i++) {
-                    if (schemas[i].validate(validateOptions)) {
-                        validSchemas.add(schemas[i]);
+                for (Schema schema : schemas) {
+                    if (schema.validate(validateOptions)) {
+                        validSchemas.add(schema);
                     }
                 }
             } else {
                 validSchemas.addAll(Arrays.asList(schemas));
             }
 
-            Schema[] startWith = (Schema[]) validSchemas.toArray(new Schema[validSchemas.size()]);
+            Schema[] startWith = validSchemas.toArray(new Schema[0]);
 
             if (incremental) {
-                Set namespaces = new HashSet();
+                Set<String> namespaces = new HashSet<>();
                 startWith = getSchemasToRecompile((SchemaTypeSystemImpl) system, startWith, namespaces);
                 state.initFromTypeSystem((SchemaTypeSystemImpl) system, namespaces);
             } else {
@@ -262,7 +262,7 @@
             StscJavaizer.javaizeAllTypes(javaize);
 
             // construct the loader out of the state
-            state.get().sts().loadFromStscState(state);
+            StscState.get().sts().loadFromStscState(state);
 
             // fill in the source-copy map
             if (sourcesToCopyMap != null) {
@@ -273,7 +273,7 @@
                 // EXPERIMENTAL: recovery from compilation errors and partial type system
                 if (state.allowPartial() && state.getRecovered() == errorWatcher.size()) {
                     // if partial type system allowed and all errors were recovered
-                    state.get().sts().setIncomplete(true);
+                    StscState.get().sts().setIncomplete(true);
                 } else {
                     // if any non-recoverable errors, return null
                     return null;
@@ -284,7 +284,7 @@
                 ((SchemaTypeSystemImpl) system).setIncomplete(true);
             }
 
-            return state.get().sts();
+            return StscState.get().sts();
         } finally {
             StscState.end();
         }
@@ -297,29 +297,28 @@
      * and of the entity resolvers that have been set up
      */
     private static Schema[] getSchemasToRecompile(SchemaTypeSystemImpl system,
-                                                  Schema[] modified, Set namespaces) {
-        Set modifiedFiles = new HashSet();
-        Map haveFile = new HashMap();
-        List result = new ArrayList();
-        for (int i = 0; i < modified.length; i++) {
-            String fileURL = modified[i].documentProperties().getSourceName();
+                                                  Schema[] modified, Set<String> namespaces) {
+        Set<String> modifiedFiles = new HashSet<>();
+        Map<String, SchemaDocument.Schema> haveFile = new HashMap<>();
+        List<SchemaDocument.Schema> result = new ArrayList<>();
+        for (Schema schema : modified) {
+            String fileURL = schema.documentProperties().getSourceName();
             if (fileURL == null) {
                 throw new IllegalArgumentException("One of the Schema files passed in" +
                                                    " doesn't have the source set, which prevents it to be incrementally" +
                                                    " compiled");
             }
             modifiedFiles.add(fileURL);
-            haveFile.put(fileURL, modified[i]);
-            result.add(modified[i]);
+            haveFile.put(fileURL, schema);
+            result.add(schema);
         }
         SchemaDependencies dep = system.getDependencies();
-        List nss = dep.getNamespacesTouched(modifiedFiles);
+        List<String> nss = dep.getNamespacesTouched(modifiedFiles);
         namespaces.addAll(dep.computeTransitiveClosure(nss));
-        List needRecompilation = dep.getFilesTouched(namespaces);
+        List<String> needRecompilation = dep.getFilesTouched(namespaces);
         StscState.get().setDependencies(new SchemaDependencies(dep, namespaces));
-        for (int i = 0; i < needRecompilation.size(); i++) {
-            String url = (String) needRecompilation.get(i);
-            Schema have = (Schema) haveFile.get(url);
+        for (String url : needRecompilation) {
+            Schema have = haveFile.get(url);
             if (have == null) {
                 // We have to load the file from the entity resolver
                 try {
@@ -337,17 +336,14 @@
                     result.add(sDoc.getSchema());
                 } catch (java.net.MalformedURLException mfe) {
                     StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[]{"MalformedURLException", url, mfe.getMessage()}, null);
-                    continue;
-                } catch (java.io.IOException ioe) {
+                } catch (IOException ioe) {
                     StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[]{"IOException", url, ioe.getMessage()}, null);
-                    continue;
                 } catch (XmlException xmle) {
                     StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[]{"XmlException", url, xmle.getMessage()}, null);
-                    continue;
                 }
             }
         }
-        return (Schema[]) result.toArray(new Schema[result.size()]);
+        return result.toArray(new Schema[0]);
     }
 
 
@@ -369,13 +365,12 @@
 
         boolean success = true;
 
-        List types = new ArrayList();
+        List<SchemaType> types = new ArrayList<>();
         types.addAll(Arrays.asList(system.globalTypes()));
         types.addAll(Arrays.asList(system.documentTypes()));
         types.addAll(Arrays.asList(system.attributeTypes()));
 
-        for (Iterator i = types.iterator(); i.hasNext(); ) {
-            SchemaType type = (SchemaType) i.next();
+        for (SchemaType type : types) {
             if (type.isBuiltinType()) {
                 continue;
             }
@@ -385,40 +380,22 @@
 
             String fjn = type.getFullJavaName();
 
-            Writer writer = null;
-
-            try {
+            try (Writer writer = filer.createSourceFile(fjn)) {
                 // Generate interface class
-                writer = filer.createSourceFile(fjn);
                 SchemaTypeCodePrinter.printType(writer, type, options);
             } catch (IOException e) {
                 System.err.println("IO Error " + e);
                 success = false;
-            } finally {
-                try {
-                    if (writer != null) {
-                        writer.close();
-                    }
-                } catch (IOException e) {
-                }
             }
 
-            try {
-                // Generate Implementation class
-                fjn = type.getFullJavaImplName();
-                writer = filer.createSourceFile(fjn);
+            fjn = type.getFullJavaImplName();
 
+            try (Writer writer = filer.createSourceFile(fjn)) {
+                // Generate Implementation class
                 SchemaTypeCodePrinter.printTypeImpl(writer, type, options);
             } catch (IOException e) {
                 System.err.println("IO Error " + e);
                 success = false;
-            } finally {
-                try {
-                    if (writer != null) {
-                        writer.close();
-                    }
-                } catch (IOException e) {
-                }
             }
         }
 
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscChecker.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscChecker.java
index 375f37f..9f056a7 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/StscChecker.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscChecker.java
@@ -28,17 +28,17 @@
         // walk the tree of types
         StscState state = StscState.get();
 
-        List allSeenTypes = new ArrayList();
+        List<SchemaType> allSeenTypes = new ArrayList<>();
         allSeenTypes.addAll(Arrays.asList(state.documentTypes()));
         allSeenTypes.addAll(Arrays.asList(state.attributeTypes()));
         allSeenTypes.addAll(Arrays.asList(state.redefinedGlobalTypes()));
         allSeenTypes.addAll(Arrays.asList(state.globalTypes()));
 
         for (int i = 0; i < allSeenTypes.size(); i++) {
-            SchemaType gType = (SchemaType) allSeenTypes.get(i);
-            if (!state.noPvr() &&  // option to turn off particle restriction checking
-                !gType.isDocumentType()) // Don't check doc types for restriction.
-            {
+            SchemaType gType = allSeenTypes.get(i);
+            // option to turn off particle restriction checking
+            // Don't check doc types for restriction.
+            if (!state.noPvr() && !gType.isDocumentType()) {
                 checkRestriction((SchemaTypeImpl) gType);
             }
             checkFields((SchemaTypeImpl) gType);
@@ -64,32 +64,32 @@
         if (sAttrModel != null) {
             SchemaLocalAttribute[] sAttrs = sAttrModel.getAttributes();
             QName idAttr = null;
-            for (int i = 0; i < sAttrs.length; i++) {
-                XmlObject attrLocation = ((SchemaLocalAttributeImpl) sAttrs[i])._parseObject;
-                if (XmlID.type.isAssignableFrom(sAttrs[i].getType())) {
+            for (SchemaLocalAttribute sAttr : sAttrs) {
+                XmlObject attrLocation = ((SchemaLocalAttributeImpl) sAttr)._parseObject;
+                if (XmlID.type.isAssignableFrom(sAttr.getType())) {
                     if (idAttr == null) {
-                        idAttr = sAttrs[i].getName();
+                        idAttr = sAttr.getName();
                     } else {
                         StscState.get().error(XmlErrorCodes.ATTR_GROUP_PROPERTIES$TWO_IDS,
-                            new Object[]{QNameHelper.pretty(idAttr), sAttrs[i].getName()},
+                            new Object[]{QNameHelper.pretty(idAttr), sAttr.getName()},
                             attrLocation != null ? attrLocation : location);
                     }
-                    if (sAttrs[i].getDefaultText() != null) {
+                    if (sAttr.getDefaultText() != null) {
                         StscState.get().error(XmlErrorCodes.ATTR_PROPERTIES$ID_FIXED_OR_DEFAULT,
                             null, attrLocation != null ? attrLocation : location);
                     }
-                } else if (XmlNOTATION.type.isAssignableFrom(sAttrs[i].getType())) {
-                    if (sAttrs[i].getType().getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
+                } else if (XmlNOTATION.type.isAssignableFrom(sAttr.getType())) {
+                    if (sAttr.getType().getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
                         StscState.get().recover(XmlErrorCodes.ATTR_NOTATION_TYPE_FORBIDDEN,
-                            new Object[]{QNameHelper.pretty(sAttrs[i].getName())},
+                            new Object[]{QNameHelper.pretty(sAttr.getName())},
                             attrLocation != null ? attrLocation : location);
                     } else {
-                        if (sAttrs[i].getType().getSimpleVariety() == SchemaType.UNION) {
-                            SchemaType[] members = sAttrs[i].getType().getUnionConstituentTypes();
-                            for (int j = 0; j < members.length; j++) {
-                                if (members[j].getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
+                        if (sAttr.getType().getSimpleVariety() == SchemaType.UNION) {
+                            SchemaType[] members = sAttr.getType().getUnionConstituentTypes();
+                            for (SchemaType member : members) {
+                                if (member.getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
                                     StscState.get().recover(XmlErrorCodes.ATTR_NOTATION_TYPE_FORBIDDEN,
-                                        new Object[]{QNameHelper.pretty(sAttrs[i].getName())},
+                                        new Object[]{QNameHelper.pretty(sAttr.getName())},
                                         attrLocation != null ? attrLocation : location);
                                 }
                             }
@@ -97,7 +97,7 @@
                         // Check that the Schema in which this is present doesn't have a targetNS
                         boolean hasNS;
                         if (sType.isAttributeType()) {
-                            hasNS = sAttrs[i].getName().getNamespaceURI().length() > 0;
+                            hasNS = sAttr.getName().getNamespaceURI().length() > 0;
                         } else {
                             SchemaType t = sType;
                             while (t.getOuterType() != null) {
@@ -111,26 +111,26 @@
                         }
                         if (hasNS) {
                             StscState.get().warning(XmlErrorCodes.ATTR_COMPATIBILITY_TARGETNS,
-                                new Object[]{QNameHelper.pretty(sAttrs[i].getName())},
+                                new Object[]{QNameHelper.pretty(sAttr.getName())},
                                 attrLocation != null ? attrLocation : location);
                         }
                     }
                 } else {
-                    String valueConstraint = sAttrs[i].getDefaultText();
+                    String valueConstraint = sAttr.getDefaultText();
                     if (valueConstraint != null) {
                         try {
-                            XmlAnySimpleType val = sAttrs[i].getDefaultValue();
+                            XmlAnySimpleType val = sAttr.getDefaultValue();
                             if (!val.validate()) {
                                 throw new Exception();
                             }
 
-                            SchemaPropertyImpl sProp = (SchemaPropertyImpl) sType.getAttributeProperty(sAttrs[i].getName());
+                            SchemaPropertyImpl sProp = (SchemaPropertyImpl) sType.getAttributeProperty(sAttr.getName());
                             if (sProp != null && sProp.getDefaultText() != null) {
                                 sProp.setDefaultValue(new XmlValueRef(val));
                             }
                         } catch (Exception e) {
                             // move to 'fixed' or 'default' attribute on the attribute definition
-                            String constraintName = (sAttrs[i].isFixed() ? "fixed" : "default");
+                            String constraintName = (sAttr.isFixed() ? "fixed" : "default");
                             XmlObject constraintLocation = location;
                             if (attrLocation != null) {
                                 constraintLocation = attrLocation.selectAttribute("", constraintName);
@@ -140,10 +140,10 @@
                             }
 
                             StscState.get().error(XmlErrorCodes.ATTR_PROPERTIES$CONSTRAINT_VALID,
-                                new Object[]{QNameHelper.pretty(sAttrs[i].getName()),
+                                new Object[]{QNameHelper.pretty(sAttr.getName()),
                                     constraintName,
                                     valueConstraint,
-                                    QNameHelper.pretty(sAttrs[i].getType().getName())},
+                                    QNameHelper.pretty(sAttr.getType().getName())},
                                 constraintLocation);
                         }
                     }
@@ -172,8 +172,8 @@
             case SchemaParticle.CHOICE:
             case SchemaParticle.ALL:
                 SchemaParticle[] children = model.getParticleChildren();
-                for (int i = 0; i < children.length; i++) {
-                    checkElementDefaults(children[i], location, parentType);
+                for (SchemaParticle child : children) {
+                    checkElementDefaults(child, location, parentType);
                 }
                 break;
             case SchemaParticle.ELEMENT:
@@ -183,7 +183,7 @@
                         try {
                             XmlAnySimpleType val = model.getDefaultValue();
                             XmlOptions opt = new XmlOptions();
-                            opt.put(XmlOptions.VALIDATE_TEXT_ONLY);
+                            opt.setValidateTextOnly();
                             if (!val.validate(opt)) {
                                 throw new Exception();
                             }
@@ -259,8 +259,8 @@
                     } else {
                         if (model.getType().getSimpleVariety() == SchemaType.UNION) {
                             SchemaType[] members = model.getType().getUnionConstituentTypes();
-                            for (int i = 0; i < members.length; i++) {
-                                if (members[i].getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
+                            for (SchemaType member : members) {
+                                if (member.getBuiltinTypeCode() == SchemaType.BTC_NOTATION) {
                                     StscState.get().recover(XmlErrorCodes.ELEM_NOTATION_TYPE_FORBIDDEN,
                                         new Object[]{QNameHelper.pretty(model.getName())},
                                         ((SchemaLocalElementImpl) model)._parseObject == null ? location :
@@ -593,11 +593,9 @@
         //  for match
         SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren();
         SchemaParticle[] baseParticleArray = baseModel.getParticleChildren();
-        for (int i = 0; i < derivedParticleArray.length; i++) {
-            SchemaParticle derivedParticle = derivedParticleArray[i];
+        for (SchemaParticle derivedParticle : derivedParticleArray) {
             boolean foundMatch = false;
-            for (int j = 0; j < baseParticleArray.length; j++) {
-                SchemaParticle baseParticle = baseParticleArray[j];
+            for (SchemaParticle baseParticle : baseParticleArray) {
                 // recurse to check if there is a match
                 if (isParticleValidRestriction(baseParticle, derivedParticle, errors, context)) {
                     // if there is a match then no need to check base particles anymore
@@ -618,9 +616,8 @@
 
         // Sum step
         BigInteger derivedRangeMin = derivedModel.getMinOccurs().multiply(BigInteger.valueOf(derivedModel.getParticleChildren().length));
-        BigInteger derivedRangeMax = null;
-        BigInteger UNBOUNDED = null;
-        if (derivedModel.getMaxOccurs() == UNBOUNDED) {
+        BigInteger derivedRangeMax;
+        if (derivedModel.getMaxOccurs() == null) {
             derivedRangeMax = null;
         } else {
             derivedRangeMax = derivedModel.getMaxOccurs().multiply(BigInteger.valueOf(derivedModel.getParticleChildren().length));
@@ -639,10 +636,10 @@
             errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MIN_OCCURS_GTE_MIN_OCCURS,
                 new Object[]{derivedRangeMin.toString(), baseModel.getMinOccurs().toString()},
                 context));
-        } else if (baseModel.getMaxOccurs() != UNBOUNDED && (derivedRangeMax == UNBOUNDED || derivedRangeMax.compareTo(baseModel.getMaxOccurs()) > 0)) {
+        } else if (baseModel.getMaxOccurs() != null && (derivedRangeMax == null || derivedRangeMax.compareTo(baseModel.getMaxOccurs()) > 0)) {
             mapAndSumValid = false;
             errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MAX_OCCURS_LTE_MAX_OCCURS,
-                new Object[]{derivedRangeMax == UNBOUNDED ? "unbounded" : derivedRangeMax.toString(), baseModel.getMaxOccurs().toString()},
+                new Object[]{derivedRangeMax == null ? "unbounded" : derivedRangeMax.toString(), baseModel.getMaxOccurs().toString()},
                 context));
         }
 
@@ -706,7 +703,7 @@
         SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren();
         SchemaParticle[] baseParticleArray = baseModel.getParticleChildren();
         int i = 0, j = 0;
-        for (; i < derivedParticleArray.length && j < baseParticleArray.length; ) {
+        while (i < derivedParticleArray.length && j < baseParticleArray.length) {
             SchemaParticle derivedParticle = derivedParticleArray[i];
             SchemaParticle baseParticle = baseParticleArray[j];
             // try to match the two particles by recursing
@@ -764,21 +761,21 @@
 
         // read baseParticle array QNames into hashmap
         SchemaParticle[] baseParticles = baseModel.getParticleChildren();
-        HashMap baseParticleMap = new HashMap(10);
-        Object MAPPED = new Object();
+        HashMap<QName, Object> baseParticleMap = new HashMap<>(10);
+        final Object MAPPED = new Object();
         // Initialize the hashmap
-        for (int i = 0; i < baseParticles.length; i++) {
-            baseParticleMap.put(baseParticles[i].getName(), baseParticles[i]);
+        for (SchemaParticle particle : baseParticles) {
+            baseParticleMap.put(particle.getName(), particle);
         }
 
         // go thru the sequence (derived model's children) and check off from base particle map
         SchemaParticle[] derivedParticles = derivedModel.getParticleChildren();
-        for (int i = 0; i < derivedParticles.length; i++) {
-            Object baseParticle = baseParticleMap.get(derivedParticles[i].getName());
+        for (SchemaParticle derivedParticle : derivedParticles) {
+            Object baseParticle = baseParticleMap.get(derivedParticle.getName());
             if (baseParticle == null) {
                 recurseUnorderedValid = false;
                 errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP,
-                    new Object[]{printParticle(derivedParticles[i])}, context));
+                    new Object[]{printParticle(derivedParticle)}, context));
                 break;
             } else {
                 // got a match
@@ -786,26 +783,26 @@
                     // whoa, this base particle has already been matched (see 2.1 above)
                     recurseUnorderedValid = false;
                     errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_UNIQUE,
-                        new Object[]{printParticle(derivedParticles[i])}, context));
+                        new Object[]{printParticle(derivedParticle)}, context));
                     break;
                 } else {
                     SchemaParticle matchedBaseParticle = (SchemaParticle) baseParticle;
-                    if (derivedParticles[i].getMaxOccurs() == null ||
-                        derivedParticles[i].getMaxOccurs().compareTo(BigInteger.ONE) > 0) {
+                    if (derivedParticle.getMaxOccurs() == null ||
+                        derivedParticle.getMaxOccurs().compareTo(BigInteger.ONE) > 0) {
                         // no derived particles can have a max occurs greater than 1
                         recurseUnorderedValid = false;
                         errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_MAX_OCCURS_1,
-                            new Object[]{printParticle(derivedParticles[i]), printMaxOccurs(derivedParticles[i].getMinOccurs())},
+                            new Object[]{printParticle(derivedParticle), printMaxOccurs(derivedParticle.getMinOccurs())},
                             context));
                         break;
                     }
-                    if (!isParticleValidRestriction(matchedBaseParticle, derivedParticles[i], errors, context)) {
+                    if (!isParticleValidRestriction(matchedBaseParticle, derivedParticle, errors, context)) {
                         // already have an error
                         recurseUnorderedValid = false;
                         break;
                     }
                     // everything is cool, got a match, update to MAPPED
-                    baseParticleMap.put(derivedParticles[i].getName(), MAPPED);
+                    baseParticleMap.put(derivedParticle.getName(), MAPPED);
                 }
             }
         }
@@ -813,9 +810,8 @@
         // if everything is cool so far then check to see if any base particles are not matched
         if (recurseUnorderedValid) {
             // get all the hashmap keys and loop thru looking for NOT_MAPPED
-            Set baseParticleCollection = baseParticleMap.keySet();
-            for (Iterator iterator = baseParticleCollection.iterator(); iterator.hasNext(); ) {
-                QName baseParticleQName = (QName) iterator.next();
+            Set<QName> baseParticleCollection = baseParticleMap.keySet();
+            for (QName baseParticleQName : baseParticleCollection) {
                 if (baseParticleMap.get(baseParticleQName) != MAPPED && !((SchemaParticle) baseParticleMap.get(baseParticleQName)).isSkippable()) {
                     // this base particle was not mapped and is not "particle emptiable" (skippable)
                     recurseUnorderedValid = false;
@@ -863,7 +859,7 @@
         SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren();
         SchemaParticle[] baseParticleArray = baseModel.getParticleChildren();
         int i = 0, j = 0;
-        for (; i < derivedParticleArray.length && j < baseParticleArray.length; ) {
+        while (i < derivedParticleArray.length && j < baseParticleArray.length) {
             SchemaParticle derivedParticle = derivedParticleArray[i];
             SchemaParticle baseParticle = baseParticleArray[j];
             // try to match the two particles by recursing
@@ -901,7 +897,7 @@
             // if at end of derived particle array and not at end of base particle array then chck remaining
             //  base particles to assure they are skippable
             if (j < baseParticleArray.length) {
-                ArrayList particles = new ArrayList(baseParticleArray.length);
+                ArrayList<SchemaParticle> particles = new ArrayList<>(baseParticleArray.length);
                 for (int k = j; k < baseParticleArray.length; k++) {
                     if (!baseParticleArray[k].isSkippable()) {
                         particles.add(baseParticleArray[k]);
@@ -948,8 +944,7 @@
         asIfPart.setTransitionNotes(baseModel.getWildcardSet(), true);
 
         SchemaParticle[] particleChildren = derivedModel.getParticleChildren();
-        for (int i = 0; i < particleChildren.length; i++) {
-            SchemaParticle particle = particleChildren[i];
+        for (SchemaParticle particle : particleChildren) {
             switch (particle.getParticleType()) {
                 case SchemaParticle.ELEMENT:
                     // Check for valid Wildcard/Element derivation
@@ -1011,9 +1006,8 @@
         // one of the following must be true:
         // The base model's {max occurs} is unbounded.
         // or both {max occurs} are numbers, and the particle's is less than or equal to the other's
-        BigInteger UNBOUNDED = null;
-        if (baseModel.getMaxOccurs() != UNBOUNDED) {
-            if (maxRange == UNBOUNDED) {
+        if (baseModel.getMaxOccurs() != null) {
+            if (maxRange == null) {
                 groupOccurrenceOK = false;
                 errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MAX_LTE_MAX,
                     new Object[]{printParticle(derivedModel), printParticle(baseModel)},
@@ -1032,7 +1026,6 @@
 
     private static BigInteger getEffectiveMaxRangeChoice(SchemaParticle derivedModel) {
         BigInteger maxRange = BigInteger.ZERO;
-        BigInteger UNBOUNDED = null;
         // Schema Component Constraint: Effective Total Range (choice)
         // The effective total range of a particle whose {term} is a group whose {compositor} is choice
         // is a pair of minimum and maximum, as follows:
@@ -1051,14 +1044,13 @@
         BigInteger maxOccursInWildCardOrElement = BigInteger.ZERO;
         BigInteger maxOccursInGroup = BigInteger.ZERO;
         SchemaParticle[] particleChildren = derivedModel.getParticleChildren();
-        for (int i = 0; i < particleChildren.length; i++) {
-            SchemaParticle particle = particleChildren[i];
+        for (SchemaParticle particle : particleChildren) {
             switch (particle.getParticleType()) {
                 case SchemaParticle.WILDCARD:
                 case SchemaParticle.ELEMENT:
                     // if unbounded then maxoccurs will be null
-                    if (particle.getMaxOccurs() == UNBOUNDED) {
-                        maxRange = UNBOUNDED;
+                    if (particle.getMaxOccurs() == null) {
+                        maxRange = null;
                     } else {
                         if (particle.getIntMaxOccurs() > 0) {
                             // show tht at least one non-zero particle is found for later test
@@ -1072,7 +1064,7 @@
                 case SchemaParticle.ALL:
                 case SchemaParticle.SEQUENCE:
                     maxRange = getEffectiveMaxRangeAllSeq(particle);
-                    if (maxRange != UNBOUNDED) {
+                    if (maxRange != null) {
                         // keep highest maxoccurs found
                         if (maxRange.compareTo(maxOccursInGroup) > 0) {
                             maxOccursInGroup = maxRange;
@@ -1081,7 +1073,7 @@
                     break;
                 case SchemaParticle.CHOICE:
                     maxRange = getEffectiveMaxRangeChoice(particle);
-                    if (maxRange != UNBOUNDED) {
+                    if (maxRange != null) {
                         // keep highest maxoccurs found
                         if (maxRange.compareTo(maxOccursInGroup) > 0) {
                             maxOccursInGroup = maxRange;
@@ -1090,7 +1082,7 @@
                     break;
             }
             // if an unbounded has been found then we are done
-            if (maxRange == UNBOUNDED) {
+            if (maxRange == null) {
                 break;
             }
         }
@@ -1098,10 +1090,10 @@
         // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or
         // the maximum part of the effective total range of any of the group particles in the group's {particles} is
         // unbounded
-        if (maxRange != UNBOUNDED) {
+        if (maxRange != null) {
             // 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded
-            if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == UNBOUNDED) {
-                maxRange = UNBOUNDED;
+            if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == null) {
+                maxRange = null;
             } else {
                 // 3) the product of the particle's {max occurs} and the maximum of the {max occurs} of every
                 // wildcard or element declaration particle in the group's {particles} and the *maximum*
@@ -1115,7 +1107,6 @@
 
     private static BigInteger getEffectiveMaxRangeAllSeq(SchemaParticle derivedModel) {
         BigInteger maxRange = BigInteger.ZERO;
-        BigInteger UNBOUNDED = null;
         // Schema Component Constraint: Effective Total Range (all and sequence)
         // The effective total range of a particle whose {term} is a group whose {compositor} is all or sequence is a
         // pair of minimum and maximum, as follows:
@@ -1131,14 +1122,13 @@
         BigInteger maxOccursTotal = BigInteger.ZERO;
         BigInteger maxOccursInGroup = BigInteger.ZERO;
         SchemaParticle[] particleChildren = derivedModel.getParticleChildren();
-        for (int i = 0; i < particleChildren.length; i++) {
-            SchemaParticle particle = particleChildren[i];
+        for (SchemaParticle particle : particleChildren) {
             switch (particle.getParticleType()) {
                 case SchemaParticle.WILDCARD:
                 case SchemaParticle.ELEMENT:
                     // if unbounded then maxoccurs will be null
-                    if (particle.getMaxOccurs() == UNBOUNDED) {
-                        maxRange = UNBOUNDED;
+                    if (particle.getMaxOccurs() == null) {
+                        maxRange = null;
                     } else {
                         if (particle.getIntMaxOccurs() > 0) {
                             // show tht at least one non-zero particle is found for later test
@@ -1150,7 +1140,7 @@
                 case SchemaParticle.ALL:
                 case SchemaParticle.SEQUENCE:
                     maxRange = getEffectiveMaxRangeAllSeq(particle);
-                    if (maxRange != UNBOUNDED) {
+                    if (maxRange != null) {
                         // keep highest maxoccurs found
                         if (maxRange.compareTo(maxOccursInGroup) > 0) {
                             maxOccursInGroup = maxRange;
@@ -1159,7 +1149,7 @@
                     break;
                 case SchemaParticle.CHOICE:
                     maxRange = getEffectiveMaxRangeChoice(particle);
-                    if (maxRange != UNBOUNDED) {
+                    if (maxRange != null) {
                         // keep highest maxoccurs found
                         if (maxRange.compareTo(maxOccursInGroup) > 0) {
                             maxOccursInGroup = maxRange;
@@ -1168,7 +1158,7 @@
                     break;
             }
             // if an unbounded has been found then we are done
-            if (maxRange == UNBOUNDED) {
+            if (maxRange == null) {
                 break;
             }
         }
@@ -1176,10 +1166,10 @@
         // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or
         // the maximum part of the effective total range of any of the group particles in the group's {particles} is
         // unbounded
-        if (maxRange != UNBOUNDED) {
+        if (maxRange != null) {
             // 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded
-            if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == UNBOUNDED) {
-                maxRange = UNBOUNDED;
+            if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == null) {
+                maxRange = null;
             } else {
                 // 3) the product of the particle's {max occurs} and the sum of the {max occurs} of every wildcard or element
                 // declaration particle in the group's {particles} and the maximum part of the effective total range of each of
@@ -1208,8 +1198,7 @@
         BigInteger minRange = null;
         // get the minimum of every wildcard or element
         // total up the effective total range for each group
-        for (int i = 0; i < particleChildren.length; i++) {
-            SchemaParticle particle = particleChildren[i];
+        for (SchemaParticle particle : particleChildren) {
             switch (particle.getParticleType()) {
                 case SchemaParticle.WILDCARD:
                 case SchemaParticle.ELEMENT:
@@ -1242,7 +1231,7 @@
     }
 
     private static BigInteger getEffectiveMinRangeAllSeq(SchemaParticle derivedModel) {
-        BigInteger minRange = BigInteger.ZERO;
+        BigInteger minRange;
         // Schema Component Constraint: Effective Total Range (all and sequence)
         // The effective total range of a particle whose {term} is a group whose {compositor} is all or sequence is a
         // pair of minimum and maximum, as follows:
@@ -1254,8 +1243,7 @@
         // of the group particles in the group's {particles} (or 0 if there are no {particles}).
         SchemaParticle[] particleChildren = derivedModel.getParticleChildren();
         BigInteger particleTotalMinOccurs = BigInteger.ZERO;
-        for (int i = 0; i < particleChildren.length; i++) {
-            SchemaParticle particle = particleChildren[i];
+        for (SchemaParticle particle : particleChildren) {
             switch (particle.getParticleType()) {
                 case SchemaParticle.WILDCARD:
                 case SchemaParticle.ELEMENT:
@@ -1280,7 +1268,7 @@
         // nsSubset is called when base: ANY, derived: ANY
         assert baseModel.getParticleType() == SchemaParticle.WILDCARD;
         assert derivedModel.getParticleType() == SchemaParticle.WILDCARD;
-        boolean nsSubset = false;
+        boolean nsSubset;
         // For a wildcard particle to be a �valid restriction� of another wildcard particle all of the following must be true:
         // 1 R's occurrence range must be a valid restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6).
         if (occurrenceRangeOK(baseModel, derivedModel, errors, context)) {
@@ -1306,7 +1294,7 @@
     private static boolean nsCompat(SchemaParticle baseModel, SchemaLocalElement derivedElement, Collection<XmlError> errors, XmlObject context) {
         // nsCompat is called when base: ANY, derived: ELEMENT
         assert baseModel.getParticleType() == SchemaParticle.WILDCARD;
-        boolean nsCompat = false;
+        boolean nsCompat;
         // For an element declaration particle to be a �valid restriction� of a wildcard particle all of the following must be true:
         // 1 The element declaration's {target namespace} is �valid� with respect to the wildcard's {namespace constraint}
         // as defined by Wildcard allows Namespace Name (�3.10.4).
@@ -1315,6 +1303,7 @@
             if (occurrenceRangeOK(baseModel, (SchemaParticle) derivedElement, errors, context)) {
                 nsCompat = true;
             } else {
+                nsCompat = false;
                 // error already produced by occurrenceRangeOK
                 //errors.add(XmlError.forObject(formatOccurenceRangeMinError(baseModel, (SchemaParticle) derivedElement), context));
             }
@@ -1374,12 +1363,7 @@
         }
 
         // 6 R's declaration's {disallowed substitutions} is a superset of B's declaration's {disallowed substitutions}.
-        if (!blockSetOK(baseElement, derivedElement, errors, context)) {
-            // error already produced
-            return false;
-        }
-
-        return true;
+        return blockSetOK(baseElement, derivedElement, errors, context);
     }
 
     private static boolean blockSetOK(SchemaLocalElement baseElement, SchemaLocalElement derivedElement, Collection<XmlError> errors, XmlObject context) {
@@ -1405,7 +1389,7 @@
     }
 
     private static boolean typeDerivationOK(SchemaType baseType, SchemaType derivedType, Collection<XmlError> errors, XmlObject context) {
-        boolean typeDerivationOK = false;
+        boolean typeDerivationOK;
         // 1 If B and D are not the same type definition, then the {derivation method} of D must not be in the subset.
         // 2 One of the following must be true:
         // 2.1 B and D must be the same type definition.
@@ -1435,9 +1419,9 @@
         SchemaType currentType = derivedType;
 
         // XMLBEANS-66: if baseType is a union, check restriction is of one of the constituant types
-        Set possibleTypes = null;
+        Set<SchemaType> possibleTypes = null;
         if (baseType.getSimpleVariety() == SchemaType.UNION) {
-            possibleTypes = new HashSet(Arrays.asList(baseType.getUnionConstituentTypes()));
+            possibleTypes = new HashSet<>(Arrays.asList(baseType.getUnionConstituentTypes()));
         }
 
         // run up the types hierarchy from derived Type to base Type and make sure that all are derived by
@@ -1463,8 +1447,7 @@
         SchemaIdentityConstraint[] baseConstraints = baseElement.getIdentityConstraints();
         SchemaIdentityConstraint[] derivedConstraints = derivedElement.getIdentityConstraints();
         // cycle thru derived's identity constraints and check each to assure they in the array of base constraints
-        for (int i = 0; i < derivedConstraints.length; i++) {
-            SchemaIdentityConstraint derivedConstraint = derivedConstraints[i];
+        for (SchemaIdentityConstraint derivedConstraint : derivedConstraints) {
             if (checkForIdentityConstraintExistence(baseConstraints, derivedConstraint)) {
                 identityConstraintsOK = false;
                 errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$IDENTITY_CONSTRAINTS,
@@ -1479,8 +1462,7 @@
     private static boolean checkForIdentityConstraintExistence(SchemaIdentityConstraint[] baseConstraints, SchemaIdentityConstraint derivedConstraint) {
         // spin thru the base identity constraints check to see if derived constraint exists
         boolean identityConstraintExists = false;
-        for (int i = 0; i < baseConstraints.length; i++) {
-            SchemaIdentityConstraint baseConstraint = baseConstraints[i];
+        for (SchemaIdentityConstraint baseConstraint : baseConstraints) {
             if (baseConstraint.getName().equals(derivedConstraint.getName())) {
                 identityConstraintExists = true;
                 break;
@@ -1493,7 +1475,7 @@
     private static boolean checkFixed(SchemaLocalElement baseModel, SchemaLocalElement derivedModel, Collection<XmlError> errors, XmlObject context) {
         // 4 either B's declaration's {value constraint} is absent, or is not fixed,
         // or R's declaration's {value constraint} is fixed with the same value.
-        boolean checkFixed = false;
+        boolean checkFixed;
         if (baseModel.isFixed()) {
             if (baseModel.getDefaultText().equals(derivedModel.getDefaultText())) {
                 //  R's declaration's {value constraint} is fixed with the same value.
@@ -1514,7 +1496,7 @@
     }
 
     private static boolean occurrenceRangeOK(SchemaParticle baseParticle, SchemaParticle derivedParticle, Collection<XmlError> errors, XmlObject context) {
-        boolean occurrenceRangeOK = false;
+        boolean occurrenceRangeOK;
         // Note: in the following comments (from the schema spec) other is the baseModel
         // 1 Its {min occurs} is greater than or equal to the other's {min occurs}.
         if (derivedParticle.getMinOccurs().compareTo(baseParticle.getMinOccurs()) >= 0) {
@@ -1545,8 +1527,8 @@
         return occurrenceRangeOK;
     }
 
-    private static String printParticles(List parts) {
-        return printParticles((SchemaParticle[]) parts.toArray(new SchemaParticle[parts.size()]));
+    private static String printParticles(List<SchemaParticle> parts) {
+        return printParticles(parts.toArray(new SchemaParticle[0]));
     }
 
     private static String printParticles(SchemaParticle[] parts) {
@@ -1602,8 +1584,7 @@
     private static void checkSubstitutionGroups(SchemaGlobalElement[] elts) {
         StscState state = StscState.get();
 
-        for (int i = 0; i < elts.length; i++) {
-            SchemaGlobalElement elt = elts[i];
+        for (SchemaGlobalElement elt : elts) {
             SchemaGlobalElement head = elt.substitutionGroup();
 
             if (head != null) {
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscImporter.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscImporter.java
index c47ba67..84d1933 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/StscImporter.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscImporter.java
@@ -15,69 +15,46 @@
 
 package org.apache.xmlbeans.impl.schema;
 
-import org.apache.xmlbeans.impl.xb.xsdschema.RedefineDocument.Redefine;
-import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema;
-import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.ImportDocument.Import;
-import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument.Include;
-
-import java.util.Map;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Arrays;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.InputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayReader;
-import java.io.Writer;
-import java.io.CharArrayWriter;
-import java.io.OutputStreamWriter;
-
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlErrorCodes;
+import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.IOUtil;
 import org.apache.xmlbeans.impl.common.XmlEncodingSniffer;
+import org.apache.xmlbeans.impl.xb.xsdschema.ImportDocument.Import;
+import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument.Include;
+import org.apache.xmlbeans.impl.xb.xsdschema.RedefineDocument.Redefine;
+import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
+import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
-public class StscImporter
-{
-    public static SchemaToProcess[] resolveImportsAndIncludes(Schema[] startWith, boolean forceSrcSave)
-    {
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+
+public class StscImporter {
+    public static SchemaToProcess[] resolveImportsAndIncludes(Schema[] startWith, boolean forceSrcSave) {
         DownloadTable engine = new DownloadTable(startWith);
         return engine.resolveImportsAndIncludes(forceSrcSave);
     }
 
-    public static class SchemaToProcess
-    {
-        private Schema schema;
-        private String chameleonNamespace;
-        private List includes; // list of SchemaToProcess objects directly included by this
-        private List redefines; // list of SchemaToProcess objects directly redefined by this
-        private List redefineObjects; // list of Redefine objects associated to each redefinition
-        private Set indirectIncludes; // set of SchemaToProcess  objects directly/indirectly included by this
-        private Set indirectIncludedBy; // set of SchemaToProcess objects that include this directly/indirectly
+    public static class SchemaToProcess {
+        private final Schema schema;
+        private final String chameleonNamespace;
+        // list of SchemaToProcess objects directly included by this
+        private List<SchemaToProcess> includes;
+        // list of SchemaToProcess objects directly redefined by this
+        private List<SchemaToProcess> redefines;
+        // list of Redefine objects associated to each redefinition
+        private List<Redefine> redefineObjects;
+        // set of SchemaToProcess  objects directly/indirectly included by this
+        private Set<SchemaToProcess> indirectIncludes;
+        // set of SchemaToProcess objects that include this directly/indirectly
+        private Set<SchemaToProcess> indirectIncludedBy;
 
-        public SchemaToProcess(Schema schema, String chameleonNamespace)
-        {
+        public SchemaToProcess(Schema schema, String chameleonNamespace) {
             this.schema = schema;
             this.chameleonNamespace = chameleonNamespace;
         }
@@ -85,26 +62,23 @@
         /**
          * The schema to parse.
          */
-        public Schema getSchema()
-        {
+        public Schema getSchema() {
             return schema;
         }
 
         /**
          * The base URI for this stp
          */
-        public String getSourceName()
-        {
+        public String getSourceName() {
             return schema.documentProperties().getSourceName();
         }
-        
+
         /**
          * The chameleon namespace. Null if this schema is not being treated
          * as a chameleon. (The ordinary targetNamespace will just be extracted
          * from the syntax of the schema.)
          */
-        public String getChameleonNamespace()
-        {
+        public String getChameleonNamespace() {
             return chameleonNamespace;
         }
 
@@ -113,108 +87,99 @@
          * directed graph of includes/redefines. This is required in order
          * to establish identity component by component, as required in
          * xmlschema-1, chapter 4.2.2
-         * @return
          */
-        public List getRedefines()
-        {
+        public List<SchemaToProcess> getRedefines() {
             return redefines;
         }
 
-        public List getRedefineObjects()
-        {
+        public List<Redefine> getRedefineObjects() {
             return redefineObjects;
         }
 
-        private void addInclude(SchemaToProcess include)
-        {
-            if (includes == null)
-                includes = new ArrayList();
+        private void addInclude(SchemaToProcess include) {
+            if (includes == null) {
+                includes = new ArrayList<>();
+            }
             includes.add(include);
         }
 
-        private void addRedefine(SchemaToProcess redefine, Redefine object)
-        {
-            if (redefines == null || redefineObjects == null)
-            {
-                redefines = new ArrayList();
-                redefineObjects = new ArrayList();
+        private void addRedefine(SchemaToProcess redefine, Redefine object) {
+            if (redefines == null || redefineObjects == null) {
+                redefines = new ArrayList<>();
+                redefineObjects = new ArrayList<>();
             }
             redefines.add(redefine);
             redefineObjects.add(object);
         }
 
-        private void buildIndirectReferences()
-        {
-            if (includes != null)
-                for (int i = 0; i < includes.size(); i++)
-                {
-                    SchemaToProcess schemaToProcess = (SchemaToProcess) includes.get(i);
+        private void buildIndirectReferences() {
+            if (includes != null) {
+                for (SchemaToProcess schemaToProcess : includes) {
                     /* We have a this-schemaToProcess vertex
-                    * This means that all nodes accessible from schemaToProcess are
-                    * also accessible from this and all nodes that have access to
-                    * this also have access to schemaToProcess */
+                     * This means that all nodes accessible from schemaToProcess are
+                     * also accessible from this and all nodes that have access to
+                     * this also have access to schemaToProcess */
                     this.addIndirectIncludes(schemaToProcess);
                 }
+            }
             // Repeat the same algorithm for redefines, since redefines are also includes
-            if (redefines != null)
-                for (int i = 0; i < redefines.size(); i++)
-                {
-                    SchemaToProcess schemaToProcess = (SchemaToProcess) redefines.get(i);
+            if (redefines != null) {
+                for (SchemaToProcess schemaToProcess : redefines) {
                     this.addIndirectIncludes(schemaToProcess);
                 }
+            }
         }
 
-        private void addIndirectIncludes(SchemaToProcess schemaToProcess)
-        {
-            if (indirectIncludes == null)
-                indirectIncludes = new HashSet();
+        private void addIndirectIncludes(SchemaToProcess schemaToProcess) {
+            if (indirectIncludes == null) {
+                indirectIncludes = new HashSet<>();
+            }
             indirectIncludes.add(schemaToProcess);
-            if (schemaToProcess.indirectIncludedBy == null)
-                schemaToProcess.indirectIncludedBy = new HashSet();
+            if (schemaToProcess.indirectIncludedBy == null) {
+                schemaToProcess.indirectIncludedBy = new HashSet<>();
+            }
             schemaToProcess.indirectIncludedBy.add(this);
             addIndirectIncludesHelper(this, schemaToProcess);
-            if (indirectIncludedBy != null)
-                for (Iterator it = indirectIncludedBy.iterator(); it.hasNext();)
-                {
-                    SchemaToProcess stp = (SchemaToProcess) it.next();
+            if (indirectIncludedBy != null) {
+                for (SchemaToProcess stp : indirectIncludedBy) {
                     stp.indirectIncludes.add(schemaToProcess);
                     schemaToProcess.indirectIncludedBy.add(stp);
                     addIndirectIncludesHelper(stp, schemaToProcess);
                 }
+            }
         }
 
         private static void addIndirectIncludesHelper(SchemaToProcess including,
-            SchemaToProcess schemaToProcess)
-        {
-            if (schemaToProcess.indirectIncludes != null)
-                for (Iterator it = schemaToProcess.indirectIncludes.iterator(); it.hasNext();)
-                {
-                    SchemaToProcess stp = (SchemaToProcess) it.next();
+                                                      SchemaToProcess schemaToProcess) {
+            if (schemaToProcess.indirectIncludes != null) {
+                for (SchemaToProcess stp : schemaToProcess.indirectIncludes) {
                     including.indirectIncludes.add(stp);
                     stp.indirectIncludedBy.add(including);
                 }
+            }
         }
 
-        public boolean indirectIncludes(SchemaToProcess schemaToProcess)
-        {
+        public boolean indirectIncludes(SchemaToProcess schemaToProcess) {
             return indirectIncludes != null && indirectIncludes.contains(schemaToProcess);
         }
 
-        public boolean equals(Object o)
-        {
-            if (this == o) return true;
-            if (!(o instanceof SchemaToProcess)) return false;
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof SchemaToProcess)) {
+                return false;
+            }
 
             final SchemaToProcess schemaToProcess = (SchemaToProcess) o;
 
-            if (chameleonNamespace != null ? !chameleonNamespace.equals(schemaToProcess.chameleonNamespace) : schemaToProcess.chameleonNamespace != null) return false;
-            if (!(schema == schemaToProcess.schema)) return false;
-
-            return true;
+            if (!Objects.equals(chameleonNamespace, schemaToProcess.chameleonNamespace)) {
+                return false;
+            }
+            return schema == schemaToProcess.schema;
         }
 
-        public int hashCode()
-        {
+        public int hashCode() {
             int result;
             result = schema.hashCode();
             result = 29 * result + (chameleonNamespace != null ? chameleonNamespace.hashCode() : 0);
@@ -224,43 +189,41 @@
 
     private final static String PROJECT_URL_PREFIX = "project://local";
 
-    private static String baseURLForDoc(XmlObject obj)
-    {
+    private static String baseURLForDoc(XmlObject obj) {
         String path = obj.documentProperties().getSourceName();
 
-        if (path == null)
+        if (path == null) {
             return null;
+        }
 
-        if (path.startsWith("/"))
+        if (path.startsWith("/")) {
             return PROJECT_URL_PREFIX + path.replace('\\', '/');
+        }
 
         // looks like a URL?
         int colon = path.indexOf(':');
-        if (colon > 1 && path.substring(0, colon).matches("^\\w+$"))
+        if (colon > 1 && path.substring(0, colon).matches("^\\w+$")) {
             return path;
+        }
 
         return PROJECT_URL_PREFIX + "/" + path.replace('\\', '/');
     }
 
-    private static URI parseURI(String s)
-    {
-        if (s == null)
+    private static URI parseURI(String s) {
+        if (s == null) {
             return null;
-
-        try
-        {
-            return new URI(s);
         }
-        catch (URISyntaxException syntax)
-        {
-                return null;
+
+        try {
+            return new URI(s);
+        } catch (URISyntaxException syntax) {
+            return null;
         }
     }
 
     //workaround for Sun bug # 4723726
     public static URI resolve(URI base, String child)
-        throws URISyntaxException
-    {
+        throws URISyntaxException {
         URI childUri = new URI(child);
         URI ruri = base.resolve(childUri);
 
@@ -270,22 +233,19 @@
         // to this ourselves to make sure that the nested jar url gets
         // resolved correctly
         if (childUri.equals(ruri) && !childUri.isAbsolute() &&
-          (base.getScheme().equals("jar") || base.getScheme().equals("zip"))) {
+            (base.getScheme().equals("jar") || base.getScheme().equals("zip"))) {
             String r = base.toString();
             int lastslash = r.lastIndexOf('/');
-            r = r.substring(0,lastslash) + "/" + childUri;
+            r = r.substring(0, lastslash) + "/" + childUri;
             // Sun's implementation of URI doesn't support references to the
             // parent directory ("/..") in the part after "!/" so we have to
             // remove these ourselves
             int exclPointSlashIndex = r.lastIndexOf("!/");
-            if (exclPointSlashIndex > 0)
-            {
+            if (exclPointSlashIndex > 0) {
                 int slashDotDotIndex = r.indexOf("/..", exclPointSlashIndex);
-                while (slashDotDotIndex > 0)
-                {
+                while (slashDotDotIndex > 0) {
                     int prevSlashIndex = r.lastIndexOf("/", slashDotDotIndex - 1);
-                    if (prevSlashIndex >= exclPointSlashIndex)
-                    {
+                    if (prevSlashIndex >= exclPointSlashIndex) {
                         String temp = r.substring(slashDotDotIndex + 3);
                         r = r.substring(0, prevSlashIndex).concat(temp);
                     }
@@ -296,39 +256,32 @@
         }
 
         //fix up normalization bug
-        if ("file".equals(ruri.getScheme()) && ! child.equals(ruri))
-        {
-            if (base.getPath().startsWith("//") && !ruri.getPath().startsWith("//"))
-            {
+        if ("file".equals(ruri.getScheme()) && !child.equals(ruri.getPath())) {
+            if (base.getPath().startsWith("//") && !ruri.getPath().startsWith("//")) {
                 String path = "///".concat(ruri.getPath());
-                try
-                {
+                try {
                     ruri = new URI("file", null, path, ruri.getQuery(), ruri.getFragment());
+                } catch (URISyntaxException ignored) {
                 }
-                catch(URISyntaxException uris)
-                {}
             }
         }
         return ruri;
     }
 
-    public static class DownloadTable
-    {
+    public static class DownloadTable {
         /**
          * Namespace/schemaLocation pair.
-         *
+         * <p>
          * Downloaded schemas are indexed by namespace, schemaLocation, and both.
-         *
+         * <p>
          * A perfect match is preferred, but a match-by-namespace is accepted.
          * A match-by-schemaLocation is only accepted for includes (not imports).
          */
-        private static class NsLocPair
-        {
-            private String namespaceURI;
-            private String locationURL;
+        private static class NsLocPair {
+            private final String namespaceURI;
+            private final String locationURL;
 
-            public NsLocPair(String namespaceURI, String locationURL)
-            {
+            public NsLocPair(String namespaceURI, String locationURL) {
                 this.namespaceURI = namespaceURI;
                 this.locationURL = locationURL;
             }
@@ -336,31 +289,31 @@
             /**
              * Empty string for no-namespace, null for namespace-not-part-of-key
              */
-            public String getNamespaceURI()
-            {
+            public String getNamespaceURI() {
                 return namespaceURI;
             }
 
-            public String getLocationURL()
-            {
+            public String getLocationURL() {
                 return locationURL;
             }
 
-            public boolean equals(Object o)
-            {
-                if (this == o) return true;
-                if (!(o instanceof NsLocPair)) return false;
+            public boolean equals(Object o) {
+                if (this == o) {
+                    return true;
+                }
+                if (!(o instanceof NsLocPair)) {
+                    return false;
+                }
 
                 final NsLocPair nsLocPair = (NsLocPair) o;
 
-                if (locationURL != null ? !locationURL.equals(nsLocPair.locationURL) : nsLocPair.locationURL != null) return false;
-                if (namespaceURI != null ? !namespaceURI.equals(nsLocPair.namespaceURI) : nsLocPair.namespaceURI != null) return false;
-
-                return true;
+                if (!Objects.equals(locationURL, nsLocPair.locationURL)) {
+                    return false;
+                }
+                return Objects.equals(namespaceURI, nsLocPair.namespaceURI);
             }
 
-            public int hashCode()
-            {
+            public int hashCode() {
                 int result;
                 result = (namespaceURI != null ? namespaceURI.hashCode() : 0);
                 result = 29 * result + (locationURL != null ? locationURL.hashCode() : 0);
@@ -368,71 +321,69 @@
             }
         }
 
-        private static class DigestKey
-        {
+        private static class DigestKey {
             byte[] _digest;
             int _hashCode;
-            DigestKey(byte[] digest)
-            {
+
+            DigestKey(byte[] digest) {
                 _digest = digest;
-                for (int i = 0; i < 4 && i < digest.length; i++)
-                {
+                for (int i = 0; i < 4 && i < digest.length; i++) {
                     _hashCode = _hashCode << 8;
                     _hashCode = _hashCode + digest[i];
                 }
             }
 
-            public boolean equals(Object o)
-            {
-                if (this == o) return true;
-                if (!(o instanceof DigestKey)) return false;
-                return Arrays.equals(_digest, ((DigestKey)o)._digest);
+            public boolean equals(Object o) {
+                if (this == o) {
+                    return true;
+                }
+                if (!(o instanceof DigestKey)) {
+                    return false;
+                }
+                return Arrays.equals(_digest, ((DigestKey) o)._digest);
             }
 
-            public int hashCode()
-            {
+            public int hashCode() {
                 return _hashCode;
             }
         }
 
-        private Map schemaByNsLocPair = new HashMap();
-        private Map schemaByDigestKey = new HashMap();
-        private LinkedList scanNeeded = new LinkedList();
-        private Set emptyNamespaceSchemas = new HashSet();
-        private Map scannedAlready = new HashMap();
-        private Set failedDownloads = new HashSet();
+        private final Map<NsLocPair, Schema> schemaByNsLocPair = new HashMap<>();
+        private final Map<DigestKey, Schema> schemaByDigestKey = new HashMap<>();
+        private final LinkedList<SchemaToProcess> scanNeeded = new LinkedList<>();
+        private final Set<Schema> emptyNamespaceSchemas = new HashSet<>();
+        private final Map<SchemaToProcess, SchemaToProcess> scannedAlready = new HashMap<>();
+        private final Set<String> failedDownloads = new HashSet<>();
 
-        private Schema downloadSchema(XmlObject referencedBy, String targetNamespace, String locationURL)
-        {
+        private Schema downloadSchema(XmlObject referencedBy, String targetNamespace, String locationURL) {
             // no location URL provided?  Then nothing to do.
-            if (locationURL == null)
+            if (locationURL == null) {
                 return null;
-            
+            }
+
             StscState state = StscState.get();
-            
+
             // First resolve relative URLs with respect to base URL for doc
             URI baseURI = parseURI(baseURLForDoc(referencedBy));
-            String absoluteURL = null;
-            try
-            {
+            String absoluteURL;
+            try {
                 absoluteURL = baseURI == null ? locationURL : resolve(baseURI, locationURL).toString();
-            }
-            catch (URISyntaxException e)
-            {
+            } catch (URISyntaxException e) {
                 state.error("Could not find resource - invalid location URL: " + e.getMessage(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
                 return null;
             }
 
             // probe 0: this url is already processed, from a previous compile
-            if (state.isFileProcessed(absoluteURL))
+            if (state.isFileProcessed(absoluteURL)) {
                 return null;
+            }
 
             // probe 1: ns+url - perfect match
-            if (absoluteURL != null && targetNamespace != null)
-            {
-                Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(targetNamespace, absoluteURL));
-                if (result != null)
+            if (absoluteURL != null && targetNamespace != null) {
+                Schema result = schemaByNsLocPair.get(new NsLocPair(targetNamespace, absoluteURL));
+                if (result != null) {
                     return result;
+                }
             }
 
             // probe 2: we have preexisting knowledge of this namespace,
@@ -444,80 +395,74 @@
             // (We never assume preexisting knowledge of the no-namespace,
             // even if we have some definitions, since it's likely that
             // more than one person is playing in the no-namespace at once.)
-            if (targetNamespace != null && !targetNamespace.equals(""))
-            {
+            if (targetNamespace != null && !targetNamespace.equals("")) {
                 // the URL is not one to download; should we assume we know about the namespace?
-                if (!state.shouldDownloadURI(absoluteURL))
-                {
+                if (!state.shouldDownloadURI(absoluteURL)) {
                     // If we already have a schema representing this namespace,
                     // then skip this URL silently without producing an error.
-                    Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(targetNamespace, null));
-                    if (result != null)
+                    Schema result = schemaByNsLocPair.get(new NsLocPair(targetNamespace, null));
+                    if (result != null) {
                         return result;
+                    }
                 }
 
                 // If the linker already knows about this namespace, skip
                 // this URL.
-                if (state.linkerDefinesNamespace(targetNamespace))
+                if (state.linkerDefinesNamespace(targetNamespace)) {
                     return null;
+                }
             }
 
             // probe 3: url only
-            if (absoluteURL != null)
-            {
-                Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(null, absoluteURL));
-                if (result != null)
+            if (absoluteURL != null) {
+                Schema result = schemaByNsLocPair.get(new NsLocPair(null, absoluteURL));
+                if (result != null) {
                     return result;
+                }
             }
 
             // no match: error if we can't or won't download.
-            if (absoluteURL == null)
-            {
+            if (absoluteURL == null) {
                 state.error("Could not find resource - no valid location URL.", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
                 return null;
             }
 
-            if (previouslyFailedToDownload(absoluteURL))
-            {
+            if (previouslyFailedToDownload(absoluteURL)) {
                 // an error message has already been produced.
                 return null;
             }
 
-            if (!state.shouldDownloadURI(absoluteURL))
-            {
+            if (!state.shouldDownloadURI(absoluteURL)) {
                 state.error("Could not load resource \"" + absoluteURL + "\" (network downloads disabled).", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
                 addFailedDownload(absoluteURL);
                 return null;
             }
 
             // try to download
-            download: try
-            {
+            download:
+            try {
                 XmlObject xdoc = downloadDocument(state.getS4SLoader(), targetNamespace, absoluteURL);
 
                 Schema result = findMatchByDigest(xdoc);
                 String shortname = state.relativize(absoluteURL);
-                if (result != null)
-                {
+                if (result != null) {
                     // if an exactly-the-same document has already been loaded, use the original and spew
                     String dupname = state.relativize(result.documentProperties().getSourceName());
-                    if (dupname != null)
+                    if (dupname != null) {
                         state.info(shortname + " is the same as " + dupname + " (ignoring the duplicate file)");
-                    else
+                    } else {
                         state.info(shortname + " is the same as another schema");
-                }
-                else
-                {
+                    }
+                } else {
                     // otherwise, it's a new document: validate it and grab the contents
                     XmlOptions voptions = new XmlOptions();
                     voptions.setErrorListener(state.getErrorListener());
-                    if (!(xdoc instanceof SchemaDocument) || !xdoc.validate(voptions))
-                    {
+                    if (!(xdoc instanceof SchemaDocument) || !xdoc.validate(voptions)) {
                         state.error("Referenced document is not a valid schema", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
                         break download;
                     }
 
-                    SchemaDocument sDoc = (SchemaDocument)xdoc;
+                    SchemaDocument sDoc = (SchemaDocument) xdoc;
 
                     result = sDoc.getSchema();
                     state.info("Loading referenced file " + shortname);
@@ -525,17 +470,11 @@
                 NsLocPair key = new NsLocPair(emptyStringIfNull(result.getTargetNamespace()), absoluteURL);
                 addSuccessfulDownload(key, result);
                 return result;
-            }
-            catch (MalformedURLException malformed)
-            {
+            } catch (MalformedURLException malformed) {
                 state.error("URL \"" + absoluteURL + "\" is not well-formed", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
-            }
-            catch (IOException connectionProblem)
-            {
+            } catch (IOException connectionProblem) {
                 state.error(connectionProblem.toString(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
-            }
-            catch (XmlException e)
-            {
+            } catch (XmlException e) {
                 state.error("Problem parsing referenced XML resource - " + e.getMessage(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy);
             }
 
@@ -543,59 +482,53 @@
             addFailedDownload(absoluteURL);
             return null;
         }
-        
+
         static XmlObject downloadDocument(SchemaTypeLoader loader, String namespace, String absoluteURL)
-                throws MalformedURLException, IOException, XmlException
-        {
+            throws IOException, XmlException {
             StscState state = StscState.get();
-            
+
             EntityResolver resolver = state.getEntityResolver();
-            if (resolver != null)
-            {
-                InputSource source = null;
-                try
-                {
+            if (resolver != null) {
+                InputSource source;
+                try {
                     source = resolver.resolveEntity(namespace, absoluteURL);
-                }
-                catch (SAXException e)
-                {
+                } catch (SAXException e) {
                     throw new XmlException(e);
                 }
 
-                if (source != null)
-                {
+                if (source != null) {
                     state.addSourceUri(absoluteURL, null);
 
                     // first preference for InputSource contract: character stream
                     Reader reader = source.getCharacterStream();
-                    if (reader != null)
-                    {
+                    if (reader != null) {
                         reader = copySchemaSource(absoluteURL, reader, state);
                         XmlOptions options = new XmlOptions();
                         options.setLoadLineNumbers();
                         options.setDocumentSourceName(absoluteURL);
                         return loader.parse(reader, null, options);
                     }
-                
-                    // second preference for InputSource contract: 
+
+                    // second preference for InputSource contract:
                     InputStream bytes = source.getByteStream();
-                    if (bytes != null)
-                    {
+                    if (bytes != null) {
                         bytes = copySchemaSource(absoluteURL, bytes, state);
                         String encoding = source.getEncoding();
                         XmlOptions options = new XmlOptions();
                         options.setLoadLineNumbers();
                         options.setLoadMessageDigest();
                         options.setDocumentSourceName(absoluteURL);
-                        if (encoding != null)
+                        if (encoding != null) {
                             options.setCharacterEncoding(encoding);
+                        }
                         return loader.parse(bytes, null, options);
                     }
-                
+
                     // third preference: use the (possibly redirected) url
                     String urlToLoad = source.getSystemId();
-                    if (urlToLoad == null)
+                    if (urlToLoad == null) {
                         throw new IOException("EntityResolver unable to resolve " + absoluteURL + " (for namespace " + namespace + ")");
+                    }
 
                     copySchemaSource(absoluteURL, state, false);
                     XmlOptions options = new XmlOptions();
@@ -619,18 +552,13 @@
             return loader.parse(urlDownload, null, options);
         }
 
-        private void addSuccessfulDownload(NsLocPair key, Schema schema)
-        {
+        private void addSuccessfulDownload(NsLocPair key, Schema schema) {
             byte[] digest = schema.documentProperties().getMessageDigest();
-            if (digest == null)
-            {
+            if (digest == null) {
                 StscState.get().addSchemaDigest(null);
-            }
-            else
-            {
+            } else {
                 DigestKey dk = new DigestKey(digest);
-                if (!schemaByDigestKey.containsKey(dk))
-                {
+                if (!schemaByDigestKey.containsKey(dk)) {
                     schemaByDigestKey.put(new DigestKey(digest), schema);
                     StscState.get().addSchemaDigest(digest);
                 }
@@ -638,77 +566,72 @@
 
             schemaByNsLocPair.put(key, schema);
             NsLocPair key1 = new NsLocPair(key.getNamespaceURI(), null);
-            if (!schemaByNsLocPair.containsKey(key1))
+            if (!schemaByNsLocPair.containsKey(key1)) {
                 schemaByNsLocPair.put(key1, schema);
+            }
             NsLocPair key2 = new NsLocPair(null, key.getLocationURL());
-            if (!schemaByNsLocPair.containsKey(key2))
+            if (!schemaByNsLocPair.containsKey(key2)) {
                 schemaByNsLocPair.put(key2, schema);
+            }
         }
 
-        private Schema findMatchByDigest(XmlObject original)
-        {
+        private Schema findMatchByDigest(XmlObject original) {
             byte[] digest = original.documentProperties().getMessageDigest();
-            if (digest == null)
+            if (digest == null) {
                 return null;
-            return (Schema)schemaByDigestKey.get(new DigestKey(digest));
+            }
+            return schemaByDigestKey.get(new DigestKey(digest));
         }
 
-        private void addFailedDownload(String locationURL)
-        {
+        private void addFailedDownload(String locationURL) {
             failedDownloads.add(locationURL);
         }
 
-        private boolean previouslyFailedToDownload(String locationURL)
-        {
+        private boolean previouslyFailedToDownload(String locationURL) {
             return failedDownloads.contains(locationURL);
         }
 
-        private static boolean nullableStringsMatch(String s1, String s2)
-        {
-            if (s1 == null && s2 == null)
+        private static boolean nullableStringsMatch(String s1, String s2) {
+            if (s1 == null && s2 == null) {
                 return true;
-            if (s1 == null || s2 == null)
+            }
+            if (s1 == null || s2 == null) {
                 return false;
+            }
             return (s1.equals(s2));
         }
 
-        private static String emptyStringIfNull(String s)
-        {
-            if (s == null)
+        private static String emptyStringIfNull(String s) {
+            if (s == null) {
                 return "";
+            }
             return s;
         }
 
-        private SchemaToProcess addScanNeeded(SchemaToProcess stp)
-        {
-            if (!scannedAlready.containsKey(stp))
-            {
+        private SchemaToProcess addScanNeeded(SchemaToProcess stp) {
+            if (!scannedAlready.containsKey(stp)) {
                 scannedAlready.put(stp, stp);
                 scanNeeded.add(stp);
                 return stp;
+            } else {
+                return scannedAlready.get(stp);
             }
-            else
-                return (SchemaToProcess) scannedAlready.get(stp);
         }
 
-        private void addEmptyNamespaceSchema(Schema s)
-        {
+        private void addEmptyNamespaceSchema(Schema s) {
             emptyNamespaceSchemas.add(s);
         }
 
-        private void usedEmptyNamespaceSchema(Schema s)
-        {
+        private void usedEmptyNamespaceSchema(Schema s) {
             emptyNamespaceSchemas.remove(s);
         }
 
-        private boolean fetchRemainingEmptyNamespaceSchemas()
-        {
-            if (emptyNamespaceSchemas.isEmpty())
+        private boolean fetchRemainingEmptyNamespaceSchemas() {
+            if (emptyNamespaceSchemas.isEmpty()) {
                 return false;
+            }
 
-            for (Iterator i = emptyNamespaceSchemas.iterator(); i.hasNext();)
-            {
-                Schema schema = (Schema)i.next();
+            for (Schema schema : emptyNamespaceSchemas) {
                 addScanNeeded(new SchemaToProcess(schema, null));
             }
 
@@ -716,35 +639,30 @@
             return true;
         }
 
-        private boolean hasNextToScan()
-        {
+        private boolean hasNextToScan() {
             return !scanNeeded.isEmpty();
         }
 
-        private SchemaToProcess nextToScan()
-        {
-            SchemaToProcess next = (SchemaToProcess)scanNeeded.removeFirst();
-            return next;
+        private SchemaToProcess nextToScan() {
+            return scanNeeded.removeFirst();
         }
 
-        public DownloadTable(Schema[] startWith)
-        {
-            for (int i = 0; i < startWith.length; i++)
-            {
-                String targetNamespace = startWith[i].getTargetNamespace();
-                NsLocPair key = new NsLocPair(targetNamespace, baseURLForDoc(startWith[i]));
-                addSuccessfulDownload(key, startWith[i]);
-                if (targetNamespace != null)
-                    addScanNeeded(new SchemaToProcess(startWith[i], null));
-                else
-                    addEmptyNamespaceSchema(startWith[i]);
+        public DownloadTable(Schema[] startWith) {
+            for (Schema schema : startWith) {
+                String targetNamespace = schema.getTargetNamespace();
+                NsLocPair key = new NsLocPair(targetNamespace, baseURLForDoc(schema));
+                addSuccessfulDownload(key, schema);
+                if (targetNamespace != null) {
+                    addScanNeeded(new SchemaToProcess(schema, null));
+                } else {
+                    addEmptyNamespaceSchema(schema);
+                }
             }
         }
 
-        public SchemaToProcess[] resolveImportsAndIncludes(boolean forceSave)
-        {
+        public SchemaToProcess[] resolveImportsAndIncludes(boolean forceSave) {
             StscState state = StscState.get();
-            List result = new ArrayList();
+            List<SchemaToProcess> result = new ArrayList<>();
             boolean hasRedefinitions = false;
 
             // algorithm is to scan through each schema document and
@@ -756,10 +674,8 @@
             // empty empty-namespace schemas that have NOT been chameleon-
             // included by other schemas and process them.
 
-            for (;;)
-            {
-                while (hasNextToScan())
-                {
+            do {
+                while (hasNextToScan()) {
                     SchemaToProcess stp = nextToScan();
                     String uri = stp.getSourceName();
                     state.addSourceUri(uri, null);
@@ -769,52 +685,45 @@
                     {
                         // handle imports
                         Import[] imports = stp.getSchema().getImportArray();
-                        for (int i = 0; i < imports.length; i++)
-                        {
-                            Schema imported = downloadSchema(imports[i], emptyStringIfNull(imports[i].getNamespace()), imports[i].getSchemaLocation());
+                        for (Import anImport : imports) {
+                            Schema imported = downloadSchema(anImport, emptyStringIfNull(anImport.getNamespace()), anImport.getSchemaLocation());
 
                             // if download fails, an error has already been reported.
-                            if (imported == null)
+                            if (imported == null) {
                                 continue;
-    
-                            if (!nullableStringsMatch(imported.getTargetNamespace(), imports[i].getNamespace()))
-                            {
-                                StscState.get().error("Imported schema has a target namespace \"" + imported.getTargetNamespace() + "\" that does not match the specified \"" + imports[i].getNamespace() + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, imports[i]);
                             }
-                            else
-                            {
+
+                            if (!nullableStringsMatch(imported.getTargetNamespace(), anImport.getNamespace())) {
+                                StscState.get().error("Imported schema has a target namespace \"" + imported.getTargetNamespace() + "\" that does not match the specified \"" + anImport.getNamespace() + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, anImport);
+                            } else {
                                 addScanNeeded(new SchemaToProcess(imported, null));
                             }
                         }
                     }
-                    
+
                     {
                         // handle includes
                         Include[] includes = stp.getSchema().getIncludeArray();
                         String sourceNamespace = stp.getChameleonNamespace();
-                        if (sourceNamespace == null)
+                        if (sourceNamespace == null) {
                             sourceNamespace = emptyStringIfNull(stp.getSchema().getTargetNamespace());
-    
-                        for (int i = 0; i < includes.length; i++)
-                        {
-                            Schema included = downloadSchema(includes[i], null, includes[i].getSchemaLocation());
+                        }
+
+                        for (Include include : includes) {
+                            Schema included = downloadSchema(include, null, include.getSchemaLocation());
                             // if download fails, an error has already been reported.
-                            if (included == null)
+                            if (included == null) {
                                 continue;
-    
-                            if (emptyStringIfNull(included.getTargetNamespace()).equals(sourceNamespace))
-                            {
+                            }
+
+                            if (emptyStringIfNull(included.getTargetNamespace()).equals(sourceNamespace)) {
                                 // non-chameleon case - just like an import
                                 SchemaToProcess s = addScanNeeded(new SchemaToProcess(included, null));
                                 stp.addInclude(s);
-                            }
-                            else if (included.getTargetNamespace() != null)
-                            {
+                            } else if (included.getTargetNamespace() != null) {
                                 // illegal include: included schema in wrong namespace.
-                                StscState.get().error("Included schema has a target namespace \"" + included.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, includes[i]);
-                            }
-                            else
-                            {
+                                StscState.get().error("Included schema has a target namespace \"" + included.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, include);
+                            } else {
                                 // chameleon include
                                 SchemaToProcess s = addScanNeeded(new SchemaToProcess(included, sourceNamespace));
                                 stp.addInclude(s);
@@ -822,37 +731,33 @@
                             }
                         }
                     }
-                    
+
                     {
                         // handle redefines
                         Redefine[] redefines = stp.getSchema().getRedefineArray();
                         String sourceNamespace = stp.getChameleonNamespace();
-                        if (sourceNamespace == null)
+                        if (sourceNamespace == null) {
                             sourceNamespace = emptyStringIfNull(stp.getSchema().getTargetNamespace());
-                        for (int i = 0; i < redefines.length; i++)
-                        {
-                            Schema redefined = downloadSchema(redefines[i], null, redefines[i].getSchemaLocation());
+                        }
+                        for (Redefine redefine : redefines) {
+                            Schema redefined = downloadSchema(redefine, null, redefine.getSchemaLocation());
                             // if download fails, an error has already been reported.
-                            if (redefined == null)
+                            if (redefined == null) {
                                 continue;
-    
-                            if (emptyStringIfNull(redefined.getTargetNamespace()).equals(sourceNamespace))
-                            {
+                            }
+
+                            if (emptyStringIfNull(redefined.getTargetNamespace()).equals(sourceNamespace)) {
                                 // non-chameleon case
                                 SchemaToProcess s = addScanNeeded(new SchemaToProcess(redefined, null));
-                                stp.addRedefine(s, redefines[i]);
+                                stp.addRedefine(s, redefine);
                                 hasRedefinitions = true;
-                            }
-                            else if (redefined.getTargetNamespace() != null)
-                            {
+                            } else if (redefined.getTargetNamespace() != null) {
                                 // illegal include: included schema in wrong namespace.
-                                StscState.get().error("Redefined schema has a target namespace \"" + redefined.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, redefines[i]);
-                            }
-                            else
-                            {
+                                StscState.get().error("Redefined schema has a target namespace \"" + redefined.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, redefine);
+                            } else {
                                 // chameleon redefine
                                 SchemaToProcess s = addScanNeeded(new SchemaToProcess(redefined, sourceNamespace));
-                                stp.addRedefine(s, redefines[i]);
+                                stp.addRedefine(s, redefine);
                                 usedEmptyNamespaceSchema(redefined);
                                 hasRedefinitions = true;
                             }
@@ -860,34 +765,31 @@
                     }
                 }
 
-                if (!fetchRemainingEmptyNamespaceSchemas())
-                    break;
-            }
+            } while (fetchRemainingEmptyNamespaceSchemas());
 
             // Build the lists of indirect references
             // Make all the effort only if there are redefinitions
-            if (hasRedefinitions)
-                for (int i = 0; i < result.size(); i++)
-                {
-                    SchemaToProcess schemaToProcess = (SchemaToProcess) result.get(i);
+            if (hasRedefinitions) {
+                for (SchemaToProcess schemaToProcess : result) {
                     schemaToProcess.buildIndirectReferences();
                 }
-            return (SchemaToProcess[])result.toArray(new SchemaToProcess[result.size()]);
+            }
+            return result.toArray(new SchemaToProcess[0]);
         }
 
-        private static Reader copySchemaSource(String url, Reader reader, StscState state)
-        {
+        private static Reader copySchemaSource(String url, Reader reader, StscState state) {
             //Copy the schema file if it wasn't already copied
-            if (state.getSchemasDir() == null)
+            if (state.getSchemasDir() == null) {
                 return reader;
+            }
 
             String schemalocation = state.sourceNameForUri(url);
             File targetFile = new File(state.getSchemasDir(), schemalocation);
-            if (targetFile.exists())
+            if (targetFile.exists()) {
                 return reader;
+            }
 
-            try
-            {
+            try {
                 File parentDir = new File(targetFile.getParent());
                 IOUtil.createDir(parentDir, null);
 
@@ -898,27 +800,25 @@
 
                 car.reset();
                 return car;
-            }
-            catch (IOException e)
-            {
+            } catch (IOException e) {
                 System.err.println("IO Error " + e);
                 return reader;
             }
         }
 
-        private static InputStream copySchemaSource(String url, InputStream bytes, StscState state)
-        {
+        private static InputStream copySchemaSource(String url, InputStream bytes, StscState state) {
             //Copy the schema file if it wasn't already copied
-            if (state.getSchemasDir() == null)
+            if (state.getSchemasDir() == null) {
                 return bytes;
+            }
 
             String schemalocation = state.sourceNameForUri(url);
             File targetFile = new File(state.getSchemasDir(), schemalocation);
-            if (targetFile.exists())
+            if (targetFile.exists()) {
                 return bytes;
+            }
 
-            try
-            {
+            try {
                 File parentDir = new File(targetFile.getParent());
                 IOUtil.createDir(parentDir, null);
 
@@ -929,51 +829,40 @@
 
                 bais.reset();
                 return bais;
-            }
-            catch (IOException e)
-            {
+            } catch (IOException e) {
                 System.err.println("IO Error " + e);
                 return bytes;
             }
         }
 
-        private static void copySchemaSource(String urlLoc, StscState state, boolean forceCopy)
-        {
+        private static void copySchemaSource(String urlLoc, StscState state, boolean forceCopy) {
             //Copy the schema file if it wasn't already copied
-            if (state.getSchemasDir()!=null)
-            {
+            if (state.getSchemasDir() != null) {
                 String schemalocation = state.sourceNameForUri(urlLoc);
 
                 File targetFile = new File(state.getSchemasDir(), schemalocation);
-                if (forceCopy || !targetFile.exists())
-                {
-                    try
-                    {
+                if (forceCopy || !targetFile.exists()) {
+                    try {
                         File parentDir = new File(targetFile.getParent());
                         IOUtil.createDir(parentDir, null);
 
                         InputStream in = null;
                         URL url = new URL(urlLoc);
                         // Copy the file from filepath to schema[METADATA_PACKAGE_GEN]/src/<schemaFile>
-                        try
-                        {
+                        try {
                             in = url.openStream();
-                        }
-                        catch (FileNotFoundException fnfe)
-                        {
-                            if (forceCopy && targetFile.exists())
+                        } catch (FileNotFoundException fnfe) {
+                            if (forceCopy && targetFile.exists()) {
                                 targetFile.delete();
-                            else
+                            } else {
                                 throw fnfe;
+                            }
                         }
-                        if (in != null)
-                        {
+                        if (in != null) {
                             FileOutputStream out = new FileOutputStream(targetFile);
                             IOUtil.copyCompletely(in, out);
                         }
-                    }
-                    catch (IOException e)
-                    {
+                    } catch (IOException e) {
                         System.err.println("IO Error " + e);
                         // failure = true; - not cause for failure
                     }
@@ -981,26 +870,26 @@
             }
         }
 
-        private static ByteArrayInputStream copy(InputStream is) throws IOException
-        {
-            byte [] buf = new byte[1024];
+        private static ByteArrayInputStream copy(InputStream is) throws IOException {
+            byte[] buf = new byte[1024];
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
             int bytesRead;
-            while(( bytesRead = is.read(buf, 0, 1024)) > 0)
+            while ((bytesRead = is.read(buf, 0, 1024)) > 0) {
                 baos.write(buf, 0, bytesRead);
+            }
 
             return new ByteArrayInputStream(baos.toByteArray());
         }
 
-        private static CharArrayReader copy(Reader is) throws IOException
-        {
+        private static CharArrayReader copy(Reader is) throws IOException {
             char[] buf = new char[1024];
             CharArrayWriter baos = new CharArrayWriter();
 
             int bytesRead;
-            while(( bytesRead = is.read(buf, 0, 1024)) > 0)
+            while ((bytesRead = is.read(buf, 0, 1024)) > 0) {
                 baos.write(buf, 0, bytesRead);
+            }
 
             return new CharArrayReader(baos.toCharArray());
         }
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java
index 247e353..8f53c58 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscState.java
@@ -82,9 +82,9 @@
     private final Map<String, SchemaContainer> _containers = new LinkedHashMap<>();
     private SchemaDependencies _dependencies;
 
-    private final Map<SchemaTypeImpl,SchemaTypeImpl> _redefinedGlobalTypes = new LinkedHashMap<>();
-    private final Map<SchemaModelGroupImpl,SchemaModelGroupImpl>  _redefinedModelGroups = new LinkedHashMap<>();
-    private final Map<SchemaAttributeGroupImpl,SchemaAttributeGroupImpl>  _redefinedAttributeGroups = new LinkedHashMap<>();
+    private final Map<SchemaTypeImpl, SchemaTypeImpl> _redefinedGlobalTypes = new LinkedHashMap<>();
+    private final Map<SchemaModelGroupImpl, SchemaModelGroupImpl> _redefinedModelGroups = new LinkedHashMap<>();
+    private final Map<SchemaAttributeGroupImpl, SchemaAttributeGroupImpl> _redefinedAttributeGroups = new LinkedHashMap<>();
 
     private final Map<QName, SchemaType> _globalTypes = new LinkedHashMap<>();
     private final Map<QName, SchemaGlobalElement> _globalElements = new LinkedHashMap<>();
@@ -450,16 +450,16 @@
 
         _allowPartial = options.hasOption("COMPILE_PARTIAL_TYPESYSTEM");
 
-        _compatMap = (Map) options.get(XmlOptions.COMPILE_SUBSTITUTE_NAMES);
-        _noUpa = options.hasOption(XmlOptions.COMPILE_NO_UPA_RULE) ? true :
-            !"true".equals(SystemProperties.getProperty("xmlbean.uniqueparticleattribution", "true"));
-        _noPvr = options.hasOption(XmlOptions.COMPILE_NO_PVR_RULE) ? true :
-            !"true".equals(SystemProperties.getProperty("xmlbean.particlerestriction", "true"));
-        _noAnn = options.hasOption(XmlOptions.COMPILE_NO_ANNOTATIONS) ? true :
-            !"true".equals(SystemProperties.getProperty("xmlbean.schemaannotations", "true"));
-        _doingDownloads = options.hasOption(XmlOptions.COMPILE_DOWNLOAD_URLS) ? true :
-            "true".equals(SystemProperties.getProperty("xmlbean.downloadurls", "false"));
-        _entityResolver = (EntityResolver) options.get(XmlOptions.ENTITY_RESOLVER);
+        _compatMap = options.getCompileSubstituteNames();
+        _noUpa = options.isCompileNoUpaRule() ||
+                 !"true".equals(SystemProperties.getProperty("xmlbean.uniqueparticleattribution", "true"));
+        _noPvr = options.isCompileNoPvrRule() ||
+                 !"true".equals(SystemProperties.getProperty("xmlbean.particlerestriction", "true"));
+        _noAnn = options.isCompileNoAnnotations() ||
+                 !"true".equals(SystemProperties.getProperty("xmlbean.schemaannotations", "true"));
+        _doingDownloads = options.isCompileDownloadUrls() ||
+                          "true".equals(SystemProperties.getProperty("xmlbean.downloadurls", "false"));
+        _entityResolver = options.getEntityResolver();
 
         if (_entityResolver == null) {
             _entityResolver = ResolverUtil.getGlobalEntityResolver();
@@ -469,8 +469,9 @@
             _doingDownloads = true;
         }
 
-        if (options.hasOption(XmlOptions.COMPILE_MDEF_NAMESPACES)) {
-            _mdefNamespaces.addAll((Collection) options.get(XmlOptions.COMPILE_MDEF_NAMESPACES));
+        Set<String> mdef = options.getCompileMdefNamespaces();
+        if (mdef != null) {
+            _mdefNamespaces.addAll(mdef);
 
             String local = "##local";
             String any = "##any";
@@ -720,7 +721,7 @@
     }
 
     SchemaType[] redefinedGlobalTypes() {
-        return (SchemaType[]) _redefinedGlobalTypes.values().toArray(new SchemaType[0]);
+        return _redefinedGlobalTypes.values().toArray(new SchemaType[0]);
     }
 
     /* DOCUMENT TYPES =================================================*/
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java
index ae275d5..2909fd8 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java
@@ -15,413 +15,320 @@
 
 package org.apache.xmlbeans.impl.schema;
 
-import org.apache.xmlbeans.QNameSet;
-import org.apache.xmlbeans.QNameSetBuilder;
-import org.apache.xmlbeans.SchemaAttributeModel;
-import org.apache.xmlbeans.SchemaBookmark;
-import org.apache.xmlbeans.SchemaGlobalAttribute;
-import org.apache.xmlbeans.SchemaGlobalElement;
-import org.apache.xmlbeans.SchemaIdentityConstraint;
-import org.apache.xmlbeans.SchemaLocalAttribute;
-import org.apache.xmlbeans.SchemaParticle;
-import org.apache.xmlbeans.SchemaType;
-import org.apache.xmlbeans.XmlAnySimpleType;
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlErrorCodes;
-import org.apache.xmlbeans.XmlNonNegativeInteger;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlPositiveInteger;
+import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.QNameHelper;
 import org.apache.xmlbeans.impl.common.XMLChar;
 import org.apache.xmlbeans.impl.common.XPath;
+import org.apache.xmlbeans.impl.schema.StscImporter.SchemaToProcess;
 import org.apache.xmlbeans.impl.values.NamespaceContext;
 import org.apache.xmlbeans.impl.values.XmlNonNegativeIntegerImpl;
 import org.apache.xmlbeans.impl.values.XmlPositiveIntegerImpl;
 import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
-import org.apache.xmlbeans.impl.xb.xsdschema.Annotated;
-import org.apache.xmlbeans.impl.xb.xsdschema.AnnotationDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.Attribute;
-import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroup;
-import org.apache.xmlbeans.impl.xb.xsdschema.Element;
-import org.apache.xmlbeans.impl.xb.xsdschema.FieldDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.FormChoice;
-import org.apache.xmlbeans.impl.xb.xsdschema.Keybase;
-import org.apache.xmlbeans.impl.xb.xsdschema.KeyrefDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.LocalElement;
-import org.apache.xmlbeans.impl.xb.xsdschema.LocalSimpleType;
-import org.apache.xmlbeans.impl.xb.xsdschema.NamedAttributeGroup;
-import org.apache.xmlbeans.impl.xb.xsdschema.NamedGroup;
+import org.apache.xmlbeans.impl.xb.xsdschema.*;
 import org.apache.xmlbeans.impl.xb.xsdschema.RedefineDocument.Redefine;
 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema;
-import org.apache.xmlbeans.impl.xb.xsdschema.SimpleType;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelSimpleType;
 import org.apache.xmlbeans.soap.SOAPArrayType;
 
 import javax.xml.namespace.QName;
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
-public class StscTranslator
-{
+public class StscTranslator {
     private static final QName WSDL_ARRAYTYPE_NAME =
         QNameHelper.forLNS("arrayType", "http://schemas.xmlsoap.org/wsdl/");
     private static final String FORM_QUALIFIED = "qualified";
 
-    public static void addAllDefinitions(StscImporter.SchemaToProcess[] schemasAndChameleons)
-    {
+    public static void addAllDefinitions(SchemaToProcess[] schemasAndChameleons) {
         // Build all redefine objects
-        List redefinitions = new ArrayList();
-        for (int i = 0; i < schemasAndChameleons.length; i++)
-        {
-            List redefines = schemasAndChameleons[i].getRedefines();
-            if (redefines != null)
-            {
-                List redefineObjects = schemasAndChameleons[i].getRedefineObjects();
-                Iterator it = redefines.iterator();
-                Iterator ito = redefineObjects.iterator();
-                for (; it.hasNext(); )
-                {
+        List<RedefinitionHolder> redefinitions = new ArrayList<>();
+        for (SchemaToProcess schemasAndChameleon : schemasAndChameleons) {
+            List<SchemaToProcess> redefines = schemasAndChameleon.getRedefines();
+            if (redefines != null) {
+                List<Redefine> redefineObjects = schemasAndChameleon.getRedefineObjects();
+                Iterator<SchemaToProcess> it = redefines.iterator();
+                Iterator<Redefine> ito = redefineObjects.iterator();
+                while (it.hasNext()) {
                     assert ito.hasNext() :
-                    "The array of redefines and redefine objects have to have the same length";
-                    redefinitions.add(new RedefinitionHolder(
-                            (StscImporter.SchemaToProcess) it.next(),
-                            (Redefine) ito.next()));
+                        "The array of redefines and redefine objects have to have the same length";
+                    redefinitions.add(new RedefinitionHolder(it.next(), ito.next()));
                 }
             }
         }
-        RedefinitionMaster globalRedefinitions = new RedefinitionMaster((RedefinitionHolder[])
-            redefinitions.toArray(new RedefinitionHolder[redefinitions.size()]));
+        RedefinitionMaster globalRedefinitions = new RedefinitionMaster(redefinitions.toArray(new RedefinitionHolder[0]));
 
         StscState state = StscState.get();
-        for (int j = 0; j < schemasAndChameleons.length; j++)
-        {
-            Schema schema = schemasAndChameleons[j].getSchema();
-            String givenTargetNamespace = schemasAndChameleons[j].getChameleonNamespace();
+        for (SchemaToProcess schemasAndChameleon : schemasAndChameleons) {
+            Schema schema = schemasAndChameleon.getSchema();
+            String givenTargetNamespace = schemasAndChameleon.getChameleonNamespace();
 
-        // quick check for a few unsupported features
+            // quick check for a few unsupported features
 
-        if (schema.sizeOfNotationArray() > 0)
-        {
-            state.warning("Schema <notation> is not yet supported for this release.", XmlErrorCodes.UNSUPPORTED_FEATURE, schema.getNotationArray(0));
-        }
+            if (schema.sizeOfNotationArray() > 0) {
+                state.warning("Schema <notation> is not yet supported for this release.", XmlErrorCodes.UNSUPPORTED_FEATURE, schema.getNotationArray(0));
+            }
 
-        // figure namespace (taking into account chameleons)
-        String targetNamespace = schema.getTargetNamespace();
-        boolean chameleon = false;
-        if (givenTargetNamespace != null && targetNamespace == null)
-        {
-            targetNamespace = givenTargetNamespace;
-            chameleon = true;
-        }
-        if (targetNamespace == null)
-            targetNamespace = "";
+            // figure namespace (taking into account chameleons)
+            String targetNamespace = schema.getTargetNamespace();
+            boolean chameleon = false;
+            if (givenTargetNamespace != null && targetNamespace == null) {
+                targetNamespace = givenTargetNamespace;
+                chameleon = true;
+            }
+            if (targetNamespace == null) {
+                targetNamespace = "";
+            }
 
-        //SchemaContainer container = null;
-        if (targetNamespace.length() > 0 || !isEmptySchema(schema))
-        {
-            state.registerContribution(targetNamespace, schema.documentProperties().getSourceName());
-            state.addNewContainer(targetNamespace);
-            //container = state.getContainer(targetNamespace);
-        }
+            //SchemaContainer container = null;
+            if (targetNamespace.length() > 0 || !isEmptySchema(schema)) {
+                state.registerContribution(targetNamespace, schema.documentProperties().getSourceName());
+                state.addNewContainer(targetNamespace);
+                //container = state.getContainer(targetNamespace);
+            }
 
-        List redefChain = new ArrayList();
-        TopLevelComplexType[] complexTypes = schema.getComplexTypeArray();
-        for (int i = 0; i < complexTypes.length; i++)
-        {
-            TopLevelComplexType type = complexTypes[i];
-            TopLevelComplexType redef;
-            // 1. Traverse the list of redefining Schemas putting all redefinitions
-            // of this type in a List
-            RedefinitionHolder[] rhArray = globalRedefinitions.getComplexTypeRedefinitions(
-                type.getName(), schemasAndChameleons[j]);
-            for (int k = 0; k < rhArray.length; k++)
-            {
-                // In error cases, some redefinitions were nulled out in the list
-                // which is why we need to perform this check
-                if (rhArray[k] != null)
-                {
-                    redef = rhArray[k].redefineComplexType(type.getName());
-                    assert redef != null; // This was already checked
-                    redefChain.add(type);
-                    type = redef;
+            List<Annotated> redefChain = new ArrayList<>();
+            TopLevelComplexType[] complexTypes = schema.getComplexTypeArray();
+            for (TopLevelComplexType complexType : complexTypes) {
+                TopLevelComplexType type = complexType;
+                TopLevelComplexType redef;
+                // 1. Traverse the list of redefining Schemas putting all redefinitions
+                // of this type in a List
+                RedefinitionHolder[] rhArray = globalRedefinitions.getComplexTypeRedefinitions(
+                    type.getName(), schemasAndChameleon);
+                for (RedefinitionHolder redefinitionHolder : rhArray) {
+                    // In error cases, some redefinitions were nulled out in the list
+                    // which is why we need to perform this check
+                    if (redefinitionHolder != null) {
+                        redef = redefinitionHolder.redefineComplexType(type.getName());
+                        assert redef != null; // This was already checked
+                        redefChain.add(type);
+                        type = redef;
+                    }
+                }
+
+                SchemaTypeImpl t = translateGlobalComplexType(type, targetNamespace, chameleon, redefChain.size() > 0);
+                state.addGlobalType(t, null);
+                SchemaTypeImpl r;
+                // 2. Traverse the List built in step 1 in reverse and add all the
+                // types in it to the list of redefined types
+                for (int k = redefChain.size() - 1; k >= 0; k--) {
+                    redef = (TopLevelComplexType) redefChain.remove(k);
+                    r = translateGlobalComplexType(redef, targetNamespace, chameleon, k > 0);
+                    state.addGlobalType(r, t);
+                    t = r;
                 }
             }
 
-            SchemaTypeImpl t = translateGlobalComplexType(type, targetNamespace, chameleon, redefChain.size() > 0);
-            state.addGlobalType(t, null);
-            SchemaTypeImpl r;
-            // 2. Traverse the List built in step 1 in reverse and add all the
-            // types in it to the list of redefined types
-            for (int k = redefChain.size() - 1; k >= 0; k--)
-            {
-                redef = (TopLevelComplexType) redefChain.remove(k);
-                r = translateGlobalComplexType(redef, targetNamespace, chameleon, k > 0);
-                state.addGlobalType(r, t);
-                t = r;
-            }
-        }
+            TopLevelSimpleType[] simpleTypes = schema.getSimpleTypeArray();
+            for (TopLevelSimpleType simpleType : simpleTypes) {
+                TopLevelSimpleType type = simpleType;
+                TopLevelSimpleType redef;
+                RedefinitionHolder[] rhArray = globalRedefinitions.getSimpleTypeRedefinitions(
+                    type.getName(), schemasAndChameleon);
+                for (RedefinitionHolder redefinitionHolder : rhArray) {
+                    // In error cases, some redefinitions were nulled out in the list
+                    // which is why we need to perform this check
+                    if (redefinitionHolder != null) {
+                        redef = redefinitionHolder.redefineSimpleType(type.getName());
+                        assert redef != null; // This was already checked
+                        redefChain.add(type);
+                        type = redef;
+                    }
+                }
 
-        TopLevelSimpleType[] simpleTypes = schema.getSimpleTypeArray();
-        for (int i = 0; i < simpleTypes.length; i++)
-        {
-            TopLevelSimpleType type = simpleTypes[i];
-            TopLevelSimpleType redef;
-            RedefinitionHolder[] rhArray = globalRedefinitions.getSimpleTypeRedefinitions(
-                type.getName(), schemasAndChameleons[j]);
-            for (int k = 0; k < rhArray.length; k++)
-            {
-                // In error cases, some redefinitions were nulled out in the list
-                // which is why we need to perform this check
-                if (rhArray[k] != null)
-                {
-                    redef = rhArray[k].redefineSimpleType(type.getName());
-                    assert redef != null; // This was already checked
-                    redefChain.add(type);
-                    type = redef;
+                SchemaTypeImpl t = translateGlobalSimpleType(type, targetNamespace, chameleon, redefChain.size() > 0);
+                state.addGlobalType(t, null);
+                SchemaTypeImpl r;
+                for (int k = redefChain.size() - 1; k >= 0; k--) {
+                    redef = (TopLevelSimpleType) redefChain.remove(k);
+                    r = translateGlobalSimpleType(redef, targetNamespace, chameleon, k > 0);
+                    state.addGlobalType(r, t);
+                    t = r;
                 }
             }
 
-            SchemaTypeImpl t = translateGlobalSimpleType(type, targetNamespace, chameleon,redefChain.size() > 0);
-            state.addGlobalType(t, null);
-            SchemaTypeImpl r;
-            for (int k = redefChain.size()-1; k >= 0; k--)
-            {
-                redef = (TopLevelSimpleType) redefChain.remove(k);
-                r = translateGlobalSimpleType(redef, targetNamespace, chameleon, k > 0);
-                state.addGlobalType(r, t);
-                t = r;
+            TopLevelElement[] elements = schema.getElementArray();
+            for (TopLevelElement element : elements) {
+                state.addDocumentType(translateDocumentType(element, targetNamespace, chameleon), QNameHelper.forLNS(element.getName(), targetNamespace));
             }
-        }
 
-        TopLevelElement[] elements = schema.getElementArray();
-        for (int i = 0; i < elements.length; i++)
-        {
-            TopLevelElement element = elements[i];
-            state.addDocumentType(translateDocumentType(element, targetNamespace, chameleon), QNameHelper.forLNS(element.getName(), targetNamespace));
-        }
+            TopLevelAttribute[] attributes = schema.getAttributeArray();
+            for (TopLevelAttribute attribute : attributes) {
+                state.addAttributeType(translateAttributeType(attribute, targetNamespace, chameleon), QNameHelper.forLNS(attribute.getName(), targetNamespace));
+            }
 
-        TopLevelAttribute[] attributes = schema.getAttributeArray();
-        for (int i = 0; i < attributes.length ; i++)
-        {
-            TopLevelAttribute attribute = attributes[i];
-            state.addAttributeType(translateAttributeType(attribute, targetNamespace, chameleon), QNameHelper.forLNS(attribute.getName(), targetNamespace));
-        }
+            NamedGroup[] modelgroups = schema.getGroupArray();
+            for (NamedGroup group : modelgroups) {
+                NamedGroup redef;
+                RedefinitionHolder[] rhArray = globalRedefinitions.getModelGroupRedefinitions(
+                    group.getName(), schemasAndChameleon);
+                for (RedefinitionHolder redefinitionHolder : rhArray) {
+                    // In error cases, some redefinitions were nulled out in the list
+                    // which is why we need to perform this check
+                    if (redefinitionHolder != null) {
+                        redef = redefinitionHolder.redefineModelGroup(group.getName());
+                        assert redef != null; // This was already checked
+                        redefChain.add(group);
+                        group = redef;
+                    }
+                }
 
-        NamedGroup[] modelgroups = schema.getGroupArray();
-        for (int i = 0; i < modelgroups.length; i++)
-        {
-            NamedGroup group = modelgroups[i];
-            NamedGroup redef;
-            RedefinitionHolder[] rhArray = globalRedefinitions.getModelGroupRedefinitions(
-                group.getName(), schemasAndChameleons[j]);
-            for (int k = 0; k < rhArray.length; k++)
-            {
-                // In error cases, some redefinitions were nulled out in the list
-                // which is why we need to perform this check
-                if (rhArray[k] != null)
-                {
-                    redef = rhArray[k].redefineModelGroup(group.getName());
-                    assert redef != null; // This was already checked
-                    redefChain.add(group);
-                    group = redef;
+                SchemaModelGroupImpl g = translateModelGroup(group, targetNamespace, chameleon, redefChain.size() > 0);
+                state.addModelGroup(g, null);
+                SchemaModelGroupImpl r;
+                for (int k = redefChain.size() - 1; k >= 0; k--) {
+                    redef = (NamedGroup) redefChain.remove(k);
+                    r = translateModelGroup(redef, targetNamespace, chameleon, k > 0);
+                    state.addModelGroup(r, g);
+                    g = r;
                 }
             }
 
-            SchemaModelGroupImpl g = translateModelGroup(group, targetNamespace, chameleon, redefChain.size() > 0);
-            state.addModelGroup(g, null);
-            SchemaModelGroupImpl r;
-            for (int k = redefChain.size()-1; k >= 0; k--)
-            {
-                redef = (NamedGroup) redefChain.remove(k);
-                r = translateModelGroup(redef, targetNamespace, chameleon, k > 0);
-                state.addModelGroup(r, g);
-                g = r;
-            }
-        }
+            NamedAttributeGroup[] attrgroups = schema.getAttributeGroupArray();
+            for (NamedAttributeGroup group : attrgroups) {
+                NamedAttributeGroup redef;
+                RedefinitionHolder[] rhArray = globalRedefinitions.getAttributeGroupRedefinitions(
+                    group.getName(), schemasAndChameleon);
+                for (RedefinitionHolder redefinitionHolder : rhArray) {
+                    // In error cases, some redefinitions were nulled out in the list
+                    // which is why we need to perform this check
+                    if (redefinitionHolder != null) {
+                        redef = redefinitionHolder.redefineAttributeGroup(group.getName());
+                        assert redef != null; // This was already checked
+                        redefChain.add(group);
+                        group = redef;
+                    }
+                }
 
-        NamedAttributeGroup[] attrgroups = schema.getAttributeGroupArray();
-        for (int i = 0; i < attrgroups.length; i++)
-        {
-            NamedAttributeGroup group = attrgroups[i];
-            NamedAttributeGroup redef;
-            RedefinitionHolder[] rhArray = globalRedefinitions.getAttributeGroupRedefinitions(
-                group.getName(), schemasAndChameleons[j]);
-            for (int k = 0; k < rhArray.length; k++)
-            {
-                // In error cases, some redefinitions were nulled out in the list
-                // which is why we need to perform this check
-                if (rhArray[k] != null)
-                {
-                    redef = rhArray[k].redefineAttributeGroup(group.getName());
-                    assert redef != null; // This was already checked
-                    redefChain.add(group);
-                    group = redef;
+                SchemaAttributeGroupImpl g = translateAttributeGroup(group, targetNamespace, chameleon, redefChain.size() > 0);
+                state.addAttributeGroup(g, null);
+                SchemaAttributeGroupImpl r;
+                for (int k = redefChain.size() - 1; k >= 0; k--) {
+                    redef = (NamedAttributeGroup) redefChain.remove(k);
+                    r = translateAttributeGroup(redef, targetNamespace, chameleon, k > 0);
+                    state.addAttributeGroup(r, g);
+                    g = r;
                 }
             }
 
-            SchemaAttributeGroupImpl g = translateAttributeGroup(group, targetNamespace, chameleon, redefChain.size() > 0);
-            state.addAttributeGroup(g, null);
-            SchemaAttributeGroupImpl r;
-            for (int k = redefChain.size()-1; k >= 0; k--)
-            {
-                redef = (NamedAttributeGroup) redefChain.remove(k);
-                r = translateAttributeGroup(redef, targetNamespace, chameleon, k > 0);
-                state.addAttributeGroup(r, g);
-                g = r;
+            AnnotationDocument.Annotation[] annotations = schema.getAnnotationArray();
+            for (AnnotationDocument.Annotation annotation : annotations) {
+                state.addAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), schema, annotation), targetNamespace);
             }
         }
 
-        AnnotationDocument.Annotation[] annotations = schema.getAnnotationArray();
-        for (int i = 0; i < annotations.length; i++)
-            state.addAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), schema, annotations[i]), targetNamespace);
+        for (Object redefinition : redefinitions) {
+            ((RedefinitionHolder) redefinition).complainAboutMissingDefinitions();
         }
-
-        for (int i = 0; i < redefinitions.size(); i++)
-            ((RedefinitionHolder) redefinitions.get(i)).complainAboutMissingDefinitions();
     }
 
-    private static class RedefinitionHolder
-    {
+    private static class RedefinitionHolder {
         // record redefinitions
-        private Map stRedefinitions = Collections.EMPTY_MAP;
-        private Map ctRedefinitions = Collections.EMPTY_MAP;
-        private Map agRedefinitions = Collections.EMPTY_MAP;
-        private Map mgRedefinitions = Collections.EMPTY_MAP;
+        private Map<String, TopLevelSimpleType> stRedefinitions = Collections.emptyMap();
+        private Map<String, TopLevelComplexType> ctRedefinitions = Collections.emptyMap();
+        private Map<String, NamedAttributeGroup> agRedefinitions = Collections.emptyMap();
+        private Map<String, NamedGroup> mgRedefinitions = Collections.emptyMap();
         private String schemaLocation = "";
-        private StscImporter.SchemaToProcess schemaRedefined;
+        private final SchemaToProcess schemaRedefined;
 
         // first build set of redefined components
-        RedefinitionHolder(StscImporter.SchemaToProcess schemaToProcess, Redefine redefine)
-        {
+        RedefinitionHolder(SchemaToProcess schemaToProcess, Redefine redefine) {
             schemaRedefined = schemaToProcess;
-            if (redefine != null)
-            {
+            if (redefine != null) {
                 StscState state = StscState.get();
 
-                stRedefinitions = new HashMap();
-                ctRedefinitions = new HashMap();
-                agRedefinitions = new HashMap();
-                mgRedefinitions = new HashMap();
-                if (redefine.getSchemaLocation() != null)
+                stRedefinitions = new HashMap<>();
+                ctRedefinitions = new HashMap<>();
+                agRedefinitions = new HashMap<>();
+                mgRedefinitions = new HashMap<>();
+                if (redefine.getSchemaLocation() != null) {
                     schemaLocation = redefine.getSchemaLocation();
+                }
 
                 TopLevelComplexType[] complexTypes = redefine.getComplexTypeArray();
-                for (int i = 0; i < complexTypes.length; i++)
-                {
-                    if (complexTypes[i].getName() != null)
-                    {
+                for (TopLevelComplexType complexType : complexTypes) {
+                    if (complexType.getName() != null) {
                         // KHK: which rule? sch-props-correct.2?
-                        if (ctRedefinitions.containsKey(complexTypes[i].getName()))
-                            state.error("Duplicate type redefinition: " + complexTypes[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
-                        else
-                            ctRedefinitions.put(complexTypes[i].getName(), complexTypes[i]);
+                        if (ctRedefinitions.containsKey(complexType.getName())) {
+                            state.error("Duplicate type redefinition: " + complexType.getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
+                        } else {
+                            ctRedefinitions.put(complexType.getName(), complexType);
+                        }
                     }
                 }
 
                 TopLevelSimpleType[] simpleTypes = redefine.getSimpleTypeArray();
-                for (int i = 0; i < simpleTypes.length; i++)
-                {
-                    if (simpleTypes[i].getName() != null)
-                    {
-                        if (stRedefinitions.containsKey(simpleTypes[i].getName()))
-                            state.error("Duplicate type redefinition: " + simpleTypes[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
-                        else
-                            stRedefinitions.put(simpleTypes[i].getName(), simpleTypes[i]);
+                for (TopLevelSimpleType simpleType : simpleTypes) {
+                    if (simpleType.getName() != null) {
+                        if (stRedefinitions.containsKey(simpleType.getName())) {
+                            state.error("Duplicate type redefinition: " + simpleType.getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
+                        } else {
+                            stRedefinitions.put(simpleType.getName(), simpleType);
+                        }
                     }
                 }
 
                 NamedGroup[] modelgroups = redefine.getGroupArray();
-                for (int i = 0; i < modelgroups.length; i++)
-                {
-                    if (modelgroups[i].getName() != null)
-                    {
-                        if (mgRedefinitions.containsKey(modelgroups[i].getName()))
-                            state.error("Duplicate type redefinition: " + modelgroups[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
-                        else
-                            mgRedefinitions.put(modelgroups[i].getName(), modelgroups[i]);
+                for (NamedGroup modelgroup : modelgroups) {
+                    if (modelgroup.getName() != null) {
+                        if (mgRedefinitions.containsKey(modelgroup.getName())) {
+                            state.error("Duplicate type redefinition: " + modelgroup.getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
+                        } else {
+                            mgRedefinitions.put(modelgroup.getName(), modelgroup);
+                        }
                     }
                 }
 
                 NamedAttributeGroup[] attrgroups = redefine.getAttributeGroupArray();
-                for (int i = 0; i < attrgroups.length; i++)
-                {
-                    if (attrgroups[i].getName() != null)
-                    {
-                        if (agRedefinitions.containsKey(attrgroups[i].getName()))
-                            state.error("Duplicate type redefinition: " + attrgroups[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
-                        else
-                            agRedefinitions.put(attrgroups[i].getName(), attrgroups[i]);
+                for (NamedAttributeGroup attrgroup : attrgroups) {
+                    if (attrgroup.getName() != null) {
+                        if (agRedefinitions.containsKey(attrgroup.getName())) {
+                            state.error("Duplicate type redefinition: " + attrgroup.getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null);
+                        } else {
+                            agRedefinitions.put(attrgroup.getName(), attrgroup);
+                        }
                     }
                 }
             }
         }
 
-        public TopLevelSimpleType redefineSimpleType(String name)
-        {
-            if (name == null || !stRedefinitions.containsKey(name))
-                return null;
-            return (TopLevelSimpleType)stRedefinitions.remove(name);
+        public TopLevelSimpleType redefineSimpleType(String name) {
+            return name == null || !stRedefinitions.containsKey(name) ? null : stRedefinitions.remove(name);
         }
 
-        public TopLevelComplexType redefineComplexType(String name)
-        {
-            if (name == null || !ctRedefinitions.containsKey(name))
-                return null;
-            return (TopLevelComplexType)ctRedefinitions.remove(name);
+        public TopLevelComplexType redefineComplexType(String name) {
+            return name == null || !ctRedefinitions.containsKey(name) ? null : ctRedefinitions.remove(name);
         }
 
-        public NamedGroup redefineModelGroup(String name)
-        {
-            if (name == null || !mgRedefinitions.containsKey(name))
-                return null;
-            return (NamedGroup)mgRedefinitions.remove(name);
+        public NamedGroup redefineModelGroup(String name) {
+            return name == null || !mgRedefinitions.containsKey(name) ? null : mgRedefinitions.remove(name);
         }
 
-        public NamedAttributeGroup redefineAttributeGroup(String name)
-        {
-            if (name == null || !agRedefinitions.containsKey(name))
-                return null;
-            return (NamedAttributeGroup)agRedefinitions.remove(name);
+        public NamedAttributeGroup redefineAttributeGroup(String name) {
+            return name == null || !agRedefinitions.containsKey(name) ? null : agRedefinitions.remove(name);
         }
 
-        public void complainAboutMissingDefinitions()
-        {
+        public void complainAboutMissingDefinitions() {
             if (stRedefinitions.isEmpty() && ctRedefinitions.isEmpty() &&
-                    agRedefinitions.isEmpty() && mgRedefinitions.isEmpty())
+                agRedefinitions.isEmpty() && mgRedefinitions.isEmpty()) {
                 return;
+            }
 
             StscState state = StscState.get();
 
-            for (Iterator i = stRedefinitions.keySet().iterator(); i.hasNext(); )
-            {
-                String name = (String)i.next();
-                state.error("Redefined simple type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)stRedefinitions.get(name));
+            for (String name : stRedefinitions.keySet()) {
+                state.error("Redefined simple type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, stRedefinitions.get(name));
             }
 
-            for (Iterator i = ctRedefinitions.keySet().iterator(); i.hasNext(); )
-            {
-                String name = (String)i.next();
-                state.error("Redefined complex type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)ctRedefinitions.get(name));
+            for (String name : ctRedefinitions.keySet()) {
+                state.error("Redefined complex type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, ctRedefinitions.get(name));
             }
 
-            for (Iterator i = agRedefinitions.keySet().iterator(); i.hasNext(); )
-            {
-                String name = (String)i.next();
-                state.error("Redefined attribute group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)agRedefinitions.get(name));
+            for (String name : agRedefinitions.keySet()) {
+                state.error("Redefined attribute group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, agRedefinitions.get(name));
             }
 
-            for (Iterator i = mgRedefinitions.keySet().iterator(); i.hasNext(); )
-            {
-                String name = (String)i.next();
-                state.error("Redefined model group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)mgRedefinitions.get(name));
+            for (String name : mgRedefinitions.keySet()) {
+                state.error("Redefined model group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, mgRedefinitions.get(name));
             }
         }
     }
@@ -435,130 +342,92 @@
      * and then topologically sorted based on the inclusion relationship to
      * ensure that redefinitions are applied in the right order.
      */
-    private static class RedefinitionMaster
-    {
+    private static class RedefinitionMaster {
+        private static final short SIMPLE_TYPE = 1;
+        private static final short COMPLEX_TYPE = 2;
+        private static final short MODEL_GROUP = 3;
+        private static final short ATTRIBUTE_GROUP = 4;
+
         // record redefinitions
-        private Map stRedefinitions = Collections.EMPTY_MAP;
-        private Map ctRedefinitions = Collections.EMPTY_MAP;
-        private Map agRedefinitions = Collections.EMPTY_MAP;
-        private Map mgRedefinitions = Collections.EMPTY_MAP;
+        private Map<String, List<RedefinitionHolder>> stRedefinitions = Collections.emptyMap();
+        private Map<String, List<RedefinitionHolder>> ctRedefinitions = Collections.emptyMap();
+        private Map<String, List<RedefinitionHolder>> agRedefinitions = Collections.emptyMap();
+        private Map<String, List<RedefinitionHolder>> mgRedefinitions = Collections.emptyMap();
         private static final RedefinitionHolder[] EMPTY_REDEFINTION_HOLDER_ARRAY =
             new RedefinitionHolder[0];
 
-        RedefinitionMaster(RedefinitionHolder[] redefHolders)
-        {
-            if (redefHolders.length > 0)
-            {
-                stRedefinitions = new HashMap();
-                ctRedefinitions = new HashMap();
-                agRedefinitions = new HashMap();
-                mgRedefinitions = new HashMap();
 
-                for (int i = 0; i < redefHolders.length; i++)
-                {
-                    RedefinitionHolder redefHolder = redefHolders[i];
-                    for (Iterator it = redefHolder.stRedefinitions.keySet().iterator(); it.hasNext();)
-                    {
-                        Object key = it.next();
-                        List redefinedIn = (List) stRedefinitions.get(key);
-                        if (redefinedIn == null)
-                        {
-                            redefinedIn = new ArrayList();
-                            stRedefinitions.put(key, redefinedIn);
-                        }
-                        redefinedIn.add(redefHolders[i]);
+        RedefinitionMaster(RedefinitionHolder[] redefHolders) {
+            if (redefHolders.length > 0) {
+                stRedefinitions = new HashMap<>();
+                ctRedefinitions = new HashMap<>();
+                agRedefinitions = new HashMap<>();
+                mgRedefinitions = new HashMap<>();
+
+                for (RedefinitionHolder redefHolder : redefHolders) {
+                    for (String key : redefHolder.stRedefinitions.keySet()) {
+                        stRedefinitions.computeIfAbsent(key, k -> new ArrayList<>()).add(redefHolder);
                     }
-                    for (Iterator it = redefHolder.ctRedefinitions.keySet().iterator(); it.hasNext();)
-                    {
-                        Object key = it.next();
-                        List redefinedIn = (List) ctRedefinitions.get(key);
-                        if (redefinedIn == null)
-                        {
-                            redefinedIn = new ArrayList();
-                            ctRedefinitions.put(key, redefinedIn);
-                        }
-                        redefinedIn.add(redefHolders[i]);
+                    for (String key : redefHolder.ctRedefinitions.keySet()) {
+                        ctRedefinitions.computeIfAbsent(key, k -> new ArrayList<>()).add(redefHolder);
                     }
-                    for (Iterator it = redefHolder.agRedefinitions.keySet().iterator(); it.hasNext();)
-                    {
-                        Object key = it.next();
-                        List redefinedIn = (List) agRedefinitions.get(key);
-                        if (redefinedIn == null)
-                        {
-                            redefinedIn = new ArrayList();
-                            agRedefinitions.put(key, redefinedIn);
-                        }
-                        redefinedIn.add(redefHolders[i]);
+                    for (String key : redefHolder.agRedefinitions.keySet()) {
+                        agRedefinitions.computeIfAbsent(key, k -> new ArrayList<>()).add(redefHolder);
                     }
-                    for (Iterator it = redefHolder.mgRedefinitions.keySet().iterator(); it.hasNext();)
-                    {
-                        Object key = it.next();
-                        List redefinedIn = (List) mgRedefinitions.get(key);
-                        if (redefinedIn == null)
-                        {
-                            redefinedIn = new ArrayList();
-                            mgRedefinitions.put(key, redefinedIn);
-                        }
-                        redefinedIn.add(redefHolders[i]);
+                    for (String key : redefHolder.mgRedefinitions.keySet()) {
+                        mgRedefinitions.computeIfAbsent(key, k -> new ArrayList<>()).add(redefHolder);
                     }
                 }
             }
         }
 
         RedefinitionHolder[] getSimpleTypeRedefinitions(String name,
-            StscImporter.SchemaToProcess schema)
-        {
-            List redefines = (List) stRedefinitions.get(name);
-            if (redefines == null)
+                                                        SchemaToProcess schema) {
+            List<RedefinitionHolder> redefines = stRedefinitions.get(name);
+            if (redefines == null) {
                 return EMPTY_REDEFINTION_HOLDER_ARRAY;
+            }
             return doTopologicalSort(redefines, schema, name, SIMPLE_TYPE);
         }
 
         RedefinitionHolder[] getComplexTypeRedefinitions(String name,
-            StscImporter.SchemaToProcess schema)
-        {
-            List redefines = (List) ctRedefinitions.get(name);
-            if (redefines == null)
+                                                         SchemaToProcess schema) {
+            List<RedefinitionHolder> redefines = ctRedefinitions.get(name);
+            if (redefines == null) {
                 return EMPTY_REDEFINTION_HOLDER_ARRAY;
+            }
             return doTopologicalSort(redefines, schema, name, COMPLEX_TYPE);
         }
 
         RedefinitionHolder[] getAttributeGroupRedefinitions(String name,
-            StscImporter.SchemaToProcess schema)
-        {
-            List redefines = (List) agRedefinitions.get(name);
-            if (redefines == null)
+                                                            SchemaToProcess schema) {
+            List<RedefinitionHolder> redefines = agRedefinitions.get(name);
+            if (redefines == null) {
                 return EMPTY_REDEFINTION_HOLDER_ARRAY;
+            }
             return doTopologicalSort(redefines, schema, name, ATTRIBUTE_GROUP);
         }
 
         RedefinitionHolder[] getModelGroupRedefinitions(String name,
-            StscImporter.SchemaToProcess schema)
-        {
-            List redefines = (List) mgRedefinitions.get(name);
-            if (redefines == null)
+                                                        SchemaToProcess schema) {
+            List<RedefinitionHolder> redefines = mgRedefinitions.get(name);
+            if (redefines == null) {
                 return EMPTY_REDEFINTION_HOLDER_ARRAY;
+            }
             return doTopologicalSort(redefines, schema, name, MODEL_GROUP);
         }
 
-        private final static short SIMPLE_TYPE = 1;
-        private final static short COMPLEX_TYPE = 2;
-        private final static short MODEL_GROUP = 3;
-        private final static short ATTRIBUTE_GROUP = 4;
-
-        private RedefinitionHolder[] doTopologicalSort(List genericRedefines,
-            StscImporter.SchemaToProcess schema, String name, short componentType)
-        {
+        private RedefinitionHolder[] doTopologicalSort(List<RedefinitionHolder> genericRedefines,
+                                                       SchemaToProcess schema, String name, short componentType) {
             // We have a list of files that redefine this name
             // Filter out the ones that don't redefine this file in particular
             RedefinitionHolder[] specificRedefines = new RedefinitionHolder[genericRedefines.size()];
             int n = 0;
-            for (int i = 0; i < genericRedefines.size(); i++)
-            {
-                RedefinitionHolder h = (RedefinitionHolder) genericRedefines.get(i);
+            for (RedefinitionHolder h : genericRedefines) {
                 if (h.schemaRedefined == schema ||
-                    h.schemaRedefined.indirectIncludes(schema))
+                    h.schemaRedefined.indirectIncludes(schema)) {
                     specificRedefines[n++] = h;
+                }
             }
             // Now we have the list of files that specifically redefine the
             // name in the file that we are looking for
@@ -567,71 +436,70 @@
             RedefinitionHolder[] sortedRedefines = new RedefinitionHolder[n];
             int[] numberOfIncludes = new int[n];
             // Just count the number of inclusions for each redefinition
-            for (int i = 0; i < n-1; i++)
-            {
+            for (int i = 0; i < n - 1; i++) {
                 RedefinitionHolder current = specificRedefines[i];
-                for (int j = i + 1; j < n; j++)
-                {
-                    if (current.schemaRedefined.indirectIncludes(specificRedefines[j].schemaRedefined))
+                for (int j = i + 1; j < n; j++) {
+                    if (current.schemaRedefined.indirectIncludes(specificRedefines[j].schemaRedefined)) {
                         numberOfIncludes[i]++;
-                    if (specificRedefines[j].schemaRedefined.indirectIncludes(current.schemaRedefined))
+                    }
+                    if (specificRedefines[j].schemaRedefined.indirectIncludes(current.schemaRedefined)) {
                         numberOfIncludes[j]++;
+                    }
                 }
             }
             // Eliminate members one by one, according to the number of schemas
             // that they include, to complete the sort
             int position = 0;
             boolean errorReported = false;
-            while (position < n)
-            {
+            while (position < n) {
                 int index = -1;
-                for (int i = 0; i < numberOfIncludes.length; i++)
-                    if (numberOfIncludes[i] == 0)
-                    {
-                        if (index < 0)
+                for (int i = 0; i < numberOfIncludes.length; i++) {
+                    if (numberOfIncludes[i] == 0) {
+                        if (index < 0) {
                             index = i;
+                        }
                     }
-                if (index < 0)
-                {
+                }
+                if (index < 0) {
                     // Error! Circular redefinition
-                    if (!errorReported)
-                    {
+                    if (!errorReported) {
                         StringBuilder fileNameList = new StringBuilder();
                         XmlObject location = null;
-                        for (int i = 0; i < n; i++)
-                            if (specificRedefines[i] != null)
-                            {
+                        for (int i = 0; i < n; i++) {
+                            if (specificRedefines[i] != null) {
                                 fileNameList.append(specificRedefines[i].schemaLocation).
                                     append(',').append(' ');
-                                if (location == null)
+                                if (location == null) {
                                     location = locationFromRedefinitionAndCode(
                                         specificRedefines[i], name, componentType);
+                                }
                             }
+                        }
                         StscState.get().error("Detected circular redefinition of " +
-                            componentNameFromCode(componentType) + " \"" + name +
-                            "\"; Files involved: " + fileNameList.toString(),
+                                              componentNameFromCode(componentType) + " \"" + name +
+                                              "\"; Files involved: " + fileNameList.toString(),
                             XmlErrorCodes.GENERIC_ERROR, location);
                         errorReported = true;
                     }
                     int min = n;
-                    for (int i = 0; i < n; i++)
-                        if (numberOfIncludes[i] > 0 && numberOfIncludes[i] < min)
-                        {
+                    for (int i = 0; i < n; i++) {
+                        if (numberOfIncludes[i] > 0 && numberOfIncludes[i] < min) {
                             min = numberOfIncludes[i];
                             index = i;
                         }
+                    }
                     numberOfIncludes[index]--;
-                }
-                else
-                {
+                } else {
                     assert specificRedefines[index] != null;
                     sortedRedefines[position++] = specificRedefines[index];
-                    for (int i = 0; i < n; i++)
+                    for (int i = 0; i < n; i++) {
                         if (specificRedefines[i] != null &&
                             specificRedefines[i].schemaRedefined.
                                 indirectIncludes(specificRedefines[index].
-                                    schemaRedefined))
+                                    schemaRedefined)) {
                             numberOfIncludes[i]--;
+                        }
+                    }
                     specificRedefines[index] = null;
                     numberOfIncludes[index]--;
                 }
@@ -640,36 +508,39 @@
             // Each one has to transitively redefine the one before, otherwise
             // it means we are attepting two different redefinitions for the same
             // component
-            for (int i = 1; i < n; i++)
-            {
+            for (int i = 1; i < n; i++) {
                 // Find the previous index with non-null Schema
                 // Since i is never 0, such index always exists
                 int j;
-                for (j = i-1; j >= 0; j--)
-                    if (sortedRedefines[j] != null)
+                for (j = i - 1; j >= 0; j--) {
+                    if (sortedRedefines[j] != null) {
                         break;
+                    }
+                }
 
                 if (!sortedRedefines[i].schemaRedefined.indirectIncludes(
-                        sortedRedefines[j].schemaRedefined))
-                {
+                    sortedRedefines[j].schemaRedefined)) {
                     StscState.get().error("Detected multiple redefinitions of " +
-                        componentNameFromCode(componentType) +
-                        " \"" + name + "\"; Files involved: " +
-                        sortedRedefines[j].schemaRedefined.getSourceName() + ", " +
-                        sortedRedefines[i].schemaRedefined.getSourceName(),
+                                          componentNameFromCode(componentType) +
+                                          " \"" + name + "\"; Files involved: " +
+                                          sortedRedefines[j].schemaRedefined.getSourceName() + ", " +
+                                          sortedRedefines[i].schemaRedefined.getSourceName(),
                         XmlErrorCodes.DUPLICATE_GLOBAL_TYPE,
                         locationFromRedefinitionAndCode(sortedRedefines[i], name, componentType));
                     // Ignore this redefinition
-                    switch (componentType)
-                    {
-                    case SIMPLE_TYPE:
-                        sortedRedefines[i].redefineSimpleType(name); break;
-                    case COMPLEX_TYPE:
-                        sortedRedefines[i].redefineComplexType(name); break;
-                    case ATTRIBUTE_GROUP:
-                        sortedRedefines[i].redefineAttributeGroup(name); break;
-                    case MODEL_GROUP:
-                        sortedRedefines[i].redefineModelGroup(name); break;
+                    switch (componentType) {
+                        case SIMPLE_TYPE:
+                            sortedRedefines[i].redefineSimpleType(name);
+                            break;
+                        case COMPLEX_TYPE:
+                            sortedRedefines[i].redefineComplexType(name);
+                            break;
+                        case ATTRIBUTE_GROUP:
+                            sortedRedefines[i].redefineAttributeGroup(name);
+                            break;
+                        case MODEL_GROUP:
+                            sortedRedefines[i].redefineModelGroup(name);
+                            break;
                     }
                     sortedRedefines[i] = null;
                 }
@@ -678,94 +549,92 @@
             return sortedRedefines;
         }
 
-        private String componentNameFromCode(short code)
-        {
+        private String componentNameFromCode(short code) {
             String componentName;
-            switch (code)
-            {
-            case SIMPLE_TYPE: componentName = "simple type"; break;
-            case COMPLEX_TYPE: componentName = "complex type"; break;
-            case MODEL_GROUP: componentName = "model group"; break;
-            case ATTRIBUTE_GROUP: componentName = "attribute group"; break;
-            default: componentName = "";
+            switch (code) {
+                case SIMPLE_TYPE:
+                    componentName = "simple type";
+                    break;
+                case COMPLEX_TYPE:
+                    componentName = "complex type";
+                    break;
+                case MODEL_GROUP:
+                    componentName = "model group";
+                    break;
+                case ATTRIBUTE_GROUP:
+                    componentName = "attribute group";
+                    break;
+                default:
+                    componentName = "";
             }
             return componentName;
         }
 
         private XmlObject locationFromRedefinitionAndCode(RedefinitionHolder redefinition,
-            String name, short code)
-        {
+                                                          String name, short code) {
             XmlObject location;
-            switch (code)
-            {
-            case SIMPLE_TYPE:
-                location = (XmlObject) redefinition.stRedefinitions.get(name);
-                break;
-            case COMPLEX_TYPE:
-                location = (XmlObject) redefinition.ctRedefinitions.get(name);
-                break;
-            case MODEL_GROUP:
-                location = (XmlObject) redefinition.mgRedefinitions.get(name);
-                break;
-            case ATTRIBUTE_GROUP:
-                location = (XmlObject) redefinition.agRedefinitions.get(name);
-                break;
-            default:
-                location = null;
+            switch (code) {
+                case SIMPLE_TYPE:
+                    location = redefinition.stRedefinitions.get(name);
+                    break;
+                case COMPLEX_TYPE:
+                    location = redefinition.ctRedefinitions.get(name);
+                    break;
+                case MODEL_GROUP:
+                    location = redefinition.mgRedefinitions.get(name);
+                    break;
+                case ATTRIBUTE_GROUP:
+                    location = redefinition.agRedefinitions.get(name);
+                    break;
+                default:
+                    location = null;
             }
             return location;
         }
     }
 
-    private static String findFilename(XmlObject xobj)
-    {
+    private static String findFilename(XmlObject xobj) {
         return StscState.get().sourceNameForUri(xobj.documentProperties().getSourceName());
     }
 
-    private static SchemaTypeImpl translateDocumentType ( TopLevelElement xsdType, String targetNamespace, boolean chameleon )
-    {
-        SchemaTypeImpl sType = new SchemaTypeImpl( StscState.get().getContainer(targetNamespace) );
+    private static SchemaTypeImpl translateDocumentType(TopLevelElement xsdType, String targetNamespace, boolean chameleon) {
+        SchemaTypeImpl sType = new SchemaTypeImpl(StscState.get().getContainer(targetNamespace));
 
         sType.setDocumentType(true);
-        sType.setParseContext( xsdType, targetNamespace, chameleon, null, null, false);
-        sType.setFilename( findFilename( xsdType ) );
+        sType.setParseContext(xsdType, targetNamespace, chameleon, null, null, false);
+        sType.setFilename(findFilename(xsdType));
 
         return sType;
     }
 
-    private static SchemaTypeImpl translateAttributeType ( TopLevelAttribute xsdType, String targetNamespace, boolean chameleon )
-    {
-        SchemaTypeImpl sType = new SchemaTypeImpl( StscState.get().getContainer(targetNamespace) );
+    private static SchemaTypeImpl translateAttributeType(TopLevelAttribute xsdType, String targetNamespace, boolean chameleon) {
+        SchemaTypeImpl sType = new SchemaTypeImpl(StscState.get().getContainer(targetNamespace));
 
         sType.setAttributeType(true);
-        sType.setParseContext( xsdType, targetNamespace, chameleon, null, null, false);
-        sType.setFilename( findFilename( xsdType ) );
+        sType.setParseContext(xsdType, targetNamespace, chameleon, null, null, false);
+        sType.setFilename(findFilename(xsdType));
 
         return sType;
     }
 
-    private static SchemaTypeImpl translateGlobalComplexType(TopLevelComplexType xsdType, String targetNamespace, boolean chameleon, boolean redefinition)
-    {
+    private static SchemaTypeImpl translateGlobalComplexType(TopLevelComplexType xsdType, String targetNamespace, boolean chameleon, boolean redefinition) {
         StscState state = StscState.get();
 
         String localname = xsdType.getName();
-        if (localname == null)
-        {
-            state.error(XmlErrorCodes.MISSING_NAME, new Object[] { "global type" }, xsdType);
+        if (localname == null) {
+            state.error(XmlErrorCodes.MISSING_NAME, new Object[]{"global type"}, xsdType);
             // recovery: ignore unnamed types.
             return null;
         }
-        if (!XMLChar.isValidNCName(localname))
-        {
-            state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { localname, "name" }, xsdType.xgetName());
+        if (!XMLChar.isValidNCName(localname)) {
+            state.error(XmlErrorCodes.INVALID_VALUE, new Object[]{localname, "name"}, xsdType.xgetName());
             // recovery: let the name go through anyway.
         }
 
         QName name = QNameHelper.forLNS(localname, targetNamespace);
 
-        if (isReservedTypeName(name))
-        {
-            state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[] { QNameHelper.pretty(name) }, xsdType);
+        if (isReservedTypeName(name)) {
+            state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[]{QNameHelper.pretty(name)}, xsdType);
             return null;
         }
         // System.err.println("Recording type " + QNameHelper.pretty(name));
@@ -779,28 +648,24 @@
         return sType;
     }
 
-    private static SchemaTypeImpl translateGlobalSimpleType(TopLevelSimpleType xsdType, String targetNamespace, boolean chameleon, boolean redefinition)
-    {
+    private static SchemaTypeImpl translateGlobalSimpleType(TopLevelSimpleType xsdType, String targetNamespace, boolean chameleon, boolean redefinition) {
         StscState state = StscState.get();
 
         String localname = xsdType.getName();
-        if (localname == null)
-        {
-            state.error(XmlErrorCodes.MISSING_NAME, new Object[] { "global type" }, xsdType);
+        if (localname == null) {
+            state.error(XmlErrorCodes.MISSING_NAME, new Object[]{"global type"}, xsdType);
             // recovery: ignore unnamed types.
             return null;
         }
-        if (!XMLChar.isValidNCName(localname))
-        {
-            state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { localname, "name" }, xsdType.xgetName());
+        if (!XMLChar.isValidNCName(localname)) {
+            state.error(XmlErrorCodes.INVALID_VALUE, new Object[]{localname, "name"}, xsdType.xgetName());
             // recovery: let the name go through anyway.
         }
 
         QName name = QNameHelper.forLNS(localname, targetNamespace);
 
-        if (isReservedTypeName(name))
-        {
-            state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[] { QNameHelper.pretty(name) }, xsdType);
+        if (isReservedTypeName(name)) {
+            state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[]{QNameHelper.pretty(name)}, xsdType);
             return null;
         }
         // System.err.println("Recording type " + QNameHelper.pretty(name));
@@ -815,10 +680,10 @@
         return sType;
     }
 
-    /*package*/ static SchemaTypeImpl translateAnonymousSimpleType(SimpleType typedef,
-        String targetNamespace, boolean chameleon, String elemFormDefault,
-        String attFormDefault, List anonymousTypes, SchemaType outerType)
-    {
+    /*package*/
+    static SchemaTypeImpl translateAnonymousSimpleType(SimpleType typedef,
+                                                       String targetNamespace, boolean chameleon, String elemFormDefault,
+                                                       String attFormDefault, List<SchemaType> anonymousTypes, SchemaType outerType) {
         StscState state = StscState.get();
         SchemaTypeImpl sType = new SchemaTypeImpl(state.getContainer(targetNamespace));
         sType.setSimpleType(true);
@@ -831,44 +696,44 @@
         return sType;
     }
 
-    static FormChoice findElementFormDefault(XmlObject obj)
-    {
+    static FormChoice findElementFormDefault(XmlObject obj) {
         XmlCursor cur = obj.newCursor();
-        while (cur.getObject().schemaType() != Schema.type)
-            if (!cur.toParent())
+        while (cur.getObject().schemaType() != Schema.type) {
+            if (!cur.toParent()) {
                 return null;
-        return ((Schema)cur.getObject()).xgetElementFormDefault();
+            }
+        }
+        return ((Schema) cur.getObject()).xgetElementFormDefault();
     }
 
-    public static boolean uriMatch(String s1, String s2)
-    {
-        if (s1 == null)
+    public static boolean uriMatch(String s1, String s2) {
+        if (s1 == null) {
             return s2 == null || s2.equals("");
-        if (s2 == null)
+        }
+        if (s2 == null) {
             return s1.equals("");
+        }
         return s1.equals(s2);
     }
 
-    public static void copyGlobalElementToLocalElement(SchemaGlobalElement referenced, SchemaLocalElementImpl target )
-    {
+    public static void copyGlobalElementToLocalElement(SchemaGlobalElement referenced, SchemaLocalElementImpl target) {
 
         target.setNameAndTypeRef(referenced.getName(), referenced.getType().getRef());
         target.setNillable(referenced.isNillable());
-        target.setDefault(referenced.getDefaultText(), referenced.isFixed(), ((SchemaGlobalElementImpl)referenced).getParseObject());
-        target.setIdentityConstraints(((SchemaLocalElementImpl)referenced).getIdentityConstraintRefs());
-        target.setBlock(referenced.blockExtension(),  referenced.blockRestriction(),  referenced.blockSubstitution());
+        target.setDefault(referenced.getDefaultText(), referenced.isFixed(), ((SchemaGlobalElementImpl) referenced).getParseObject());
+        target.setIdentityConstraints(((SchemaLocalElementImpl) referenced).getIdentityConstraintRefs());
+        target.setBlock(referenced.blockExtension(), referenced.blockRestriction(), referenced.blockSubstitution());
         target.setAbstract(referenced.isAbstract());
-        target.setTransitionRules(((SchemaParticle)referenced).acceptedStartNames(),
-            ((SchemaParticle)referenced).isSkippable());
+        target.setTransitionRules(((SchemaParticle) referenced).acceptedStartNames(),
+            ((SchemaParticle) referenced).isSkippable());
         target.setAnnotation(referenced.getAnnotation());
     }
 
-    public static void copyGlobalAttributeToLocalAttribute(SchemaGlobalAttributeImpl referenced, SchemaLocalAttributeImpl target )
-    {
+    public static void copyGlobalAttributeToLocalAttribute(SchemaGlobalAttributeImpl referenced, SchemaLocalAttributeImpl target) {
         target.init(
             referenced.getName(), referenced.getTypeRef(), referenced.getUse(),
             referenced.getDefaultText(),
-                referenced.getParseObject(), referenced._defaultValue,
+            referenced.getParseObject(), referenced._defaultValue,
             referenced.isFixed(),
             referenced.getWSDLArrayType(),
             referenced.getAnnotation(), null);
@@ -882,119 +747,102 @@
     public static SchemaLocalElementImpl translateElement(
         Element xsdElt, String targetNamespace, boolean chameleon,
         String elemFormDefault, String attFormDefault,
-        List anonymousTypes, SchemaType outerType)
-    {
+        List<SchemaType> anonymousTypes, SchemaType outerType) {
         StscState state = StscState.get();
 
         SchemaTypeImpl sgHead = null;
 
         // translate sg head
-        if (xsdElt.isSetSubstitutionGroup())
-        {
+        if (xsdElt.isSetSubstitutionGroup()) {
             sgHead = state.findDocumentType(xsdElt.getSubstitutionGroup(),
-                ((SchemaTypeImpl)outerType).getChameleonNamespace(), targetNamespace);
+                ((SchemaTypeImpl) outerType).getChameleonNamespace(), targetNamespace);
 
-            if (sgHead != null)
+            if (sgHead != null) {
                 StscResolver.resolveType(sgHead);
+            }
         }
 
         String name = xsdElt.getName();
         QName ref = xsdElt.getRef();
 
 
-        if (ref != null && name != null)
-        {
+        if (ref != null && name != null) {
             // if (name.equals(ref.getLocalPart()) && uriMatch(targetNamespace, ref.getNamespaceURI()))
             //     state.warning("Element " + name + " specifies both a ref and a name", XmlErrorCodes.ELEMENT_EXTRA_REF, xsdElt.xgetRef());
             // else
-                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdElt.xgetRef());
+            state.error(XmlErrorCodes.SCHEMA_ELEM$REF_OR_NAME_HAS_BOTH, new Object[]{name}, xsdElt.xgetRef());
             // ignore name
             name = null;
         }
-        if (ref == null && name == null)
-        {
+        if (ref == null && name == null) {
             state.error(XmlErrorCodes.SCHEMA_ELEM$REF_OR_NAME_HAS_NEITHER, null, xsdElt);
             // recovery: ignore this element
             return null;
         }
-        if (name != null && !XMLChar.isValidNCName(name))
-        {
-            state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { name, "name" }, xsdElt.xgetName());
+        if (name != null && !XMLChar.isValidNCName(name)) {
+            state.error(XmlErrorCodes.INVALID_VALUE, new Object[]{name, "name"}, xsdElt.xgetName());
             // recovery: let the name go through anyway.
         }
 
-        if (ref != null)
-        {
-            if (xsdElt.getType() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "type" }, xsdElt.xgetType());
+        if (ref != null) {
+            if (xsdElt.getType() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"type"}, xsdElt.xgetType());
                 // recovery: let the name go through anyway.
             }
 
-            if (xsdElt.getSimpleType() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "<simpleType>" }, xsdElt.getSimpleType());
+            if (xsdElt.getSimpleType() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"<simpleType>"}, xsdElt.getSimpleType());
                 // recovery: let the name go through anyway.
             }
 
-            if (xsdElt.getComplexType() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "<complexType>" }, xsdElt.getComplexType());
+            if (xsdElt.getComplexType() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"<complexType>"}, xsdElt.getComplexType());
                 // recovery: let the name go through anyway.
             }
 
-            if (xsdElt.getForm() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "form" }, xsdElt.xgetForm());
+            if (xsdElt.getForm() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"form"}, xsdElt.xgetForm());
                 // recovery: let the name go through anyway.
             }
 
-            if (xsdElt.sizeOfKeyArray() > 0)
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "<key>" }, xsdElt);
+            if (xsdElt.sizeOfKeyArray() > 0) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"<key>"}, xsdElt);
                 // recovery: ignore
             }
 
-            if (xsdElt.sizeOfKeyrefArray() > 0)
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "<keyref>" }, xsdElt);
+            if (xsdElt.sizeOfKeyrefArray() > 0) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"<keyref>"}, xsdElt);
                 // recovery: ignore
             }
 
-            if (xsdElt.sizeOfUniqueArray() > 0)
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "<unique>" }, xsdElt);
+            if (xsdElt.sizeOfUniqueArray() > 0) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"<unique>"}, xsdElt);
                 // recovery: ignore
             }
 
-            if (xsdElt.isSetDefault())
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "default" }, xsdElt.xgetDefault());
+            if (xsdElt.isSetDefault()) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"default"}, xsdElt.xgetDefault());
                 // recovery: ignore
             }
 
-            if (xsdElt.isSetFixed())
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "fixed" }, xsdElt.xgetFixed());
+            if (xsdElt.isSetFixed()) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"fixed"}, xsdElt.xgetFixed());
                 // recovery: ignore
             }
 
-            if (xsdElt.isSetBlock())
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "block" }, xsdElt.xgetBlock());
+            if (xsdElt.isSetBlock()) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"block"}, xsdElt.xgetBlock());
                 // recovery: ignore
             }
 
-            if (xsdElt.isSetNillable())
-            {
-                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "nillable" }, xsdElt.xgetNillable());
+            if (xsdElt.isSetNillable()) {
+                state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[]{"nillable"}, xsdElt.xgetNillable());
                 // recovery: ignore
             }
 
-            assert(xsdElt instanceof LocalElement);
+            assert (xsdElt instanceof LocalElement);
             SchemaGlobalElement referenced = state.findGlobalElement(ref, chameleon ? targetNamespace : null, targetNamespace);
-            if (referenced == null)
-            {
+            if (referenced == null) {
                 state.notFoundError(ref, SchemaType.ELEMENT, xsdElt.xgetRef(), true);
                 // recovery: ignore this element
                 return null;
@@ -1002,7 +850,7 @@
             SchemaLocalElementImpl target = new SchemaLocalElementImpl();
             target.setParticleType(SchemaParticle.ELEMENT);
             target.setUserData(getUserData(xsdElt));
-            copyGlobalElementToLocalElement( referenced, target );
+            copyGlobalElementToLocalElement(referenced, target);
             return target;
         }
 
@@ -1010,48 +858,43 @@
         SchemaLocalElementImpl impl;
         SchemaType sType = null;
 
-        if (xsdElt instanceof LocalElement)
-        {
+        if (xsdElt instanceof LocalElement) {
             impl = new SchemaLocalElementImpl();
-            boolean qualified = false; // default
+            boolean qualified;
             FormChoice form = xsdElt.xgetForm();
-            if (form != null)
+            if (form != null) {
                 qualified = form.getStringValue().equals(FORM_QUALIFIED);
-            else if (elemFormDefault != null)
+            } else if (elemFormDefault != null) {
                 qualified = elemFormDefault.equals(FORM_QUALIFIED);
-            else
-            {
+            } else {
                 form = findElementFormDefault(xsdElt);
                 qualified = form != null && form.getStringValue().equals(FORM_QUALIFIED);
             }
 
             qname = qualified ? QNameHelper.forLNS(name, targetNamespace) : QNameHelper.forLN(name);
-        }
-        else
-        {
+        } else {
             SchemaGlobalElementImpl gelt = new SchemaGlobalElementImpl(state.getContainer(targetNamespace));
             impl = gelt;
 
             // Set subst group head
-            if (sgHead != null)
-            {
+            if (sgHead != null) {
                 SchemaGlobalElementImpl head = state.findGlobalElement(xsdElt.getSubstitutionGroup(), chameleon ? targetNamespace : null, targetNamespace);
-                if (head != null)
+                if (head != null) {
                     gelt.setSubstitutionGroup(head.getRef());
+                }
             }
 
             // Set subst group members
             qname = QNameHelper.forLNS(name, targetNamespace);
-            SchemaTypeImpl docType = (SchemaTypeImpl)outerType;
+            SchemaTypeImpl docType = (SchemaTypeImpl) outerType;
 
             QName[] sgMembers = docType.getSubstitutionGroupMembers();
             QNameSetBuilder transitionRules = new QNameSetBuilder();
             transitionRules.add(qname);
 
-            for (int i = 0 ; i < sgMembers.length ; i++)
-            {
-                gelt.addSubstitutionGroupMember(sgMembers[i]);
-                transitionRules.add(sgMembers[i]);
+            for (QName sgMember : sgMembers) {
+                gelt.addSubstitutionGroupMember(sgMember);
+                transitionRules.add(sgMember);
             }
 
             impl.setTransitionRules(QNameSet.forSpecification(transitionRules), false);
@@ -1060,19 +903,18 @@
             boolean finalExt = false;
             boolean finalRest = false;
             Object ds = xsdElt.getFinal();
-            if (ds != null)
-            {
-                if (ds instanceof String && ds.equals("#all"))
-                {
+            if (ds != null) {
+                if (ds instanceof String && ds.equals("#all")) {
                     // #ALL value
                     finalExt = finalRest = true;
-                }
-                else if (ds instanceof List)
-                {
-                    if (((List)ds).contains("extension"))
+                } else if (ds instanceof List) {
+                    List<?> dsList = (List<?>) ds;
+                    if (dsList.contains("extension")) {
                         finalExt = true;
-                    if (((List)ds).contains("restriction"))
+                    }
+                    if (dsList.contains("restriction")) {
                         finalRest = true;
+                    }
                 }
             }
 
@@ -1085,94 +927,86 @@
         SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), xsdElt);
         impl.setAnnotation(ann);
         impl.setUserData(getUserData(xsdElt));
-        if (xsdElt.getType() != null)
-        {
-            sType = state.findGlobalType(xsdElt.getType(), chameleon ? targetNamespace : null, targetNamespace );
-            if (sType == null)
+        if (xsdElt.getType() != null) {
+            sType = state.findGlobalType(xsdElt.getType(), chameleon ? targetNamespace : null, targetNamespace);
+            if (sType == null) {
                 state.notFoundError(xsdElt.getType(), SchemaType.TYPE, xsdElt.xgetType(), true);
+            }
         }
 
         boolean simpleTypedef = false;
         Annotated typedef = xsdElt.getComplexType();
-        if (typedef == null)
-        {
+        if (typedef == null) {
             typedef = xsdElt.getSimpleType();
             simpleTypedef = true;
         }
 
-        if ((sType != null) && typedef != null)
-        {
+        if ((sType != null) && typedef != null) {
             state.error(XmlErrorCodes.SCHEMA_ELEM$TYPE_ATTR_OR_NESTED_TYPE, null, typedef);
             typedef = null;
         }
 
-        if (typedef != null)
-        {
+        if (typedef != null) {
             Object[] grps = state.getCurrentProcessing();
             QName[] context = new QName[grps.length];
-            for (int i = 0; i < context.length; i++)
-                if (grps[i] instanceof SchemaModelGroupImpl)
-                    context[i] = ((SchemaModelGroupImpl ) grps[i]).getName();
-            SchemaType repeat = checkRecursiveGroupReference(context, qname, (SchemaTypeImpl)outerType);
-            if (repeat != null)
+            for (int i = 0; i < context.length; i++) {
+                if (grps[i] instanceof SchemaModelGroupImpl) {
+                    context[i] = ((SchemaModelGroupImpl) grps[i]).getName();
+                }
+            }
+            SchemaType repeat = checkRecursiveGroupReference(context, qname, (SchemaTypeImpl) outerType);
+            if (repeat != null) {
                 sType = repeat;
-            else
-            {
-            SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.getContainer(targetNamespace));
-            sType = sTypeImpl;
-            sTypeImpl.setContainerField(impl);
-            sTypeImpl.setOuterSchemaTypeRef(outerType == null ? null : outerType.getRef());
-            sTypeImpl.setGroupReferenceContext(context);
-            // leave the anonymous type unresolved: it will be resolved later.
-            anonymousTypes.add(sType);
-            sTypeImpl.setSimpleType(simpleTypedef);
-            sTypeImpl.setParseContext(typedef, targetNamespace, chameleon,
-                 elemFormDefault, attFormDefault, false);
-            sTypeImpl.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), typedef));
-            sTypeImpl.setUserData(getUserData(typedef));
+            } else {
+                SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.getContainer(targetNamespace));
+                sType = sTypeImpl;
+                sTypeImpl.setContainerField(impl);
+                sTypeImpl.setOuterSchemaTypeRef(outerType == null ? null : outerType.getRef());
+                sTypeImpl.setGroupReferenceContext(context);
+                // leave the anonymous type unresolved: it will be resolved later.
+                anonymousTypes.add(sType);
+                sTypeImpl.setSimpleType(simpleTypedef);
+                sTypeImpl.setParseContext(typedef, targetNamespace, chameleon,
+                    elemFormDefault, attFormDefault, false);
+                sTypeImpl.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), typedef));
+                sTypeImpl.setUserData(getUserData(typedef));
             }
         }
 
-        if (sType == null)
-        {
+        if (sType == null) {
             // type may inherit from substitution group head
-            if (sgHead != null)
-            {
+            if (sgHead != null) {
                 SchemaGlobalElement head = state.findGlobalElement(xsdElt.getSubstitutionGroup(), chameleon ? targetNamespace : null, targetNamespace);
 
                 // Bug - Do I need to copy the type if it's anonymous?
                 // If element does not exist, error has already been reported
-                if (head != null)
+                if (head != null) {
                     sType = head.getType();
+                }
             }
 
         }
 
 
-
-        if (sType == null)
+        if (sType == null) {
             sType = BuiltinSchemaTypeSystem.ST_ANY_TYPE;
+        }
 
         SOAPArrayType wat = null;
         XmlCursor c = xsdElt.newCursor();
         String arrayType = c.getAttributeText(WSDL_ARRAYTYPE_NAME);
         c.dispose();
-        if (arrayType != null)
-        {
-            try
-            {
+        if (arrayType != null) {
+            try {
                 wat = new SOAPArrayType(arrayType, new NamespaceContext(xsdElt));
-            }
-            catch (XmlValueOutOfRangeException e)
-            {
-                state.error(XmlErrorCodes.SOAPARRAY, new Object[] {arrayType}, xsdElt);
+            } catch (XmlValueOutOfRangeException e) {
+                state.error(XmlErrorCodes.SOAPARRAY, new Object[]{arrayType}, xsdElt);
             }
         }
         impl.setWsdlArrayType(wat);
 
         boolean isFixed = xsdElt.isSetFixed();
-        if (xsdElt.isSetDefault() && isFixed)
-        {
+        if (xsdElt.isSetDefault() && isFixed) {
             state.error(XmlErrorCodes.SCHEMA_ELEM$DEFAULT_OR_FIXED, null, xsdElt.xgetFixed());
             // recovery: ignore fixed
             isFixed = false;
@@ -1187,21 +1021,21 @@
         boolean blockRest = false;
         boolean blockSubst = false;
 
-        if (block != null)
-        {
-            if (block instanceof String && block.equals("#all"))
-            {
+        if (block != null) {
+            if (block instanceof String && block.equals("#all")) {
                 // #ALL value
                 blockExt = blockRest = blockSubst = true;
-            }
-            else if (block instanceof List)
-            {
-                if (((List)block).contains("extension"))
+            } else if (block instanceof List) {
+                List<?> blockList = (List<?>) block;
+                if (blockList.contains("extension")) {
                     blockExt = true;
-                if (((List)block).contains("restriction"))
+                }
+                if (blockList.contains("restriction")) {
                     blockRest = true;
-                if (((List)block).contains("substitution"))
+                }
+                if (blockList.contains("substitution")) {
                     blockSubst = true;
+                }
             }
         }
 
@@ -1217,39 +1051,42 @@
 
         // Handle key constraints
         Keybase[] keys = xsdElt.getKeyArray();
-        for (int i = 0 ; i < keys.length ; i++, cur++) {
+        for (int i = 0; i < keys.length; i++, cur++) {
             constraints[cur] = translateIdentityConstraint(keys[i], targetNamespace, chameleon);
-            if (constraints[cur] != null)
+            if (constraints[cur] != null) {
                 constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_KEY);
-            else
+            } else {
                 constraintFailed = true;
+            }
         }
 
         // Handle unique constraints
         Keybase[] uc = xsdElt.getUniqueArray();
-        for (int i = 0 ; i < uc.length ; i++, cur++) {
+        for (int i = 0; i < uc.length; i++, cur++) {
             constraints[cur] = translateIdentityConstraint(uc[i], targetNamespace, chameleon);
-            if (constraints[cur] != null)
+            if (constraints[cur] != null) {
                 constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_UNIQUE);
-            else
+            } else {
                 constraintFailed = true;
+            }
         }
 
         // Handle keyref constraints
         KeyrefDocument.Keyref[] krs = xsdElt.getKeyrefArray();
-        for (int i = 0 ; i < krs.length ; i++, cur++) {
+        for (int i = 0; i < krs.length; i++, cur++) {
             constraints[cur] = translateIdentityConstraint(krs[i], targetNamespace, chameleon);
-            if (constraints[cur] != null)
+            if (constraints[cur] != null) {
                 constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_KEYREF);
-            else
+            } else {
                 constraintFailed = true;
+            }
         }
 
-        if (!constraintFailed)
-        {
+        if (!constraintFailed) {
             SchemaIdentityConstraint.Ref[] refs = new SchemaIdentityConstraint.Ref[length];
-            for (int i = 0 ; i < refs.length ; i++)
+            for (int i = 0; i < refs.length; i++) {
                 refs[i] = constraints[i].getRef();
+            }
 
             impl.setIdentityConstraints(refs);
         }
@@ -1260,13 +1097,13 @@
     /**
      * We need to do this because of the following kind of Schemas:
      * <xs:group name="e">
-     *     <xs:sequence>
-     *         <xs:element name="error">
-     *             <xs:complexType>
-     *                 <xs:group ref="e"/>
-     *             </xs:complexType>
-     *         </xs:element>
-     *     </xs:sequence>
+     * <xs:sequence>
+     * <xs:element name="error">
+     * <xs:complexType>
+     * <xs:group ref="e"/>
+     * </xs:complexType>
+     * </xs:element>
+     * </xs:sequence>
      * </xs:group>
      * (see JIRA bug XMLBEANS-35)
      * Even though this should not be allowed because it produces an infinite
@@ -1280,32 +1117,31 @@
      * and if the same pattern is about to repeat, it means that we are in a
      * case similar to the above.
      */
-    private static SchemaType checkRecursiveGroupReference(QName[] context, QName containingElement, SchemaTypeImpl outerType)
-    {
-        if (context.length < 1)
+    private static SchemaType checkRecursiveGroupReference(QName[] context, QName containingElement, SchemaTypeImpl outerType) {
+        if (context.length < 1) {
             return null;
+        }
         SchemaTypeImpl type = outerType;
 
-        while (type != null)
-        {
-            if (type.getName() != null || type.isDocumentType())
+        while (type != null) {
+            if (type.getName() != null || type.isDocumentType()) {
                 return null; // not anonymous
-            if (containingElement.equals(type.getContainerField().getName()))
-            {
+            }
+            if (containingElement.equals(type.getContainerField().getName())) {
                 QName[] outerContext = type.getGroupReferenceContext();
-                if (outerContext != null && outerContext.length == context.length)
-                {
+                if (outerContext != null && outerContext.length == context.length) {
                     // Smells like trouble
                     boolean equal = true;
-                    for (int i = 0; i < context.length; i++)
+                    for (int i = 0; i < context.length; i++) {
                         if (!(context[i] == null && outerContext[i] == null ||
-                              context[i] != null && context[i].equals(outerContext[i])))
-                        {
+                              context[i] != null && context[i].equals(outerContext[i]))) {
                             equal = false;
                             break;
                         }
-                    if (equal)
+                    }
+                    if (equal) {
                         return type;
+                    }
                 }
             }
             type = (SchemaTypeImpl) type.getOuterType();
@@ -1313,14 +1149,13 @@
         return null;
     }
 
-    private static String removeWhitespace(String xpath)
-    {
+    private static String removeWhitespace(String xpath) {
         StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < xpath.length(); i++)
-        {
+        for (int i = 0; i < xpath.length(); i++) {
             char ch = xpath.charAt(i);
-            if (XMLChar.isSpace(ch))
+            if (XMLChar.isSpace(ch)) {
                 continue;
+            }
             sb.append(ch);
         }
         return sb.toString();
@@ -1328,40 +1163,35 @@
 
     public static final org.apache.xmlbeans.impl.regex.RegularExpression XPATH_REGEXP = new org.apache.xmlbeans.impl.regex.RegularExpression("(\\.//)?((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)/)*((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)|((attribute::|@)((\\i\\c*:)?(\\i\\c*|\\*))))(\\|(\\.//)?((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)/)*((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)|((attribute::|@)((\\i\\c*:)?(\\i\\c*|\\*)))))*", "X");
 
-    private static boolean checkXPathSyntax(String xpath)
-    {
-        if (xpath == null)
+    private static boolean checkXPathSyntax(String xpath) {
+        if (xpath == null) {
             return false;
+        }
 
         // strip whitespace from xpath
         xpath = removeWhitespace(xpath);
 
         // apply regexp
-        synchronized (XPATH_REGEXP)
-        {
+        synchronized (XPATH_REGEXP) {
             return (XPATH_REGEXP.matches(xpath));
         }
     }
 
     private static SchemaIdentityConstraintImpl translateIdentityConstraint(Keybase parseIC,
-        String targetNamespace, boolean chameleon)
-    {
+                                                                            String targetNamespace, boolean chameleon) {
         StscState state = StscState.get();
 
         // first do some checking
         String selector = parseIC.getSelector() == null ? null : parseIC.getSelector().getXpath();
-        if (!checkXPathSyntax(selector))
-        {
-            state.error(XmlErrorCodes.SELECTOR_XPATH, new Object[] { selector }, parseIC.getSelector().xgetXpath());
+        if (!checkXPathSyntax(selector)) {
+            state.error(XmlErrorCodes.SELECTOR_XPATH, new Object[]{selector}, parseIC.getSelector().xgetXpath());
             return null;
         }
 
         FieldDocument.Field[] fieldElts = parseIC.getFieldArray();
-        for (int j = 0; j < fieldElts.length; j++)
-        {
-            if (!checkXPathSyntax(fieldElts[j].getXpath()))
-            {
-                state.error(XmlErrorCodes.FIELDS_XPATH, new Object[] { fieldElts[j].getXpath() }, fieldElts[j].xgetXpath());
+        for (FieldDocument.Field fieldElt : fieldElts) {
+            if (!checkXPathSyntax(fieldElt.getXpath())) {
+                state.error(XmlErrorCodes.FIELDS_XPATH, new Object[]{fieldElt.getXpath()}, fieldElt.xgetXpath());
                 return null;
             }
         }
@@ -1377,7 +1207,7 @@
 
         // Set the ns map
         XmlCursor c = parseIC.newCursor();
-        Map nsMap = new HashMap();
+        Map<String, String> nsMap = new HashMap<>();
 
         c.getAllNamespaces(nsMap);
         nsMap.remove(""); // Remove the default mapping. This cannot be used by the xpath expressions.
@@ -1385,15 +1215,15 @@
         c.dispose();
 
         String[] fields = new String[fieldElts.length];
-        for (int j = 0 ; j < fields.length ; j++)
+        for (int j = 0; j < fields.length; j++) {
             fields[j] = fieldElts[j].getXpath();
+        }
         ic.setFields(fields);
 
         try {
             ic.buildPaths();
-        }
-        catch (XPath.XPathCompileException e) {
-            state.error(XmlErrorCodes.INVALID_XPATH, new Object[] { e.getMessage() }, parseIC);
+        } catch (XPath.XPathCompileException e) {
+            state.error(XmlErrorCodes.INVALID_XPATH, new Object[]{e.getMessage()}, parseIC);
             return null;
         }
 
@@ -1404,12 +1234,10 @@
 
     }
 
-    public static SchemaModelGroupImpl translateModelGroup(NamedGroup namedGroup, String targetNamespace, boolean chameleon, boolean redefinition)
-    {
+    public static SchemaModelGroupImpl translateModelGroup(NamedGroup namedGroup, String targetNamespace, boolean chameleon, boolean redefinition) {
         String name = namedGroup.getName();
-        if (name == null)
-        {
-            StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[] { "model group" }, namedGroup);
+        if (name == null) {
+            StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[]{"model group"}, namedGroup);
             return null;
         }
         SchemaContainer c = StscState.get().getContainer(targetNamespace);
@@ -1425,12 +1253,10 @@
         return result;
     }
 
-    public static SchemaAttributeGroupImpl translateAttributeGroup(AttributeGroup attrGroup, String targetNamespace, boolean chameleon, boolean redefinition)
-    {
+    public static SchemaAttributeGroupImpl translateAttributeGroup(AttributeGroup attrGroup, String targetNamespace, boolean chameleon, boolean redefinition) {
         String name = attrGroup.getName();
-        if (name == null)
-        {
-            StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[] { "attribute group" }, attrGroup);
+        if (name == null) {
+            StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[]{"attribute group"}, attrGroup);
             return null;
         }
         SchemaContainer c = StscState.get().getContainer(targetNamespace);
@@ -1444,43 +1270,41 @@
         return result;
     }
 
-    static FormChoice findAttributeFormDefault(XmlObject obj)
-    {
+    static FormChoice findAttributeFormDefault(XmlObject obj) {
         XmlCursor cur = obj.newCursor();
-        while (cur.getObject().schemaType() != Schema.type)
-            if (!cur.toParent())
+        while (cur.getObject().schemaType() != Schema.type) {
+            if (!cur.toParent()) {
                 return null;
-        return ((Schema)cur.getObject()).xgetAttributeFormDefault();
+            }
+        }
+        return ((Schema) cur.getObject()).xgetAttributeFormDefault();
     }
 
     static SchemaLocalAttributeImpl translateAttribute(
         Attribute xsdAttr, String targetNamespace, String formDefault, boolean chameleon,
-        List anonymousTypes, SchemaType outerType, SchemaAttributeModel baseModel,
-        boolean local)
-    {
+        List<SchemaType> anonymousTypes, SchemaType outerType, SchemaAttributeModel baseModel,
+        boolean local) {
         StscState state = StscState.get();
 
         String name = xsdAttr.getName();
         QName ref = xsdAttr.getRef();
 
-        if (ref != null && name != null)
-        {
-            if (name.equals(ref.getLocalPart()) && uriMatch(targetNamespace, ref.getNamespaceURI()))
-                state.warning(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdAttr.xgetRef());
-            else
-                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdAttr.xgetRef());
+        if (ref != null && name != null) {
+            if (name.equals(ref.getLocalPart()) && uriMatch(targetNamespace, ref.getNamespaceURI())) {
+                state.warning(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[]{name}, xsdAttr.xgetRef());
+            } else {
+                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[]{name}, xsdAttr.xgetRef());
+            }
             // ignore name
             name = null;
         }
-        if (ref == null && name == null)
-        {
+        if (ref == null && name == null) {
             state.error(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_NEITHER, null, xsdAttr);
             // recovery: ignore this element
             return null;
         }
-        if (name != null && !XMLChar.isValidNCName(name))
-        {
-            state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { name, "name" }, xsdAttr.xgetName());
+        if (name != null && !XMLChar.isValidNCName(name)) {
+            state.error(XmlErrorCodes.INVALID_VALUE, new Object[]{name, "name"}, xsdAttr.xgetName());
             // recovery: let the name go through anyway.
         }
 
@@ -1492,37 +1316,31 @@
         SchemaType sType = null;
         int use = SchemaLocalAttribute.OPTIONAL;
 
-        if (local)
+        if (local) {
             sAttr = new SchemaLocalAttributeImpl();
-        else
-        {
-            sAttr = new SchemaGlobalAttributeImpl(state.get().getContainer(targetNamespace));
-            ((SchemaGlobalAttributeImpl)sAttr).setParseContext(xsdAttr, targetNamespace, chameleon);
+        } else {
+            sAttr = new SchemaGlobalAttributeImpl(StscState.get().getContainer(targetNamespace));
+            ((SchemaGlobalAttributeImpl) sAttr).setParseContext(xsdAttr, targetNamespace, chameleon);
         }
 
-        if (ref != null)
-        {
-            if (xsdAttr.getType() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "type" }, xsdAttr.xgetType());
+        if (ref != null) {
+            if (xsdAttr.getType() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[]{"type"}, xsdAttr.xgetType());
                 // recovery: ignore type, simpleType
             }
 
-            if (xsdAttr.getSimpleType() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "<simpleType>" }, xsdAttr.getSimpleType());
+            if (xsdAttr.getSimpleType() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[]{"<simpleType>"}, xsdAttr.getSimpleType());
                 // recovery: ignore type, simpleType
             }
 
-            if (xsdAttr.getForm() != null)
-            {
-                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "form" }, xsdAttr.xgetForm());
+            if (xsdAttr.getForm() != null) {
+                state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[]{"form"}, xsdAttr.xgetForm());
                 // recovery: ignore form
             }
 
             SchemaGlobalAttribute referenced = state.findGlobalAttribute(ref, chameleon ? targetNamespace : null, targetNamespace);
-            if (referenced == null)
-            {
+            if (referenced == null) {
                 state.notFoundError(ref, SchemaType.ATTRIBUTE, xsdAttr.xgetRef(), true);
                 // recovery: ignore this element
                 return null;
@@ -1532,63 +1350,53 @@
             use = referenced.getUse();
             sType = referenced.getType();
             deftext = referenced.getDefaultText();
-            if (deftext != null)
-            {
+            if (deftext != null) {
                 isFixed = referenced.isFixed();
-                if (isFixed)
+                if (isFixed) {
                     fmrfixedtext = deftext;
+                }
             }
-        }
-        else
-        {
-            if (local)
-            {
-                boolean qualified = false; // default
+        } else {
+            if (local) {
+                boolean qualified;
                 FormChoice form = xsdAttr.xgetForm();
-                if (form != null)
+                if (form != null) {
                     qualified = form.getStringValue().equals(FORM_QUALIFIED);
-                else if (formDefault != null)
+                } else if (formDefault != null) {
                     qualified = formDefault.equals(FORM_QUALIFIED);
-                else
-                {
+                } else {
                     form = findAttributeFormDefault(xsdAttr);
                     qualified = form != null && form.getStringValue().equals(FORM_QUALIFIED);
                 }
 
                 qname = qualified ? QNameHelper.forLNS(name, targetNamespace) : QNameHelper.forLN(name);
-            }
-            else
-            {
+            } else {
                 qname = QNameHelper.forLNS(name, targetNamespace);
             }
 
-            if (xsdAttr.getType() != null)
-            {
-                sType = state.findGlobalType(xsdAttr.getType(), chameleon ? targetNamespace : null, targetNamespace );
-                if (sType == null)
+            if (xsdAttr.getType() != null) {
+                sType = state.findGlobalType(xsdAttr.getType(), chameleon ? targetNamespace : null, targetNamespace);
+                if (sType == null) {
                     state.notFoundError(xsdAttr.getType(), SchemaType.TYPE, xsdAttr.xgetType(), true);
+                }
             }
 
-            if (qname.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema-instance"))
-            {
-                state.error(XmlErrorCodes.NO_XSI, new Object[] { "http://www.w3.org/2001/XMLSchema-instance" }, xsdAttr.xgetName());
+            if (qname.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema-instance")) {
+                state.error(XmlErrorCodes.NO_XSI, new Object[]{"http://www.w3.org/2001/XMLSchema-instance"}, xsdAttr.xgetName());
             }
 
-            if (qname.getNamespaceURI().length() == 0 && qname.getLocalPart().equals("xmlns"))
-            {
+            if (qname.getNamespaceURI().length() == 0 && qname.getLocalPart().equals("xmlns")) {
                 state.error(XmlErrorCodes.NO_XMLNS, null, xsdAttr.xgetName());
             }
 
             LocalSimpleType typedef = xsdAttr.getSimpleType();
 
-            if ((sType != null) && typedef != null)
-            {
+            if ((sType != null) && typedef != null) {
                 state.error(XmlErrorCodes.SCHEMA_ATTR$TYPE_ATTR_OR_NESTED_TYPE, null, typedef);
                 typedef = null;
             }
 
-            if (typedef != null)
-            {
+            if (typedef != null) {
                 SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.getContainer(targetNamespace));
                 sType = sTypeImpl;
                 sTypeImpl.setContainerField(sAttr);
@@ -1601,39 +1409,39 @@
                 sTypeImpl.setUserData(getUserData(typedef));
             }
 
-            if (sType == null && baseModel != null && baseModel.getAttribute(qname) != null)
+            if (sType == null && baseModel != null && baseModel.getAttribute(qname) != null) {
                 sType = baseModel.getAttribute(qname).getType();
+            }
         }
 
-        if (sType == null)
+        if (sType == null) {
             sType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
+        }
 
-        if (!sType.isSimpleType())
-        {
+        if (!sType.isSimpleType()) {
             // KHK: which rule? could use #a-simple_type_definition
             state.error("Attributes must have a simple type (not complex).", XmlErrorCodes.INVALID_SCHEMA, xsdAttr);
             // recovery: switch to the any-type
             sType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE;
         }
 
-        if (xsdAttr.isSetUse())
-        {
+        if (xsdAttr.isSetUse()) {
             use = translateUseCode(xsdAttr.xgetUse());
 
             // ignore referenced default if no longer optional
-            if (use != SchemaLocalAttribute.OPTIONAL && !isFixed)
+            if (use != SchemaLocalAttribute.OPTIONAL && !isFixed) {
                 deftext = null;
+            }
         }
 
-        if (xsdAttr.isSetDefault() || xsdAttr.isSetFixed())
-        {
-            if (isFixed && !xsdAttr.isSetFixed())
+        if (xsdAttr.isSetDefault() || xsdAttr.isSetFixed()) {
+            if (isFixed && !xsdAttr.isSetFixed()) {
                 state.error("A use of a fixed attribute definition must also be fixed", XmlErrorCodes.REDUNDANT_DEFAULT_FIXED, xsdAttr.xgetFixed());
+            }
 
             isFixed = xsdAttr.isSetFixed();
 
-            if (xsdAttr.isSetDefault() && isFixed)
-            {
+            if (xsdAttr.isSetDefault() && isFixed) {
                 state.error(XmlErrorCodes.SCHEMA_ATTR$DEFAULT_OR_FIXED, null, xsdAttr.xgetFixed());
                 // recovery: ignore fixed
                 isFixed = false;
@@ -1641,32 +1449,26 @@
             deftext = isFixed ? xsdAttr.getFixed() : xsdAttr.getDefault();
             // BUGBUG(radup) this is not good, since they should be compared by value
             // in StscChecker; but there we don't have yet access to the referred attr
-            if (fmrfixedtext != null && !fmrfixedtext.equals(deftext))
-            {
+            if (fmrfixedtext != null && !fmrfixedtext.equals(deftext)) {
                 state.error(XmlErrorCodes.SCHEMA_ATTR$FIXED_NOT_MATCH, null, xsdAttr.xgetFixed());
                 // recovery: reset fixed to the original value
                 deftext = fmrfixedtext;
             }
         }
 
-        if (!local)
-        {
-            ((SchemaGlobalAttributeImpl)sAttr).setFilename(findFilename(xsdAttr));
+        if (!local) {
+            ((SchemaGlobalAttributeImpl) sAttr).setFilename(findFilename(xsdAttr));
         }
 
         SOAPArrayType wat = null;
         XmlCursor c = xsdAttr.newCursor();
         String arrayType = c.getAttributeText(WSDL_ARRAYTYPE_NAME);
         c.dispose();
-        if (arrayType != null)
-        {
-            try
-            {
+        if (arrayType != null) {
+            try {
                 wat = new SOAPArrayType(arrayType, new NamespaceContext(xsdAttr));
-            }
-            catch (XmlValueOutOfRangeException e)
-            {
-                state.error(XmlErrorCodes.SOAPARRAY, new Object[] {arrayType}, xsdAttr);
+            } catch (XmlValueOutOfRangeException e) {
+                state.error(XmlErrorCodes.SOAPARRAY, new Object[]{arrayType}, xsdAttr);
             }
         }
 
@@ -1681,40 +1483,39 @@
         return sAttr;
     }
 
-    static int translateUseCode(Attribute.Use attruse)
-    {
-        if (attruse == null)
+    static int translateUseCode(Attribute.Use attruse) {
+        if (attruse == null) {
             return SchemaLocalAttribute.OPTIONAL;
+        }
 
         String val = attruse.getStringValue();
-        if (val.equals("optional"))
+        if (val.equals("optional")) {
             return SchemaLocalAttribute.OPTIONAL;
-        if (val.equals("required"))
+        }
+        if (val.equals("required")) {
             return SchemaLocalAttribute.REQUIRED;
-        if (val.equals("prohibited"))
+        }
+        if (val.equals("prohibited")) {
             return SchemaLocalAttribute.PROHIBITED;
+        }
         return SchemaLocalAttribute.OPTIONAL;
     }
 
-    static BigInteger buildBigInt(XmlAnySimpleType value)
-    {
-        if (value == null)
+    static BigInteger buildBigInt(XmlAnySimpleType value) {
+        if (value == null) {
             return null;
+        }
         String text = value.getStringValue();
         BigInteger bigInt;
-        try
-        {
+        try {
             bigInt = new BigInteger(text);
-        }
-        catch (NumberFormatException e)
-        {
-            StscState.get().error(XmlErrorCodes.INVALID_VALUE_DETAIL, new Object[] { text, "nonNegativeInteger", e.getMessage() }, value);
+        } catch (NumberFormatException e) {
+            StscState.get().error(XmlErrorCodes.INVALID_VALUE_DETAIL, new Object[]{text, "nonNegativeInteger", e.getMessage()}, value);
             return null;
         }
 
-        if (bigInt.signum() < 0)
-        {
-            StscState.get().error(XmlErrorCodes.INVALID_VALUE, new Object[] { text, "nonNegativeInteger" }, value);
+        if (bigInt.signum() < 0) {
+            StscState.get().error(XmlErrorCodes.INVALID_VALUE, new Object[]{text, "nonNegativeInteger"}, value);
             return null;
         }
 
@@ -1722,60 +1523,50 @@
     }
 
 
-    static XmlNonNegativeInteger buildNnInteger(XmlAnySimpleType value)
-    {
+    static XmlNonNegativeInteger buildNnInteger(XmlAnySimpleType value) {
         BigInteger bigInt = buildBigInt(value);
-        try
-        {
+        try {
             XmlNonNegativeIntegerImpl i = new XmlNonNegativeIntegerImpl();
-            i.set(bigInt);
+            i.setBigIntegerValue(bigInt);
             i.setImmutable();
             return i;
-        }
-        catch (XmlValueOutOfRangeException e)
-        {
+        } catch (XmlValueOutOfRangeException e) {
             StscState.get().error("Internal error processing number", XmlErrorCodes.MALFORMED_NUMBER, value);
             return null;
         }
     }
 
-    static XmlPositiveInteger buildPosInteger(XmlAnySimpleType value)
-    {
+    static XmlPositiveInteger buildPosInteger(XmlAnySimpleType value) {
         BigInteger bigInt = buildBigInt(value);
-        try
-        {
+        try {
             XmlPositiveIntegerImpl i = new XmlPositiveIntegerImpl();
-            i.set(bigInt);
+            i.setBigIntegerValue(bigInt);
             i.setImmutable();
             return i;
-        }
-        catch (XmlValueOutOfRangeException e)
-        {
+        } catch (XmlValueOutOfRangeException e) {
             StscState.get().error("Internal error processing number", XmlErrorCodes.MALFORMED_NUMBER, value);
             return null;
         }
     }
 
 
-    private static Object getUserData(XmlObject pos)
-    {
+    private static Object getUserData(XmlObject pos) {
         XmlCursor.XmlBookmark b = pos.newCursor().getBookmark(SchemaBookmark.class);
-        if (b != null && b instanceof SchemaBookmark)
+        if (b instanceof SchemaBookmark) {
             return ((SchemaBookmark) b).getValue();
-        else
+        } else {
             return null;
+        }
     }
 
-    private static boolean isEmptySchema(Schema schema)
-    {
+    private static boolean isEmptySchema(Schema schema) {
         XmlCursor cursor = schema.newCursor();
         boolean result = !cursor.toFirstChild();
         cursor.dispose();
         return result;
     }
 
-    private static boolean isReservedTypeName(QName name)
-    {
+    private static boolean isReservedTypeName(QName name) {
         return (BuiltinSchemaTypeSystem.get().findType(name) != null);
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Cur.java b/src/main/java/org/apache/xmlbeans/impl/store/Cur.java
index 5721fc8..66b3665 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Cur.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Cur.java
@@ -145,8 +145,9 @@
     boolean isContainerOrFinish() {
         assert isPositioned();
 
-        if (_pos != 0 && _pos != END_POS)
+        if (_pos != 0 && _pos != END_POS) {
             return false;
+        }
 
         int kind = _xobj.kind();
         return kind == ELEM || kind == -ELEM || kind == ROOT || kind == -ROOT;
@@ -248,36 +249,60 @@
     static Xobj createDomDocumentRootXobj(Locale l, boolean fragment) {
         Xobj xo;
 
-        if (l._saaj == null)
-            if (fragment)
+        if (l._saaj == null) {
+            if (fragment) {
                 xo = new DocumentFragXobj(l);
-            else
+            } else {
                 xo = new DocumentXobj(l);
-        else
+            }
+        } else {
             xo = new SoapPartDocXobj(l);
+        }
 
-        if (l._ownerDoc == null)
+        if (l._ownerDoc == null) {
             l._ownerDoc = xo.getDom();
+        }
 
         return xo;
     }
 
     static Xobj createElementXobj(Locale l, QName name, QName parentName) {
-        if (l._saaj == null)
+        if (l._saaj == null) {
             return new ElementXobj(l, name);
+        }
 
         Class c = l._saaj.identifyElement(name, parentName);
 
-        if (c == SOAPElement.class) return new SoapElementXobj(l, name);
-        if (c == SOAPBody.class) return new SoapBodyXobj(l, name);
-        if (c == SOAPBodyElement.class) return new SoapBodyElementXobj(l, name);
-        if (c == SOAPEnvelope.class) return new SoapEnvelopeXobj(l, name);
-        if (c == SOAPHeader.class) return new SoapHeaderXobj(l, name);
-        if (c == SOAPHeaderElement.class) return new SoapHeaderElementXobj(l, name);
-        if (c == SOAPFaultElement.class) return new SoapFaultElementXobj(l, name);
-        if (c == Detail.class) return new DetailXobj(l, name);
-        if (c == DetailEntry.class) return new DetailEntryXobj(l, name);
-        if (c == SOAPFault.class) return new SoapFaultXobj(l, name);
+        if (c == SOAPElement.class) {
+            return new SoapElementXobj(l, name);
+        }
+        if (c == SOAPBody.class) {
+            return new SoapBodyXobj(l, name);
+        }
+        if (c == SOAPBodyElement.class) {
+            return new SoapBodyElementXobj(l, name);
+        }
+        if (c == SOAPEnvelope.class) {
+            return new SoapEnvelopeXobj(l, name);
+        }
+        if (c == SOAPHeader.class) {
+            return new SoapHeaderXobj(l, name);
+        }
+        if (c == SOAPHeaderElement.class) {
+            return new SoapHeaderElementXobj(l, name);
+        }
+        if (c == SOAPFaultElement.class) {
+            return new SoapFaultElementXobj(l, name);
+        }
+        if (c == Detail.class) {
+            return new DetailXobj(l, name);
+        }
+        if (c == DetailEntry.class) {
+            return new DetailEntryXobj(l, name);
+        }
+        if (c == SOAPFault.class) {
+            return new SoapFaultXobj(l, name);
+        }
 
         throw new IllegalStateException("Unknown SAAJ element class: " + c);
     }
@@ -337,8 +362,9 @@
 
         // If in differnet locales, then can't comapre
 
-        if (_locale != that._locale)
+        if (_locale != that._locale) {
             return 2;
+        }
 
         // No need to denormalize, but I want positions which I can compare (no END_POS)
 
@@ -391,12 +417,12 @@
 
         while (dThis > dThat) {
             dThis--;
-            assert(xThis != null);
+            assert (xThis != null);
             xThis = xThis._parent;
         }
         while (dThat > dThis) {
             dThat--;
-            assert(xThat != null);
+            assert (xThat != null);
             xThat = xThat._parent;
         }
 
@@ -614,8 +640,9 @@
                 next[i] = before;
                 prev[before] = i;
 
-                if (head == before)
+                if (head == before) {
                     head = i;
+                }
             } else {
                 prev[i] = prev[head];
                 assert next[i] == NULL;
@@ -864,8 +891,9 @@
     boolean hasParent() {
         assert isPositioned();
 
-        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
+        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) {
             return true;
+        }
 
         assert _pos == 0 || _xobj._parent != null;
 
@@ -875,13 +903,15 @@
     Xobj getParentNoRoot() {
         assert isPositioned();
 
-        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
+        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) {
             return _xobj;
+        }
 
         assert _pos == 0 || _xobj._parent != null;
 
-        if (_xobj._parent != null)
+        if (_xobj._parent != null) {
             return _xobj._parent;
+        }
 
         return null;
     }
@@ -889,16 +919,19 @@
     Xobj getParent(boolean raw) {
         assert isPositioned();
 
-        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter()))
+        if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) {
             return _xobj;
+        }
 
         assert _pos == 0 || _xobj._parent != null;
 
-        if (_xobj._parent != null)
+        if (_xobj._parent != null) {
             return _xobj._parent;
+        }
 
-        if (raw || _xobj.isRoot())
+        if (raw || _xobj.isRoot()) {
             return null;
+        }
 
         Cur r = _locale.tempCur();
 
@@ -916,8 +949,9 @@
     boolean toParent(boolean raw) {
         Xobj parent = getParent(raw);
 
-        if (parent == null)
+        if (parent == null) {
             return false;
+        }
 
         moveTo(parent);
 
@@ -967,8 +1001,9 @@
     boolean toFirstChild() {
         assert isNode();
 
-        if (!_xobj.hasChildren())
+        if (!_xobj.hasChildren()) {
             return false;
+        }
 
         for (Xobj x = _xobj._firstChild; ; x = x._nextSibling) {
             if (!x.isAttr()) {
@@ -981,8 +1016,9 @@
     protected boolean toLastChild() {
         assert isNode();
 
-        if (!_xobj.hasChildren())
+        if (!_xobj.hasChildren()) {
             return false;
+        }
 
         moveTo(_xobj._lastChild);
 
@@ -1015,8 +1051,9 @@
             prefixForNamespace(
                 ns, qname.getPrefix().length() > 0 ? qname.getPrefix() : null, true);
 
-        if (prefix.length() > 0)
+        if (prefix.length() > 0) {
             value = prefix + ":" + value;
+        }
 
         setValue(value);
     }
@@ -1042,10 +1079,11 @@
 
         if (toNextAttr()) {
             while (isAttr()) {
-                if (getName().equals(attrName))
+                if (getName().equals(attrName)) {
                     moveNode(null);
-                else if (!toNextAttr())
+                } else if (!toNextAttr()) {
                     break;
+                }
             }
         }
 
@@ -1103,8 +1141,9 @@
 
         Xobj a = _xobj.getAttr(name);
 
-        if (a == null)
+        if (a == null) {
             return false;
+        }
 
         moveTo(a);
 
@@ -1133,7 +1172,9 @@
         }
 
         //noinspection StatementWithEmptyBody
-        while (toNextAttr()) ;
+        while (toNextAttr()) {
+            ;
+        }
 
         return true;
     }
@@ -1198,16 +1239,19 @@
     boolean skip() {
         assert isNode();
 
-        if (_xobj.isRoot())
+        if (_xobj.isRoot()) {
             return false;
+        }
 
         if (_xobj.isAttr()) {
-            if (_xobj._nextSibling == null || !_xobj._nextSibling.isAttr())
+            if (_xobj._nextSibling == null || !_xobj._nextSibling.isAttr()) {
                 return false;
+            }
 
             moveTo(_xobj._nextSibling, 0);
-        } else
+        } else {
             moveTo(getNormal(_xobj, _xobj.posAfter()), _posTemp);
+        }
 
         return true;
     }
@@ -1408,13 +1452,15 @@
 
         int cchLeft = cchLeft();
 
-        if (cch < 0 || cch > cchLeft)
+        if (cch < 0 || cch > cchLeft) {
             cch = cchLeft;
+        }
 
         // Dang, I love this stmt :-)
 
-        if (cch != 0)
+        if (cch != 0) {
             moveTo(getNormal(getDenormal(), _posTemp - cch), _posTemp);
+        }
 
         return cch;
     }
@@ -1424,8 +1470,9 @@
 
         int cchRight = cchRight();
 
-        if (cchRight == 0)
+        if (cchRight == 0) {
             return 0;
+        }
 
         if (cch < 0 || cch >= cchRight) {
             // Use next to not skip over children
@@ -1447,13 +1494,15 @@
 
         assert !x.isRoot() || (p > 0 && p < x.posAfter());
 
-        if (p >= x.posAfter())
+        if (p >= x.posAfter()) {
             x._charNodesAfter = nodes;
-        else
+        } else {
             x._charNodesValue = nodes;
+        }
 
-        for (; nodes != null; nodes = nodes._next)
+        for (; nodes != null; nodes = nodes._next) {
             nodes.setDom((Dom) x);
+        }
 
         // No Need to notify text change or alter version, text nodes are
         // not part of the infoset
@@ -1554,8 +1603,9 @@
     }
 
     void insertString(String s) {
-        if (s != null)
+        if (s != null) {
             insertChars(s, 0, s.length());
+        }
     }
 
     void insertChars(Object src, int off, int cch) {
@@ -1564,8 +1614,9 @@
 
         // Check for nothing to insert
 
-        if (cch <= 0)
+        if (cch <= 0) {
             return;
+        }
 
         _locale.notifyChange();
 
@@ -1575,8 +1626,9 @@
         // insert in the value of the parent.  In the latter case, because the parent has a child,
         // it cannot be vacant.
 
-        if (_pos == END_POS)
+        if (_pos == END_POS) {
             _xobj.ensureOccupancy();
+        }
 
         // Get the denormailized Xobj and pos.  This is the Xobj which will actually receive
         // the new chars.  Note that a denormalized position can never be <= 0.
@@ -1609,8 +1661,9 @@
         assert cchMove <= 0 || cchMove <= cchRight();
         assert to == null || (to.isPositioned() && !to.isRoot());
 
-        if (cchMove < 0)
+        if (cchMove < 0) {
             cchMove = cchRight();
+        }
 
         // If we're instructed to move 0 characters, then return the null triple.
 
@@ -1689,10 +1742,11 @@
         //
         //if ( _xobj != null )
         {
-            if (to == null)
+            if (to == null) {
                 _xobj.removeCharsHelper(_pos, cchMove, null, NO_POS, false, true);
-            else
+            } else {
                 _xobj.removeCharsHelper(_pos, cchMove, to._xobj, to._pos, false, true);
+            }
         }
 
         // Need to update the position of this cursor even though it did not move anywhere.  This
@@ -1771,8 +1825,9 @@
             // a vacant node, I get it occupied.  I do not need to worry about the source being
             // vacant.
 
-            if (to._pos == END_POS)
+            if (to._pos == END_POS) {
                 to._xobj.ensureOccupancy();
+            }
 
             // See if the destination is on the edge of the node to be moved (a no-op).  It is
             // illegal to call this fcn when to is contained within the node to be moved.  Note
@@ -1804,14 +1859,16 @@
         // Node is going away.  Invalidate the parent (the text around the node is merging).
         // Also, this node may be an attribute -- invalidate special attrs ...
 
-        if (x.isAttr())
+        if (x.isAttr()) {
             x.invalidateSpecialAttr(to == null ? null : to.getParentRaw());
-        else {
-            if (x._parent != null)
+        } else {
+            if (x._parent != null) {
                 x._parent.invalidateUser();
+            }
 
-            if (to != null && to.hasParent())
+            if (to != null && to.hasParent()) {
                 to.getParent().invalidateUser();
+            }
         }
 
         // If there is any text after x, I move it to be before x.  This frees me to extract x
@@ -1870,16 +1927,18 @@
                 to.pop();
             }
 
-            if (append)
+            if (append) {
                 here.appendXobj(x);
-            else
+            } else {
                 here.insertXobj(x);
+            }
 
             // The only text I need to move is that to the right of "to".  Even considering all
             // the cases where an attribute is involed!
 
-            if (cchRight > 0)
+            if (cchRight > 0) {
                 transferChars(to._xobj, to._pos, x, x.posAfter(), cchRight);
+            }
 
             to.moveTo(x);
         }
@@ -1962,8 +2021,9 @@
 
             // TODO - shuffle interior curs?
 
-            if (isAtLeftEdge)
+            if (isAtLeftEdge) {
                 return;
+            }
 
             // Now, after dealing with the edge condition, I can assert that to is not inside x
 
@@ -1990,8 +2050,9 @@
             c.moveChars(to, -1);
             c.release();
 
-            if (to != null)
+            if (to != null) {
                 to.nextChars(valueMovedCch = c._cchSrc);
+            }
         }
 
         // Now, walk all the contents, invalidating special attrs, reportioning cursors,
@@ -2015,13 +2076,15 @@
                 y.invalidateSpecialAttr(to == null ? null : to.getParent());
             }
 
-            for (Cur c; (c = y._embedded) != null; )
+            for (Cur c; (c = y._embedded) != null; ) {
                 c.moveTo(x, END_POS);
+            }
 
             y.disconnectUser();
 
-            if (to != null)
+            if (to != null) {
                 y._locale = to._locale;
+            }
 
             sawBookmark = sawBookmark || y._bookmarks != null;
         }
@@ -2046,8 +2109,9 @@
         // invalidation needed.  If I've move text to "to" already, no need to invalidate
         // again.
 
-        if (!lastToMove.isAttr())
+        if (!lastToMove.isAttr()) {
             x.invalidateUser();
+        }
 
         x._locale._versionAll++;
         x._locale._versionSansText++;
@@ -2093,8 +2157,9 @@
             if (firstToMove.isAttr()) {
                 Xobj lastNewAttr = firstToMove;
 
-                while (lastNewAttr._nextSibling != null && lastNewAttr._nextSibling.isAttr())
+                while (lastNewAttr._nextSibling != null && lastNewAttr._nextSibling.isAttr()) {
                     lastNewAttr = lastNewAttr._nextSibling;
+                }
 
                 // Get to's parnet now before I potentially move him with the next transfer
 
@@ -2112,7 +2177,7 @@
                         cch = y._cchValue;
                     } else {
                         y = y.lastAttr();
-                        assert(y != null);
+                        assert (y != null);
                         p = y.posAfter();
                         cch = y._cchAfter;
                     }
@@ -2139,8 +2204,9 @@
 
         // If I consed up a to, release it here
 
-        if (surragateTo != null)
+        if (surragateTo != null) {
             surragateTo.release();
+        }
     }
 
     protected final Bookmark setBookmark(Object key, Object value) {
@@ -2154,9 +2220,11 @@
         assert isNormal();
         assert key != null;
 
-        for (Bookmark b = _xobj._bookmarks; b != null; b = b._next)
-            if (b._pos == _pos && b._key == key)
+        for (Bookmark b = _xobj._bookmarks; b != null; b = b._next) {
+            if (b._pos == _pos && b._key == key) {
                 return b._value;
+            }
+        }
 
         return null;
     }
@@ -2170,9 +2238,11 @@
         int d = -1;
 
         if (isText()) {
-            for (Bookmark b = _xobj._bookmarks; b != null; b = b._next)
-                if (b._key == key && inChars(b, cch, false))
+            for (Bookmark b = _xobj._bookmarks; b != null; b = b._next) {
+                if (b._key == key && inChars(b, cch, false)) {
                     d = (d == -1 || b._pos - _pos < d) ? b._pos - _pos : d;
+                }
+            }
         }
 
         return d;
@@ -2644,17 +2714,15 @@
             _lastXobj = _frontier;
             _lastPos = 0;
 
-            if (options.hasOption(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT)) {
-                _replaceDocElem = (QName) options.get(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT);
-                _discardDocElem = true;
-            }
+            _replaceDocElem = options.getLoadReplaceDocumentElement();
+            _discardDocElem = options.hasOption(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT);
 
-            _stripWhitespace = options.hasOption(XmlOptions.LOAD_STRIP_WHITESPACE);
-            _stripComments = options.hasOption(XmlOptions.LOAD_STRIP_COMMENTS);
-            _stripProcinsts = options.hasOption(XmlOptions.LOAD_STRIP_PROCINSTS);
+            _stripWhitespace = options.isSetLoadStripWhitespace();
+            _stripComments = options.isLoadStripComments();
+            _stripProcinsts = options.isLoadStripProcinsts();
 
-            _substituteNamespaces = (Map) options.get(XmlOptions.LOAD_SUBSTITUTE_NAMESPACES);
-            _additionalNamespaces = (Map) options.get(XmlOptions.LOAD_ADDITIONAL_NAMESPACES);
+            _substituteNamespaces = options.getLoadSubstituteNamespaces();
+            _additionalNamespaces = options.getLoadAdditionalNamespaces();
 
             _locale._versionAll++;
             _locale._versionSansText++;
@@ -2857,8 +2925,9 @@
         }
 
         protected void comment(String comment) {
-            if (!_stripComments)
+            if (!_stripComments) {
                 comment(comment, 0, comment.length());
+            }
             _stripLeft = true;
         }
 
@@ -2915,9 +2984,9 @@
         }
 
         protected void bookmarkLastNonAttr(XmlBookmark bm) {
-            if (_lastPos > 0 || !_lastXobj.isAttr())
+            if (_lastPos > 0 || !_lastXobj.isAttr()) {
                 _lastXobj.setBookmark(_lastPos, bm.getKey(), bm);
-            else {
+            } else {
                 assert _lastXobj._parent != null;
 
                 _lastXobj._parent.setBookmark(0, bm.getKey(), bm);
@@ -2955,8 +3024,9 @@
         protected Cur finish() {
             flushText();
 
-            if (_after)
+            if (_after) {
                 _frontier = _frontier._parent;
+            }
 
             assert _frontier != null && _frontier._parent == null && _frontier.isRoot();
 
@@ -2978,7 +3048,9 @@
                     // does not appear to have been the contents of the removed element.
 
                     //noinspection StatementWithEmptyBody
-                    while (c.toParent()) ;
+                    while (c.toParent()) {
+                        ;
+                    }
 
                     c.next();
 
@@ -3237,29 +3309,34 @@
     }
 
     private static void dumpXobj(PrintStream o, Xobj xo, int level, Object ref) {
-        if (xo == null)
+        if (xo == null) {
             return;
+        }
 
-        if (xo == ref)
+        if (xo == ref) {
             o.print("* ");
-        else
+        } else {
             o.print("  ");
+        }
 
-        for (int i = 0; i < level; i++)
+        for (int i = 0; i < level; i++) {
             o.print("  ");
+        }
 
         o.print(kindName(xo.kind()));
 
         if (xo._name != null) {
             o.print(" ");
 
-            if (xo._name.getPrefix().length() > 0)
+            if (xo._name.getPrefix().length() > 0) {
                 o.print(xo._name.getPrefix() + ":");
+            }
 
             o.print(xo._name.getLocalPart());
 
-            if (xo._name.getNamespaceURI().length() > 0)
+            if (xo._name.getNamespaceURI().length() > 0) {
                 o.print("@" + xo._name.getNamespaceURI());
+            }
         }
 
         if (xo._srcValue != null || xo._charNodesValue != null) {
@@ -3269,11 +3346,13 @@
             o.print(" )");
         }
 
-        if (xo._user != null)
+        if (xo._user != null) {
             o.print(" (USER)");
+        }
 
-        if (xo.isVacant())
+        if (xo.isVacant()) {
             o.print(" (VACANT)");
+        }
 
         if (xo._srcAfter != null || xo._charNodesAfter != null) {
             o.print(" After( ");
@@ -3294,8 +3373,9 @@
 
             i = className.lastIndexOf('$');
 
-            if (i > 0)
+            if (i > 0) {
                 className = className.substring(i + 1);
+            }
         }
 
         o.print(" (");
@@ -3304,8 +3384,9 @@
 
         o.println();
 
-        for (xo = xo._firstChild; xo != null; xo = xo._nextSibling)
+        for (xo = xo._firstChild; xo != null; xo = xo._nextSibling) {
             dumpXobj(o, xo, level + 1, ref);
+        }
     }
 
     void setId(String id) {
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 decbe7c..acdd4bb 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Cursor.java
@@ -68,8 +68,9 @@
             if (c.toParentRaw()) {
                 int pk = c.kind();
 
-                if (pk == COMMENT || pk == PROCINST || pk == ATTR)
+                if (pk == COMMENT || pk == PROCINST || pk == ATTR) {
                     return false;
+                }
             }
 
             c.pop();
@@ -95,35 +96,43 @@
     }
 
     static void validateLocalName(QName name) {
-        if (name == null)
+        if (name == null) {
             throw new IllegalArgumentException("QName is null");
+        }
 
         validateLocalName(name.getLocalPart());
     }
 
     static void validateLocalName(String name) {
-        if (name == null)
+        if (name == null) {
             throw new IllegalArgumentException("Name is null");
+        }
 
-        if (name.length() == 0)
+        if (name.length() == 0) {
             throw new IllegalArgumentException("Name is empty");
+        }
 
-        if (!XMLChar.isValidNCName(name))
+        if (!XMLChar.isValidNCName(name)) {
             throw new IllegalArgumentException("Name is not valid");
+        }
     }
 
     static void validatePrefix(String name) {
-        if (name == null)
+        if (name == null) {
             throw new IllegalArgumentException("Prefix is null");
+        }
 
-        if (name.length() == 0)
+        if (name.length() == 0) {
             throw new IllegalArgumentException("Prefix is empty");
+        }
 
-        if (Locale.beginsWithXml(name))
+        if (Locale.beginsWithXml(name)) {
             throw new IllegalArgumentException("Prefix begins with 'xml'");
+        }
 
-        if (!XMLChar.isValidNCName(name))
+        if (!XMLChar.isValidNCName(name)) {
             throw new IllegalArgumentException("Prefix is not valid");
+        }
     }
 
     private static void complain(String msg) {
@@ -133,16 +142,19 @@
     private void checkInsertionValidity(Cur that) {
         int thatKind = that.kind();
 
-        if (thatKind < 0)
+        if (thatKind < 0) {
             complain("Can't move/copy/insert an end token.");
+        }
 
-        if (thatKind == ROOT)
+        if (thatKind == ROOT) {
             complain("Can't move/copy/insert a whole document.");
+        }
 
         int thisKind = _cur.kind();
 
-        if (thisKind == ROOT)
+        if (thisKind == ROOT) {
             complain("Can't insert before the start of the document.");
+        }
 
         if (thatKind == ATTR) {
             _cur.push();
@@ -155,8 +167,9 @@
             }
         }
 
-        if (thisKind == ATTR && thatKind != ATTR)
+        if (thisKind == ATTR && thatKind != ATTR) {
             complain("Can only insert attributes before other attributes or after containers.");
+        }
     }
 
     private void insertNode(Cur that, String text) {
@@ -205,7 +218,7 @@
 
                 if (_cur.isXmlns()) {
                     return
-                            _cur._locale.makeQNameNoCheck(_cur.getXmlnsUri(), _cur.getXmlnsPrefix());
+                        _cur._locale.makeQNameNoCheck(_cur.getXmlnsUri(), _cur.getXmlnsPrefix());
                 }
 
                 // Fall thru
@@ -219,33 +232,34 @@
     }
 
     public void _setName(QName name) {
-        if (name == null)
+        if (name == null) {
             throw new IllegalArgumentException("Name is null");
+        }
 
         switch (_cur.kind()) {
             case ELEM:
-            case ATTR:
-                {
-                    validateLocalName(name.getLocalPart());
-                    break;
+            case ATTR: {
+                validateLocalName(name.getLocalPart());
+                break;
+            }
+
+            case PROCINST: {
+                validatePrefix(name.getLocalPart());
+
+                if (name.getNamespaceURI().length() > 0) {
+                    throw new IllegalArgumentException("Procinst name must have no URI");
                 }
 
-            case PROCINST:
-                {
-                    validatePrefix(name.getLocalPart());
-
-                    if (name.getNamespaceURI().length() > 0)
-                        throw new IllegalArgumentException("Procinst name must have no URI");
-
-                    if (name.getPrefix().length() > 0)
-                        throw new IllegalArgumentException("Procinst name must have no prefix");
-
-                    break;
+                if (name.getPrefix().length() > 0) {
+                    throw new IllegalArgumentException("Procinst name must have no prefix");
                 }
 
-            default :
+                break;
+            }
+
+            default:
                 throw
-                        new IllegalStateException("Can set name on element, atrtribute and procinst only");
+                    new IllegalStateException("Can set name on element, atrtribute and procinst only");
         }
 
         _cur.setName(name);
@@ -272,7 +286,7 @@
             case PROCINST:
                 return TokenType.PROCINST;
 
-            default :
+            default:
                 throw new IllegalStateException();
         }
     }
@@ -354,38 +368,36 @@
 
         switch (_cur.kind()) {
             case ROOT:
-            case ELEM:
-                {
-                    if (!_cur.toFirstAttr())
-                        _cur.next();
-
-                    break;
+            case ELEM: {
+                if (!_cur.toFirstAttr()) {
+                    _cur.next();
                 }
 
-            case ATTR:
-                {
-                    if (!_cur.toNextSibling()) {
-                        _cur.toParent();
-                        _cur.next();
-                    }
+                break;
+            }
 
-                    break;
+            case ATTR: {
+                if (!_cur.toNextSibling()) {
+                    _cur.toParent();
+                    _cur.next();
                 }
 
+                break;
+            }
+
             case COMMENT:
-            case PROCINST:
-                {
-                    _cur.skip();
-                    break;
+            case PROCINST: {
+                _cur.skip();
+                break;
+            }
+
+            default: {
+                if (!_cur.next()) {
+                    return TokenType.NONE;
                 }
 
-            default :
-                {
-                    if (!_cur.next())
-                        return TokenType.NONE;
-
-                    break;
-                }
+                break;
+            }
         }
 
         return _currentTokenType();
@@ -545,13 +557,14 @@
     }
 
     public void _save(ContentHandler ch, LexicalHandler lh, XmlOptions options)
-            throws SAXException {
+        throws SAXException {
         new Saver.SaxSaver(_cur, options, ch, lh);
     }
 
     public void _save(File file, XmlOptions options) throws IOException {
-        if (file == null)
+        if (file == null) {
             throw new IllegalArgumentException("Null file specified");
+        }
 
         try (OutputStream os = new FileOutputStream(file)) {
             _save(os, options);
@@ -559,33 +572,31 @@
     }
 
     public void _save(OutputStream os, XmlOptions options) throws IOException {
-        if (os == null)
+        if (os == null) {
             throw new IllegalArgumentException("Null OutputStream specified");
+        }
 
-        InputStream is = _newInputStream(options);
-
-        try {
+        try (InputStream is = _newInputStream(options)) {
             byte[] bytes = new byte[8192];
 
-            for (; ;) {
+            for (; ; ) {
                 int n = is.read(bytes);
 
-                if (n < 0)
+                if (n < 0) {
                     break;
+                }
 
                 os.write(bytes, 0, n);
             }
-        } finally {
-            is.close();
         }
     }
 
     public void _save(Writer w, XmlOptions options) throws IOException {
-        if (w == null)
+        if (w == null) {
             throw new IllegalArgumentException("Null Writer specified");
+        }
 
-        if (options != null && options.hasOption( XmlOptions.SAVE_OPTIMIZE_FOR_SPEED ))
-        {
+        if (options != null && options.isSaveOptimizeForSpeed()) {
             Saver.OptimizedForSpeedSaver.save(_cur, w); //ignore all other options
             return;
         }
@@ -593,7 +604,7 @@
         try (Reader r = _newReader(options)) {
             char[] chars = new char[8192];
 
-            for (;;) {
+            for (; ; ) {
                 int n = r.read(chars);
 
                 if (n < 0) {
@@ -610,8 +621,9 @@
     }
 
     private boolean isDomFragment() {
-        if (!isStartdoc())
+        if (!isStartdoc()) {
             return true;
+        }
 
         boolean seenElement = false;
 
@@ -619,18 +631,21 @@
         int token = c.toNextToken().intValue();
 
         try {
-            LOOP: for (; ;) {
+            LOOP:
+            for (; ; ) {
                 switch (token) {
                     case TokenType.INT_START:
-                        if (seenElement)
+                        if (seenElement) {
                             return true;
+                        }
                         seenElement = true;
                         token = c.toEndToken().intValue();
                         break;
 
                     case TokenType.INT_TEXT:
-                        if (!Locale.isWhiteSpace(c.getChars()))
+                        if (!Locale.isWhiteSpace(c.getChars())) {
                             return true;
+                        }
                         token = c.toNextToken().intValue();
                         break;
 
@@ -663,9 +678,9 @@
     public Node _newDomNode(XmlOptions options) {
         // Must ignore inner options for compat with v1.
 
-        if (XmlOptions.hasOption(options, XmlOptions.SAVE_INNER)) {
+        if (options != null && options.isSaveInner()) {
             options = new XmlOptions(options);
-            options.remove(XmlOptions.SAVE_INNER);
+            options.setSaveInner(false);
         }
 
         return new DomSaver(_cur, isDomFragment(), options).saveDom();
@@ -691,8 +706,9 @@
         // Force any path to get exausted, cursor may be disposed, but still be on the notification
         // list.
 
-        if (_cur != null)
+        if (_cur != null) {
             _getSelectionCount();
+        }
     }
 
     public void setNextChangeListener(ChangeListener listener) {
@@ -734,12 +750,14 @@
     }
 
     public boolean _toSelection(int i) {
-        if (i < 0)
+        if (i < 0) {
             return false;
+        }
 
         while (i >= _cur.selectionCount()) {
-            if (_pathEngine == null)
+            if (_pathEngine == null) {
                 return false;
+            }
 
             if (!_pathEngine.next(_cur)) {
                 _pathEngine.release();
@@ -779,15 +797,17 @@
     }
 
     public String _namespaceForPrefix(String prefix) {
-        if (!_cur.isContainer())
+        if (!_cur.isContainer()) {
             throw new IllegalStateException("Not on a container");
+        }
 
         return _cur.namespaceForPrefix(prefix, true);
     }
 
     public String _prefixForNamespace(String ns) {
-        if (ns == null || ns.length() == 0)
+        if (ns == null || ns.length() == 0) {
             throw new IllegalArgumentException("Must specify a namespace");
+        }
 
 // Note: I loosen this requirement in v2, can call this from anywhere
 //        if (!_cur.isContainer())
@@ -796,12 +816,14 @@
         return _cur.prefixForNamespace(ns, null, true);
     }
 
-    public void _getAllNamespaces(Map addToThis) {
-        if (!_cur.isContainer())
+    public void _getAllNamespaces(Map<String,String> addToThis) {
+        if (!_cur.isContainer()) {
             throw new IllegalStateException("Not on a container");
+        }
 
-        if (addToThis != null)
+        if (addToThis != null) {
             Locale.getAllNamespaces(_cur, addToThis);
+        }
     }
 
     public XmlObject _getObject() {
@@ -820,7 +842,7 @@
 
     public boolean _hasNextToken() {
         //return _cur.kind() != -ROOT;
-        return _cur._pos!=Cur.END_POS || _cur._xobj.kind()!=ROOT;
+        return _cur._pos != Cur.END_POS || _cur._xobj.kind() != ROOT;
     }
 
     public boolean _hasPrevToken() {
@@ -828,8 +850,9 @@
     }
 
     public TokenType _toFirstContentToken() {
-        if (!_cur.isContainer())
+        if (!_cur.isContainer()) {
             return TokenType.NONE;
+        }
 
         _cur.next();
 
@@ -837,8 +860,9 @@
     }
 
     public TokenType _toEndToken() {
-        if (!_cur.isContainer())
+        if (!_cur.isContainer()) {
             return TokenType.NONE;
+        }
 
         _cur.toEnd();
 
@@ -953,8 +977,9 @@
     }
 
     public String _getAttributeText(QName attrName) {
-        if (attrName == null)
+        if (attrName == null) {
             throw new IllegalArgumentException("Attr name is null");
+        }
 
         if (!_cur.isContainer()) {
             return null;
@@ -1167,7 +1192,7 @@
 
     public XmlCursor _execQuery(String query, XmlOptions options) {
         checkThisCursor();
-        return Query.cursorExecQuery(_cur,query,options);
+        return Query.cursorExecQuery(_cur, query, options);
     }
 
 
@@ -1196,7 +1221,7 @@
 
         _cur.push();
 
-        for (; ;) {
+        for (; ; ) {
             // Move a minimal amount.  If at text, move to a potential bookmark in the text.
 
             if ((cch = _cur.cchRight()) > 1) {
@@ -1222,14 +1247,15 @@
     }
 
     public XmlBookmark _toPrevBookmark(Object key) {
-        if (key == null)
+        if (key == null) {
             return null;
+        }
 
         int cch;
 
         _cur.push();
 
-        for (; ;) {
+        for (; ; ) {
             // Move a minimal amount.  If at text, move to a potential bookmark in the text.
 
             if ((cch = _cur.cchLeft()) > 1) {
@@ -1316,10 +1342,11 @@
 
         assert _cur.isText() || _cur.isNode();
 
-        if (_cur.isText())
+        if (_cur.isText()) {
             _cur.moveChars(null, -1);
-        else
+        } else {
             _cur.moveNode(null);
+        }
 
         return true;
     }
@@ -1482,11 +1509,13 @@
     public int _moveChars(int cch, Cursor to) {
         int cchRight = _cur.cchRight();
 
-        if (cchRight <= 0 || cch == 0)
+        if (cchRight <= 0 || cch == 0) {
             return 0;
+        }
 
-        if (cch < 0 || cch > cchRight)
+        if (cch < 0 || cch > cchRight) {
             cch = cchRight;
+        }
 
         to.checkInsertionValidity(_cur);
 
@@ -1500,11 +1529,13 @@
     public int _copyChars(int cch, Cursor to) {
         int cchRight = _cur.cchRight();
 
-        if (cchRight <= 0 || cch == 0)
+        if (cchRight <= 0 || cch == 0) {
             return 0;
+        }
 
-        if (cch < 0 || cch > cchRight)
+        if (cch < 0 || cch > cchRight) {
             cch = cchRight;
+        }
 
         to.checkInsertionValidity(_cur);
 
@@ -1521,7 +1552,7 @@
         if (l > 0) {
             if (_cur.isRoot() || _cur.isAttr()) {
                 throw
-                        new IllegalStateException("Can't insert before the document or an attribute.");
+                    new IllegalStateException("Can't insert before the document or an attribute.");
             }
 
             _cur.insertChars(text, 0, l);
@@ -1641,8 +1672,9 @@
     public void _insertProcInst(String target, String text) {
         validateLocalName(target);
 
-        if (Locale.beginsWithXml(target) && target.length() == 3)
+        if (Locale.beginsWithXml(target) && target.length() == 3) {
             throw new IllegalArgumentException("Target is 'xml'");
+        }
 
         Cur c = _cur._locale.tempCur();
 
@@ -1666,23 +1698,27 @@
     //
 
     private void checkThisCursor() {
-        if (_cur == null)
+        if (_cur == null) {
             throw new IllegalStateException("This cursor has been disposed");
+        }
     }
 
     private Cursor checkCursors(XmlCursor xOther) {
         checkThisCursor();
 
-        if (xOther == null)
+        if (xOther == null) {
             throw new IllegalArgumentException("Other cursor is <null>");
+        }
 
-        if (!(xOther instanceof Cursor))
+        if (!(xOther instanceof Cursor)) {
             throw new IllegalArgumentException("Incompatible cursors: " + xOther);
+        }
 
         Cursor other = (Cursor) xOther;
 
-        if (other._cur == null)
+        if (other._cur == null) {
             throw new IllegalStateException("Other cursor has been disposed");
+        }
 
         return other;
     }
@@ -1709,9 +1745,9 @@
         }
 
         if (locale.noSync()) {
-            if (otherLocale.noSync())
+            if (otherLocale.noSync()) {
                 return twoLocaleOp(other, op, arg);
-            else {
+            } else {
                 synchronized (otherLocale) {
                     return twoLocaleOp(other, op, arg);
                 }
@@ -1739,8 +1775,9 @@
         } catch (InterruptedException e) {
             throw new RuntimeException(e.getMessage(), e);
         } finally {
-            if (acquired)
+            if (acquired) {
                 GlobalLock.release();
+            }
         }
     }
 
@@ -1765,7 +1802,7 @@
                 case COPY_CHARS:
                     return _copyChars(arg, other);
 
-                default :
+                default:
                     throw new RuntimeException("Unknown operation: " + op);
             }
         } finally {
@@ -1863,12 +1900,14 @@
             } finally {
                 l.exit();
             }
-        } else synchronized (l) {
-            l.enter();
-            try {
-                return new Cursor(x, p);
-            } finally {
-                l.exit();
+        } else {
+            synchronized (l) {
+                l.enter();
+                try {
+                    return new Cursor(x, p);
+                } finally {
+                    l.exit();
+                }
             }
         }
     }
@@ -1901,7 +1940,7 @@
     }
 
     public XMLStreamReader newXMLStreamReader() {
-        return syncWrap((Supplier<XMLStreamReader>)this::_newXMLStreamReader);
+        return syncWrap((Supplier<XMLStreamReader>) this::_newXMLStreamReader);
     }
 
     public XMLStreamReader newXMLStreamReader(XmlOptions options) {
@@ -1912,23 +1951,23 @@
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     public XMLInputStream newXMLInputStream() {
-        return syncWrap((Supplier<XMLInputStream>)this::_newXMLInputStream);
+        return syncWrap((Supplier<XMLInputStream>) this::_newXMLInputStream);
     }
 
     public String xmlText() {
-        return syncWrap((Supplier<String>)this::_xmlText);
+        return syncWrap((Supplier<String>) this::_xmlText);
     }
 
     public InputStream newInputStream() {
-        return syncWrap((Supplier<InputStream>)this::_newInputStream);
+        return syncWrap((Supplier<InputStream>) this::_newInputStream);
     }
 
     public Reader newReader() {
-        return syncWrap((Supplier<Reader>)this::_newReader);
+        return syncWrap((Supplier<Reader>) this::_newReader);
     }
 
     public Node newDomNode() {
-        return syncWrap((Supplier<Node>)this::_newDomNode);
+        return syncWrap((Supplier<Node>) this::_newDomNode);
     }
 
     public Node getDomNode() {
@@ -2058,7 +2097,7 @@
         return syncWrap(() -> _prefixForNamespace(namespaceURI));
     }
 
-    public void getAllNamespaces(Map addToThis) {
+    public void getAllNamespaces(Map<String,String> addToThis) {
         syncWrap(() -> _getAllNamespaces(addToThis));
     }
 
@@ -2166,7 +2205,7 @@
 
         Xobj parent = _cur.getParentNoRoot();
 
-        if (parent==null) {
+        if (parent == null) {
             _cur._locale.enter();
             try {
                 parent = _cur.getParent();
@@ -2259,7 +2298,7 @@
     }
 
     public String getTextValue() {
-        return syncWrap((Supplier<String>)this::_getTextValue);
+        return syncWrap((Supplier<String>) this::_getTextValue);
     }
 
     public int getTextValue(char[] chars, int offset, int cch) {
@@ -2275,7 +2314,7 @@
     }
 
     public String getChars() {
-        return syncWrap((Supplier<String>)this::_getChars);
+        return syncWrap((Supplier<String>) this::_getChars);
     }
 
     public int getChars(char[] chars, int offset, int cch) {
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/DomSaver.java b/src/main/java/org/apache/xmlbeans/impl/store/DomSaver.java
index b3fd666..dcc2f89 100644
--- a/src/main/java/org/apache/xmlbeans/impl/store/DomSaver.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/DomSaver.java
@@ -22,7 +22,7 @@
 import org.w3c.dom.Node;
 
 import javax.xml.namespace.QName;
-import java.util.ArrayList;
+import java.util.List;
 
 final class DomSaver extends Saver {
     private Cur _nodeCur;
@@ -79,7 +79,8 @@
         }
     }
 
-    protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+    @Override
+    protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
         // If there was text or comments before the frag element, I will loose them -- oh well
         // Also, I will lose any attributes and namesapces on the fragment -- DOM can
         // have attrs in fragments
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Jsr173.java b/src/main/java/org/apache/xmlbeans/impl/store/Jsr173.java
index 049b733..6fec248 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Jsr173.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Jsr173.java
@@ -15,166 +15,156 @@
 
 package org.apache.xmlbeans.impl.store;
 
-import java.io.Reader;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.ConcurrentModificationException;
+import org.apache.xmlbeans.XmlDocumentProperties;
+import org.apache.xmlbeans.XmlLineNumber;
+import org.apache.xmlbeans.XmlOptions;
+import org.w3c.dom.Node;
 
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
-
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
 
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlLineNumber;
-import org.apache.xmlbeans.XmlDocumentProperties;
-
-import org.w3c.dom.Node;
-
-public class Jsr173
-{
-    public static Node nodeFromStream ( XMLStreamReader xs )
-    {
-        if (!(xs instanceof Jsr173GateWay))
+public class Jsr173 {
+    public static Node nodeFromStream(XMLStreamReader xs) {
+        if (!(xs instanceof Jsr173GateWay)) {
             return null;
+        }
 
         Jsr173GateWay gw = (Jsr173GateWay) xs;
 
         Locale l = gw._l;
 
-        if (l.noSync())         { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } }
+        if (l.noSync()) {
+            l.enter();
+            try {
+                return nodeFromStreamImpl(gw);
+            } finally {
+                l.exit();
+            }
+        } else {
+            synchronized (l) {
+                l.enter();
+                try {
+                    return nodeFromStreamImpl(gw);
+                } finally {
+                    l.exit();
+                }
+            }
+        }
 
     }
 
-    public static Node nodeFromStreamImpl ( Jsr173GateWay gw )
-    {
+    public static Node nodeFromStreamImpl(Jsr173GateWay gw) {
         Cur c = gw._xs.getStreamCur();
 
         return c.isNode() ? (Node) c.getDom() : (Node) null;
     }
 
-    public static XMLStreamReader newXmlStreamReader ( Cur c, Object src, int off, int cch )
-    {
-        XMLStreamReaderBase xs = new XMLStreamReaderForString( c, src, off, cch );
+    public static XMLStreamReader newXmlStreamReader(Cur c, Object src, int off, int cch) {
+        XMLStreamReaderBase xs = new XMLStreamReaderForString(c, src, off, cch);
 
-        if (c._locale.noSync())
-            return new UnsyncedJsr173( c._locale, xs );
-        else
-            return new SyncedJsr173( c._locale, xs );
+        if (c._locale.noSync()) {
+            return new UnsyncedJsr173(c._locale, xs);
+        } else {
+            return new SyncedJsr173(c._locale, xs);
+        }
     }
 
-    public static XMLStreamReader newXmlStreamReader ( Cur c, XmlOptions options )
-    {
-        options = XmlOptions.maskNull( options );
+    public static XMLStreamReader newXmlStreamReader(Cur c, XmlOptions options) {
+        options = XmlOptions.maskNull(options);
 
-        boolean inner =
-            options.hasOption( XmlOptions.SAVE_INNER ) &&
-                !options.hasOption( XmlOptions.SAVE_OUTER );
+        boolean inner = options.isSaveInner() && !options.isSaveOuter();
 
         XMLStreamReaderBase xs;
 
         int k = c.kind();
 
-        if (k == Cur.TEXT || k < 0)
-        {
-            xs = new XMLStreamReaderForString( c, c.getChars( -1 ), c._offSrc, c._cchSrc );
-        }
-        else if (inner)
-        {
-            if (!c.hasAttrs() && !c.hasChildren())
-                xs = new XMLStreamReaderForString( c, c.getFirstChars(), c._offSrc, c._cchSrc );
-            else
-            {
+        if (k == Cur.TEXT || k < 0) {
+            xs = new XMLStreamReaderForString(c, c.getChars(-1), c._offSrc, c._cchSrc);
+        } else if (inner) {
+            if (!c.hasAttrs() && !c.hasChildren()) {
+                xs = new XMLStreamReaderForString(c, c.getFirstChars(), c._offSrc, c._cchSrc);
+            } else {
                 assert c.isContainer();
-                xs = new XMLStreamReaderForNode( c, true );
+                xs = new XMLStreamReaderForNode(c, true);
             }
+        } else {
+            xs = new XMLStreamReaderForNode(c, false);
         }
-        else
-            xs = new XMLStreamReaderForNode( c, false );
 
-        if (c._locale.noSync())
-            return new UnsyncedJsr173( c._locale, xs );
-        else
-            return new SyncedJsr173( c._locale, xs );
+        if (c._locale.noSync()) {
+            return new UnsyncedJsr173(c._locale, xs);
+        } else {
+            return new SyncedJsr173(c._locale, xs);
+        }
     }
 
     //
     //
     //
 
-    private static final class XMLStreamReaderForNode extends XMLStreamReaderBase
-    {
-        public XMLStreamReaderForNode ( Cur c, boolean inner )
-        {
-            super( c );
+    private static final class XMLStreamReaderForNode extends XMLStreamReaderBase {
+        public XMLStreamReaderForNode(Cur c, boolean inner) {
+            super(c);
 
             assert c.isContainer() || c.isComment() || c.isProcinst() || c.isAttr();
 
             // Iterate over everything *between* _cur and _end.  Do
             // not iterate the thing to the right of _end
 
-            if (inner)
-            {
+            if (inner) {
                 assert c.isContainer();
 
-                _cur = c.weakCur( this );
+                _cur = c.weakCur(this);
 
-                if (!_cur.toFirstAttr())
+                if (!_cur.toFirstAttr()) {
                     _cur.next();
+                }
 
-                _end = c.weakCur( this );
+                _end = c.weakCur(this);
                 _end.toEnd();
-            }
-            else
-            {
-                _cur = c.weakCur( this );
+            } else {
+                _cur = c.weakCur(this);
 
-                if (c.isRoot())
+                if (c.isRoot()) {
                     _wholeDoc = true;
-                else
-                {
-                    _end = c.weakCur( this );
+                } else {
+                    _end = c.weakCur(this);
 
-                    if (c.isAttr())
-                    {
-                        if (!_end.toNextAttr())
-                        {
+                    if (c.isAttr()) {
+                        if (!_end.toNextAttr()) {
                             _end.toParent();
                             _end.next();
                         }
-                    }
-                    else
+                    } else {
                         _end.skip();
+                    }
                 }
             }
 
-            if (!_wholeDoc)
-            {
+            if (!_wholeDoc) {
                 // Set the _done bit properly
 
                 _cur.push();
 
-                try
-                {
+                try {
                     next();
-                }
-                catch ( XMLStreamException e )
-                {
-                    throw new RuntimeException( e.getMessage(), e );
+                } catch (XMLStreamException e) {
+                    throw new RuntimeException(e.getMessage(), e);
                 }
 
                 _cur.pop();
             }
 
-            assert _wholeDoc || !_cur.isSamePos( _end );
+            assert _wholeDoc || !_cur.isSamePos(_end);
         }
 
-        protected Cur getStreamCur ( )
-        {
+        protected Cur getStreamCur() {
             return _cur;
         }
 
@@ -182,66 +172,66 @@
         //
         //
 
-        public boolean hasNext ( ) throws XMLStreamException
-        {
+        public boolean hasNext() throws XMLStreamException {
             checkChanged();
 
             return !_done;
         }
 
-        public int getEventType ( )
-        {
-            switch ( _cur.kind() )
-            {
-                case  Cur.ROOT     : return START_DOCUMENT;
-                case -Cur.ROOT     : return END_DOCUMENT;
-                case  Cur.ELEM     : return START_ELEMENT;
-                case -Cur.ELEM     : return END_ELEMENT;
-                case  Cur.ATTR     : return _cur.isXmlns() ? NAMESPACE : ATTRIBUTE;
-                case  Cur.TEXT     : return CHARACTERS;
-                case  Cur.COMMENT  : return COMMENT;
-                case  Cur.PROCINST : return PROCESSING_INSTRUCTION;
-                default            : throw new IllegalStateException();
+        public int getEventType() {
+            switch (_cur.kind()) {
+                case Cur.ROOT:
+                    return START_DOCUMENT;
+                case -Cur.ROOT:
+                    return END_DOCUMENT;
+                case Cur.ELEM:
+                    return START_ELEMENT;
+                case -Cur.ELEM:
+                    return END_ELEMENT;
+                case Cur.ATTR:
+                    return _cur.isXmlns() ? NAMESPACE : ATTRIBUTE;
+                case Cur.TEXT:
+                    return CHARACTERS;
+                case Cur.COMMENT:
+                    return COMMENT;
+                case Cur.PROCINST:
+                    return PROCESSING_INSTRUCTION;
+                default:
+                    throw new IllegalStateException();
             }
         }
 
-        public int next ( ) throws XMLStreamException
-        {
+        public int next() throws XMLStreamException {
             checkChanged();
 
-            if (!hasNext())
-                throw new IllegalStateException( "No next event in stream" );
+            if (!hasNext()) {
+                throw new IllegalStateException("No next event in stream");
+            }
 
             int kind = _cur.kind();
 
-            if (kind == -Cur.ROOT)
-            {
+            if (kind == -Cur.ROOT) {
                 assert _wholeDoc;
                 _done = true;
-            }
-            else
-            {
-                if (kind == Cur.ATTR)
-                {
-                    if (!_cur.toNextAttr())
-                    {
+            } else {
+                if (kind == Cur.ATTR) {
+                    if (!_cur.toNextAttr()) {
                         _cur.toParent();
                         _cur.next();
                     }
-                }
-                else if (kind == Cur.COMMENT || kind == Cur.PROCINST)
+                } else if (kind == Cur.COMMENT || kind == Cur.PROCINST) {
                     _cur.skip();
-                else if (kind == Cur.ROOT)
-                {
-                    if (!_cur.toFirstAttr())
+                } else if (kind == Cur.ROOT) {
+                    if (!_cur.toFirstAttr()) {
                         _cur.next();
-                }
-                else
+                    }
+                } else {
                     _cur.next();
+                }
 
                 assert _wholeDoc || _end != null;
 
-                _done = _wholeDoc ? _cur.kind() == -Cur.ROOT : _cur.isSamePos( _end );
+                _done = _wholeDoc ? _cur.kind() == -Cur.ROOT : _cur.isSamePos(_end);
             }
 
             _textFetched = false;
@@ -250,123 +240,117 @@
             return getEventType();
         }
 
-        public String getText ( )
-        {
+        public String getText() {
             checkChanged();
 
             int k = _cur.kind();
 
-            if (k == Cur.COMMENT)
+            if (k == Cur.COMMENT) {
                 return _cur.getValueAsString();
+            }
 
-            if (k == Cur.TEXT)
+            if (k == Cur.TEXT) {
                 return _cur.getCharsAsString();
+            }
 
             throw new IllegalStateException();
         }
 
-        public boolean isStartElement ( )
-        {
+        public boolean isStartElement() {
             return getEventType() == START_ELEMENT;
         }
 
-        public boolean isEndElement ( )
-        {
+        public boolean isEndElement() {
             return getEventType() == END_ELEMENT;
         }
 
-        public boolean isCharacters ( )
-        {
+        public boolean isCharacters() {
             return getEventType() == CHARACTERS;
         }
 
-        public String getElementText ( ) throws XMLStreamException
-        {
+        public String getElementText() throws XMLStreamException {
             checkChanged();
 
-            if (!isStartElement())
+            if (!isStartElement()) {
                 throw new IllegalStateException();
+            }
 
             StringBuilder sb = new StringBuilder();
 
-            for ( ; ; )
-            {
-                if (!hasNext())
+            for (; ; ) {
+                if (!hasNext()) {
                     throw new XMLStreamException();
+                }
 
                 int e = next();
 
-                if (e == END_ELEMENT)
+                if (e == END_ELEMENT) {
                     break;
-                else if (e == START_ELEMENT)
+                } else if (e == START_ELEMENT) {
                     throw new XMLStreamException();
-                else if (e != COMMENT && e != PROCESSING_INSTRUCTION)
-                    sb.append( getText() );
+                } else if (e != COMMENT && e != PROCESSING_INSTRUCTION) {
+                    sb.append(getText());
+                }
             }
 
             return sb.toString();
         }
 
-        public int nextTag ( ) throws XMLStreamException
-        {
+        public int nextTag() throws XMLStreamException {
             checkChanged();
 
-            for ( ; ; )
-            {
-                if (isStartElement() || isEndElement())
+            for (; ; ) {
+                if (isStartElement() || isEndElement()) {
                     return getEventType();
+                }
 
-                if (!isWhiteSpace())
+                if (!isWhiteSpace()) {
                     throw new XMLStreamException();
+                }
 
-                if (!hasNext())
+                if (!hasNext()) {
                     throw new XMLStreamException();
+                }
 
                 next();
             }
         }
 
-        private static boolean matchAttr ( Cur c, String uri, String local )
-        {
+        private static boolean matchAttr(Cur c, String uri, String local) {
             assert c.isNormalAttr();
 
             QName name = c.getName();
 
             return
-                name.getLocalPart().equals( local ) &&
-                    (uri == null || name.getNamespaceURI().equals( uri ));
+                name.getLocalPart().equals(local) &&
+                (uri == null || name.getNamespaceURI().equals(uri));
         }
 
-        private static Cur toAttr ( Cur c, String uri, String local )
-        {
-            if (uri == null || local == null || local.length() == 0)
+        private static Cur toAttr(Cur c, String uri, String local) {
+            if (uri == null || local == null || local.length() == 0) {
                 throw new IllegalArgumentException();
+            }
 
             Cur ca = c.tempCur();
             boolean match = false;
 
-            if (c.isElem())
-            {
-                if (ca.toFirstAttr())
-                {
-                    do
-                    {
-                        if (ca.isNormalAttr() && matchAttr( ca, uri, local ))
-                        {
+            if (c.isElem()) {
+                if (ca.toFirstAttr()) {
+                    do {
+                        if (ca.isNormalAttr() && matchAttr(ca, uri, local)) {
                             match = true;
                             break;
                         }
                     }
-                    while ( ca.toNextSibling() );
+                    while (ca.toNextSibling());
                 }
-            }
-            else if (c.isNormalAttr())
-                match = matchAttr( c, uri, local );
-            else
+            } else if (c.isNormalAttr()) {
+                match = matchAttr(c, uri, local);
+            } else {
                 throw new IllegalStateException();
+            }
 
-            if (!match)
-            {
+            if (!match) {
                 ca.release();
                 ca = null;
             }
@@ -374,14 +358,12 @@
             return ca;
         }
 
-        public String getAttributeValue ( String uri, String local )
-        {
-            Cur ca = toAttr( _cur, uri, local );
+        public String getAttributeValue(String uri, String local) {
+            Cur ca = toAttr(_cur, uri, local);
 
             String value = null;
 
-            if (ca != null)
-            {
+            if (ca != null) {
                 value = ca.getValueAsString();
                 ca.release();
             }
@@ -389,108 +371,93 @@
             return value;
         }
 
-        private static Cur toAttr ( Cur c, int i )
-        {
-            if (i < 0)
-                throw new IndexOutOfBoundsException( "Attribute index is negative" );
+        private static Cur toAttr(Cur c, int i) {
+            if (i < 0) {
+                throw new IndexOutOfBoundsException("Attribute index is negative");
+            }
 
             Cur ca = c.tempCur();
             boolean match = false;
 
-            if (c.isElem())
-            {
-                if (ca.toFirstAttr())
-                {
-                    do
-                    {
-                        if (ca.isNormalAttr() && i-- == 0)
-                        {
+            if (c.isElem()) {
+                if (ca.toFirstAttr()) {
+                    do {
+                        if (ca.isNormalAttr() && i-- == 0) {
                             match = true;
                             break;
                         }
                     }
-                    while ( ca.toNextSibling() );
+                    while (ca.toNextSibling());
                 }
-            }
-            else if (c.isNormalAttr())
+            } else if (c.isNormalAttr()) {
                 match = i == 0;
-            else
+            } else {
                 throw new IllegalStateException();
+            }
 
-            if (!match)
-            {
+            if (!match) {
                 ca.release();
-                throw new IndexOutOfBoundsException( "Attribute index is too large" );
+                throw new IndexOutOfBoundsException("Attribute index is too large");
             }
 
             return ca;
         }
 
-        public int getAttributeCount ( )
-        {
+        public int getAttributeCount() {
             int n = 0;
 
-            if (_cur.isElem())
-            {
+            if (_cur.isElem()) {
                 Cur ca = _cur.tempCur();
 
-                if (ca.toFirstAttr())
-                {
-                    do
-                    {
-                        if (ca.isNormalAttr())
+                if (ca.toFirstAttr()) {
+                    do {
+                        if (ca.isNormalAttr()) {
                             n++;
+                        }
                     }
-                    while ( ca.toNextSibling() );
+                    while (ca.toNextSibling());
                 }
 
                 ca.release();
-            }
-            else if (_cur.isNormalAttr())
+            } else if (_cur.isNormalAttr()) {
                 n++;
-            else
+            } else {
                 throw new IllegalStateException();
+            }
 
             return n;
         }
 
-        public QName getAttributeName ( int index )
-        {
-            Cur ca = toAttr( _cur, index );
+        public QName getAttributeName(int index) {
+            Cur ca = toAttr(_cur, index);
             QName name = ca.getName();
             ca.release();
             return name;
         }
 
-        public String getAttributeNamespace ( int index )
-        {
-            return getAttributeName( index ).getNamespaceURI();
+        public String getAttributeNamespace(int index) {
+            return getAttributeName(index).getNamespaceURI();
         }
 
-        public String getAttributeLocalName ( int index )
-        {
-            return getAttributeName( index ).getLocalPart();
+        public String getAttributeLocalName(int index) {
+            return getAttributeName(index).getLocalPart();
         }
 
-        public String getAttributePrefix ( int index )
-        {
-            return getAttributeName( index ).getPrefix();
+        public String getAttributePrefix(int index) {
+            return getAttributeName(index).getPrefix();
         }
 
-        public String getAttributeType ( int index )
-        {
-            toAttr( _cur, index ).release();
+        public String getAttributeType(int index) {
+            toAttr(_cur, index).release();
             return "CDATA";
         }
 
-        public String getAttributeValue ( int index )
-        {
-            Cur ca = toAttr( _cur, index );
+        public String getAttributeValue(int index) {
+            Cur ca = toAttr(_cur, index);
 
             String value = null;
 
-            if (ca != null)
-            {
+            if (ca != null) {
                 value = ca.getValueAsString();
                 ca.release();
             }
@@ -498,149 +465,136 @@
             return value;
         }
 
-        public boolean isAttributeSpecified ( int index )
-        {
+        public boolean isAttributeSpecified(int index) {
             // Go to attr to force index check
-            Cur ca = toAttr( _cur, index );
+            Cur ca = toAttr(_cur, index);
             ca.release();
 
             return false;
         }
 
-        public int getNamespaceCount ( )
-        {
+        public int getNamespaceCount() {
             int n = 0;
 
-            if (_cur.isElem() || _cur.kind() == -Cur.ELEM)
-            {
+            if (_cur.isElem() || _cur.kind() == -Cur.ELEM) {
                 Cur ca = _cur.tempCur();
 
-                if (_cur.kind() == -Cur.ELEM)
+                if (_cur.kind() == -Cur.ELEM) {
                     ca.toParent();
+                }
 
-                if (ca.toFirstAttr())
-                {
-                    do
-                    {
-                        if (ca.isXmlns())
+                if (ca.toFirstAttr()) {
+                    do {
+                        if (ca.isXmlns()) {
                             n++;
+                        }
                     }
-                    while ( ca.toNextSibling() );
+                    while (ca.toNextSibling());
                 }
 
                 ca.release();
-            }
-            else if (_cur.isXmlns())
+            } else if (_cur.isXmlns()) {
                 n++;
-            else
+            } else {
                 throw new IllegalStateException();
+            }
 
             return n;
         }
 
-        private static Cur toXmlns ( Cur c, int i )
-        {
-            if (i < 0)
-                throw new IndexOutOfBoundsException( "Namespace index is negative" );
+        private static Cur toXmlns(Cur c, int i) {
+            if (i < 0) {
+                throw new IndexOutOfBoundsException("Namespace index is negative");
+            }
 
             Cur ca = c.tempCur();
             boolean match = false;
 
-            if (c.isElem() || c.kind() == -Cur.ELEM)
-            {
-                if (c.kind() == -Cur.ELEM)
+            if (c.isElem() || c.kind() == -Cur.ELEM) {
+                if (c.kind() == -Cur.ELEM) {
                     ca.toParent();
+                }
 
-                if (ca.toFirstAttr())
-                {
-                    do
-                    {
-                        if (ca.isXmlns() && i-- == 0)
-                        {
+                if (ca.toFirstAttr()) {
+                    do {
+                        if (ca.isXmlns() && i-- == 0) {
                             match = true;
                             break;
                         }
                     }
-                    while ( ca.toNextSibling() );
+                    while (ca.toNextSibling());
                 }
-            }
-            else if (c.isXmlns())
+            } else if (c.isXmlns()) {
                 match = i == 0;
-            else
+            } else {
                 throw new IllegalStateException();
+            }
 
-            if (!match)
-            {
+            if (!match) {
                 ca.release();
-                throw new IndexOutOfBoundsException( "Namespace index is too large" );
+                throw new IndexOutOfBoundsException("Namespace index is too large");
             }
 
             return ca;
         }
 
-        public String getNamespacePrefix ( int index )
-        {
-            Cur ca = toXmlns( _cur, index );
+        public String getNamespacePrefix(int index) {
+            Cur ca = toXmlns(_cur, index);
             String prefix = ca.getXmlnsPrefix();
             ca.release();
             return prefix;
         }
 
-        public String getNamespaceURI ( int index )
-        {
-            Cur ca = toXmlns( _cur, index );
+        public String getNamespaceURI(int index) {
+            Cur ca = toXmlns(_cur, index);
             String uri = ca.getXmlnsUri();
             ca.release();
             return uri;
         }
 
-        private void fetchChars ( )
-        {
-            if (!_textFetched)
-            {
+        private void fetchChars() {
+            if (!_textFetched) {
                 int k = _cur.kind();
 
                 Cur cText = null;
 
-                if (k == Cur.COMMENT)
-                {
+                if (k == Cur.COMMENT) {
                     cText = _cur.tempCur();
                     cText.next();
-                }
-                else if (k == Cur.TEXT)
+                } else if (k == Cur.TEXT) {
                     cText = _cur;
-                else
+                } else {
                     throw new IllegalStateException();
+                }
 
-                Object src = cText.getChars( -1 );
+                Object src = cText.getChars(-1);
 
-                ensureCharBufLen( cText._cchSrc );
+                ensureCharBufLen(cText._cchSrc);
 
                 CharUtil.getChars(
-                    _chars, _offChars = 0, src, cText._offSrc, _cchChars = cText._cchSrc );
+                    _chars, _offChars = 0, src, cText._offSrc, _cchChars = cText._cchSrc);
 
-                if (cText != _cur)
+                if (cText != _cur) {
                     cText.release();
+                }
 
                 _textFetched = true;
             }
         }
 
-        private void ensureCharBufLen ( int cch )
-        {
-            if (_chars == null || _chars.length < cch)
-            {
+        private void ensureCharBufLen(int cch) {
+            if (_chars == null || _chars.length < cch) {
                 int l = 256;
 
-                while ( l < cch )
+                while (l < cch) {
                     l *= 2;
+                }
 
-                _chars = new char [ l ];
+                _chars = new char[l];
             }
         }
 
-        public char[] getTextCharacters ( )
-        {
+        public char[] getTextCharacters() {
             checkChanged();
 
             fetchChars();
@@ -648,8 +602,7 @@
             return _chars;
         }
 
-        public int getTextStart ( )
-        {
+        public int getTextStart() {
             checkChanged();
 
             fetchChars();
@@ -657,8 +610,7 @@
             return _offChars;
         }
 
-        public int getTextLength ( )
-        {
+        public int getTextLength() {
             checkChanged();
 
             fetchChars();
@@ -666,99 +618,95 @@
             return _cchChars;
         }
 
-        public int getTextCharacters (
-            int sourceStart, char[] target, int targetStart, int length )
-                throws XMLStreamException
-        {
-            if (length < 0)
+        public int getTextCharacters(
+            int sourceStart, char[] target, int targetStart, int length)
+            throws XMLStreamException {
+            if (length < 0) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (targetStart < 0 || targetStart >= target.length)
+            if (targetStart < 0 || targetStart >= target.length) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (targetStart + length > target.length)
+            if (targetStart + length > target.length) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (!_srcFetched)
-            {
+            if (!_srcFetched) {
                 int k = _cur.kind();
 
                 Cur cText = null;
 
-                if (k == Cur.COMMENT)
-                {
+                if (k == Cur.COMMENT) {
                     cText = _cur.tempCur();
                     cText.next();
-                }
-                else if (k == Cur.TEXT)
+                } else if (k == Cur.TEXT) {
                     cText = _cur;
-                else
+                } else {
                     throw new IllegalStateException();
+                }
 
-                _src = cText.getChars( -1 );
+                _src = cText.getChars(-1);
                 _offSrc = cText._offSrc;
                 _cchSrc = cText._cchSrc;
 
-                if (cText != _cur)
+                if (cText != _cur) {
                     cText.release();
+                }
 
                 _srcFetched = true;
             }
 
-            if (sourceStart > _cchSrc)
+            if (sourceStart > _cchSrc) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (sourceStart + length > _cchSrc)
+            if (sourceStart + length > _cchSrc) {
                 length = _cchSrc - sourceStart;
+            }
 
-            CharUtil.getChars( target, targetStart, _src, _offSrc, length );
+            CharUtil.getChars(target, targetStart, _src, _offSrc, length);
 
             return length;
         }
 
-        public boolean hasText ( )
-        {
+        public boolean hasText() {
             int k = _cur.kind();
 
             return k == Cur.COMMENT || k == Cur.TEXT;
         }
 
-        public boolean hasName ( )
-        {
+        public boolean hasName() {
             int k = _cur.kind();
             return k == Cur.ELEM || k == -Cur.ELEM;
         }
 
-        public QName getName ( )
-        {
-            if (!hasName())
+        public QName getName() {
+            if (!hasName()) {
                 throw new IllegalStateException();
+            }
 
             return _cur.getName();
         }
 
-        public String getNamespaceURI ( )
-        {
+        public String getNamespaceURI() {
             return getName().getNamespaceURI();
         }
 
-        public String getLocalName ( )
-        {
+        public String getLocalName() {
             return getName().getLocalPart();
         }
 
-        public String getPrefix ( )
-        {
+        public String getPrefix() {
             return getName().getPrefix();
         }
 
-        public String getPITarget ( )
-        {
+        public String getPITarget() {
             return _cur.kind() == Cur.PROCINST ? _cur.getName().getLocalPart() : null;
         }
 
-        public String getPIData ( )
-        {
+        public String getPIData() {
             return _cur.kind() == Cur.PROCINST ? _cur.getValueAsString() : null;
         }
 
@@ -773,14 +721,14 @@
         private Cur _end;
 
         private boolean _srcFetched;
-        private Object  _src;
-        private int     _offSrc;
-        private int     _cchSrc;
+        private Object _src;
+        private int _offSrc;
+        private int _cchSrc;
 
         private boolean _textFetched;
-        private char[]  _chars;
-        private int     _offChars;
-        private int     _cchChars;
+        private char[] _chars;
+        private int _offChars;
+        private int _cchChars;
     }
 
     //
@@ -788,58 +736,50 @@
     //
 
     private static abstract class XMLStreamReaderBase
-        implements XMLStreamReader, NamespaceContext, Location
-    {
-        XMLStreamReaderBase ( Cur c )
-        {
+        implements XMLStreamReader, NamespaceContext, Location {
+        XMLStreamReaderBase(Cur c) {
             _locale = c._locale;
             _version = _locale.version();
         }
 
-        protected final void checkChanged ( )
-        {
-            if (_version != _locale.version())
-                throw new ConcurrentModificationException( "Document changed while streaming" );
+        protected final void checkChanged() {
+            if (_version != _locale.version()) {
+                throw new ConcurrentModificationException("Document changed while streaming");
+            }
         }
 
         //
         // XMLStreamReader methods
         //
 
-        public void close ( ) throws XMLStreamException
-        {
+        public void close() throws XMLStreamException {
             checkChanged();
         }
 
-        public boolean isWhiteSpace ( )
-        {
+        public boolean isWhiteSpace() {
             checkChanged();
 
             // TODO - avoid creating a string here
             String s = getText();
 
-            return _locale.getCharUtil().isWhiteSpace( s, 0, s.length() );
+            return _locale.getCharUtil().isWhiteSpace(s, 0, s.length());
         }
 
-        public Location getLocation ( )
-        {
+        public Location getLocation() {
             checkChanged();
 
             Cur c = getStreamCur();
 
-            XmlLineNumber ln = (XmlLineNumber) c.getBookmark( XmlLineNumber.class );
+            XmlLineNumber ln = (XmlLineNumber) c.getBookmark(XmlLineNumber.class);
 
             // BUGBUG - put source name here
             _uri = null;
 
-            if (ln != null)
-            {
+            if (ln != null) {
                 _line = ln.getLine();
                 _column = ln.getColumn();
                 _offset = ln.getOffset();
-            }
-            else
-            {
+            } else {
                 _line = -1;
                 _column = -1;
                 _offset = -1;
@@ -849,135 +789,146 @@
         }
 
 
-        public Object getProperty ( String name )
-        {
+        public Object getProperty(String name) {
             checkChanged();
 
-            if (name == null)
-                throw new IllegalArgumentException( "Property name is null" );
+            if (name == null) {
+                throw new IllegalArgumentException("Property name is null");
+            }
 
             // BUGBUG - I should implement some perperties here
 
             return null;
         }
 
-        public String getCharacterEncodingScheme ( )
-        {
+        public String getCharacterEncodingScheme() {
             checkChanged();
 
-            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );
+            XmlDocumentProperties props = _locale.getDocProps(getStreamCur(), false);
 
             return props == null ? null : props.getEncoding();
         }
 
-        public String getEncoding ( )
-        {
+        public String getEncoding() {
             // BUGBUG - this should probably return the actual decoding used on the document
             return null;
         }
 
-        public String getVersion ( )
-        {
+        public String getVersion() {
             checkChanged();
 
-            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );
+            XmlDocumentProperties props = _locale.getDocProps(getStreamCur(), false);
 
             return props == null ? null : props.getVersion();
         }
 
-        public boolean isStandalone ( )
-        {
+        public boolean isStandalone() {
             checkChanged();
 
-            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );
+            XmlDocumentProperties props = _locale.getDocProps(getStreamCur(), false);
 
             return props == null ? false : props.getStandalone();
         }
 
-        public boolean standaloneSet ( )
-        {
+        public boolean standaloneSet() {
             checkChanged();
 
             return false;
         }
 
-        public void require ( int type, String namespaceURI, String localName )
-            throws XMLStreamException
-        {
+        public void require(int type, String namespaceURI, String localName)
+            throws XMLStreamException {
             checkChanged();
 
-            if (type != getEventType())
+            if (type != getEventType()) {
                 throw new XMLStreamException();
+            }
 
-            if (namespaceURI != null && !getNamespaceURI().equals( namespaceURI ))
+            if (namespaceURI != null && !getNamespaceURI().equals(namespaceURI)) {
                 throw new XMLStreamException();
+            }
 
-            if (localName != null && !getLocalName().equals( localName ))
+            if (localName != null && !getLocalName().equals(localName)) {
                 throw new XMLStreamException();
+            }
         }
 
         //
         // Location methods do not need a gatway
         //
 
-        public int    getCharacterOffset ( ) { return _offset; }
-        public int    getColumnNumber    ( ) { return _column; }
-        public int    getLineNumber      ( ) { return _line;   }
-        public String getLocationURI     ( ) { return _uri;    }
-
-        public String getPublicId ( ) { return null; }
-        public String getSystemId ( ) { return null; }
-
-        public NamespaceContext getNamespaceContext ( )
-        {
-            throw new RuntimeException( "This version of getNamespaceContext should not be called");
+        public int getCharacterOffset() {
+            return _offset;
         }
 
-        public String getNamespaceURI ( String prefix )
-        {
+        public int getColumnNumber() {
+            return _column;
+        }
+
+        public int getLineNumber() {
+            return _line;
+        }
+
+        public String getLocationURI() {
+            return _uri;
+        }
+
+        public String getPublicId() {
+            return null;
+        }
+
+        public String getSystemId() {
+            return null;
+        }
+
+        public NamespaceContext getNamespaceContext() {
+            throw new RuntimeException("This version of getNamespaceContext should not be called");
+        }
+
+        public String getNamespaceURI(String prefix) {
             checkChanged();
 
             Cur c = getStreamCur();
 
             c.push();
 
-            if (!c.isContainer())
+            if (!c.isContainer()) {
                 c.toParent();
+            }
 
-            String ns = c.namespaceForPrefix( prefix, true );
+            String ns = c.namespaceForPrefix(prefix, true);
 
             c.pop();
 
             return ns;
         }
 
-        public String getPrefix ( String namespaceURI )
-        {
+        public String getPrefix(String namespaceURI) {
             checkChanged();
 
             Cur c = getStreamCur();
 
             c.push();
 
-            if (!c.isContainer())
+            if (!c.isContainer()) {
                 c.toParent();
+            }
 
-            String prefix = c.prefixForNamespace( namespaceURI, null, false );
+            String prefix = c.prefixForNamespace(namespaceURI, null, false);
 
             c.pop();
 
             return prefix;
         }
 
-        public Iterator getPrefixes ( String namespaceURI )
-        {
+        public Iterator getPrefixes(String namespaceURI) {
             checkChanged();
 
             // BUGBUG - get only one for now ...
 
             HashMap map = new HashMap();
 
-            map.put( namespaceURI, getPrefix( namespaceURI ) );
+            map.put(namespaceURI, getPrefix(namespaceURI));
 
             return map.values().iterator();
         }
@@ -986,18 +937,18 @@
         //
         //
 
-        protected abstract Cur getStreamCur ( );
+        protected abstract Cur getStreamCur();
 
         //
         //
         //
 
         private Locale _locale;
-        private long   _version;
+        private long _version;
 
         String _uri;
 
-        int _line   = -1;
+        int _line = -1;
         int _column = -1;
         int _offset = -1;
     }
@@ -1006,11 +957,9 @@
     //
     //
 
-    private static final class XMLStreamReaderForString extends XMLStreamReaderBase
-    {
-        XMLStreamReaderForString ( Cur c, Object src, int off, int cch )
-        {
-            super( c );
+    private static final class XMLStreamReaderForString extends XMLStreamReaderBase {
+        XMLStreamReaderForString(Cur c, Object src, int off, int cch) {
+            super(c);
 
             _src = src;
             _off = off;
@@ -1019,8 +968,7 @@
             _cur = c;
         }
 
-        protected Cur getStreamCur ( )
-        {
+        protected Cur getStreamCur() {
             return _cur;
         }
 
@@ -1028,224 +976,1271 @@
         // Legal stream methods
         //
 
-        public String getText ( )
-        {
+        public String getText() {
             checkChanged();
 
-            return CharUtil.getString( _src, _off, _cch );
+            return CharUtil.getString(_src, _off, _cch);
         }
 
-        public char[] getTextCharacters ( )
-        {
+        public char[] getTextCharacters() {
             checkChanged();
 
-            char[] chars = new char [ _cch ];
+            char[] chars = new char[_cch];
 
-            CharUtil.getChars( chars, 0, _src, _off, _cch );
+            CharUtil.getChars(chars, 0, _src, _off, _cch);
 
             return chars;
         }
-        public int getTextStart ( )
-        {
+
+        public int getTextStart() {
             checkChanged();
 
             return _off;
         }
-        public int getTextLength ( )
-        {
+
+        public int getTextLength() {
             checkChanged();
 
             return _cch;
         }
 
-        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length )
-        {
+        public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) {
             checkChanged();
 
-            if (length < 0)
+            if (length < 0) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (sourceStart > _cch)
+            if (sourceStart > _cch) {
                 throw new IndexOutOfBoundsException();
+            }
 
-            if (sourceStart + length > _cch)
+            if (sourceStart + length > _cch) {
                 length = _cch - sourceStart;
+            }
 
-            CharUtil.getChars( target, targetStart, _src, _off + sourceStart, length );
+            CharUtil.getChars(target, targetStart, _src, _off + sourceStart, length);
 
             return length;
         }
 
-        public int     getEventType      ( ) { checkChanged(); return CHARACTERS; }
-        public boolean hasName           ( ) { checkChanged(); return false;      }
-        public boolean hasNext           ( ) { checkChanged(); return false;      }
-        public boolean hasText           ( ) { checkChanged(); return true;       }
-        public boolean isCharacters      ( ) { checkChanged(); return true;       }
-        public boolean isEndElement      ( ) { checkChanged(); return false;      }
-        public boolean isStartElement    ( ) { checkChanged(); return false;      }
+        public int getEventType() {
+            checkChanged();
+            return CHARACTERS;
+        }
+
+        public boolean hasName() {
+            checkChanged();
+            return false;
+        }
+
+        public boolean hasNext() {
+            checkChanged();
+            return false;
+        }
+
+        public boolean hasText() {
+            checkChanged();
+            return true;
+        }
+
+        public boolean isCharacters() {
+            checkChanged();
+            return true;
+        }
+
+        public boolean isEndElement() {
+            checkChanged();
+            return false;
+        }
+
+        public boolean isStartElement() {
+            checkChanged();
+            return false;
+        }
 
         //
         // Illegal stream methods
         //
 
-        public int     getAttributeCount ( ) { throw new IllegalStateException(); }
-        public String  getAttributeLocalName ( int index ) { throw new IllegalStateException(); }
-        public QName   getAttributeName ( int index ) { throw new IllegalStateException(); }
-        public String  getAttributeNamespace ( int index ) { throw new IllegalStateException(); }
-        public String  getAttributePrefix ( int index ) { throw new IllegalStateException(); }
-        public String  getAttributeType ( int index ) { throw new IllegalStateException(); }
-        public String  getAttributeValue ( int index ) { throw new IllegalStateException(); }
-        public String  getAttributeValue ( String namespaceURI, String localName ) { throw new IllegalStateException(); }
-        public String  getElementText ( ) { throw new IllegalStateException(); }
-        public String  getLocalName ( ) { throw new IllegalStateException(); }
-        public QName   getName ( ) { throw new IllegalStateException(); }
-        public int     getNamespaceCount ( ) { throw new IllegalStateException(); }
-        public String  getNamespacePrefix ( int index ) { throw new IllegalStateException(); }
-        public String  getNamespaceURI ( int index ) { throw new IllegalStateException(); }
-        public String  getNamespaceURI ( ) { throw new IllegalStateException(); }
-        public String  getPIData ( ) { throw new IllegalStateException(); }
-        public String  getPITarget ( ) { throw new IllegalStateException(); }
-        public String  getPrefix ( ) { throw new IllegalStateException(); }
-        public boolean isAttributeSpecified ( int index ) { throw new IllegalStateException(); }
-        public int     next ( ) { throw new IllegalStateException(); }
-        public int     nextTag ( ) { throw new IllegalStateException(); }
-        public String  getPublicId() { throw new IllegalStateException();  }
-        public String  getSystemId() { throw new IllegalStateException();  }
+        public int getAttributeCount() {
+            throw new IllegalStateException();
+        }
 
-        private Cur    _cur;
+        public String getAttributeLocalName(int index) {
+            throw new IllegalStateException();
+        }
+
+        public QName getAttributeName(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getAttributeNamespace(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getAttributePrefix(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getAttributeType(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getAttributeValue(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getAttributeValue(String namespaceURI, String localName) {
+            throw new IllegalStateException();
+        }
+
+        public String getElementText() {
+            throw new IllegalStateException();
+        }
+
+        public String getLocalName() {
+            throw new IllegalStateException();
+        }
+
+        public QName getName() {
+            throw new IllegalStateException();
+        }
+
+        public int getNamespaceCount() {
+            throw new IllegalStateException();
+        }
+
+        public String getNamespacePrefix(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getNamespaceURI(int index) {
+            throw new IllegalStateException();
+        }
+
+        public String getNamespaceURI() {
+            throw new IllegalStateException();
+        }
+
+        public String getPIData() {
+            throw new IllegalStateException();
+        }
+
+        public String getPITarget() {
+            throw new IllegalStateException();
+        }
+
+        public String getPrefix() {
+            throw new IllegalStateException();
+        }
+
+        public boolean isAttributeSpecified(int index) {
+            throw new IllegalStateException();
+        }
+
+        public int next() {
+            throw new IllegalStateException();
+        }
+
+        public int nextTag() {
+            throw new IllegalStateException();
+        }
+
+        public String getPublicId() {
+            throw new IllegalStateException();
+        }
+
+        public String getSystemId() {
+            throw new IllegalStateException();
+        }
+
+        private Cur _cur;
         private Object _src;
-        private int    _off;
-        private int    _cch;
+        private int _off;
+        private int _cch;
     }
 
     //
     //
     //
 
-    private static abstract class Jsr173GateWay
-    {
-        public Jsr173GateWay ( Locale l, XMLStreamReaderBase xs ) { _l = l; _xs = xs; }
+    private static abstract class Jsr173GateWay {
+        public Jsr173GateWay(Locale l, XMLStreamReaderBase xs) {
+            _l = l;
+            _xs = xs;
+        }
 
-        Locale              _l;
+        Locale _l;
         XMLStreamReaderBase _xs;
     }
 
-    private static final class SyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext
-    {
-        public SyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); }
+    private static final class SyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext {
+        public SyncedJsr173(Locale l, XMLStreamReaderBase xs) {
+            super(l, xs);
+        }
 
-        public Object getProperty ( java.lang.String name ) { synchronized ( _l ) { _l.enter(); try { return _xs.getProperty( name ); } finally { _l.exit(); } } }
-        public int next ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.next(); } finally { _l.exit(); } } }
-        public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } } }
-        public String getElementText ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getElementText(); } finally { _l.exit(); } } }
-        public int nextTag ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.nextTag(); } finally { _l.exit(); } } }
-        public boolean hasNext ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.hasNext(); } finally { _l.exit(); } } }
-        public void close ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.close(); } finally { _l.exit(); } } }
-        public String getNamespaceURI ( String prefix ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } } }
-        public boolean isStartElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStartElement(); } finally { _l.exit(); } } }
-        public boolean isEndElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isEndElement(); } finally { _l.exit(); } } }
-        public boolean isCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isCharacters(); } finally { _l.exit(); } } }
-        public boolean isWhiteSpace ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isWhiteSpace(); } finally { _l.exit(); } } }
-        public String getAttributeValue ( String namespaceURI, String localName ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } } }
-        public int getAttributeCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeCount(); } finally { _l.exit(); } } }
-        public QName getAttributeName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeName ( index ); } finally { _l.exit(); } } }
-        public String getAttributeNamespace ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } } }
-        public String getAttributeLocalName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } } }
-        public String getAttributePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } } }
-        public String getAttributeType ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeType ( index ); } finally { _l.exit(); } } }
-        public String getAttributeValue ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( index ); } finally { _l.exit(); } } }
-        public boolean isAttributeSpecified ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } } }
-        public int getNamespaceCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceCount(); } finally { _l.exit(); } } }
-        public String getNamespacePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } } }
-        public String getNamespaceURI ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } } }
-        public NamespaceContext getNamespaceContext ( ) { return this; }
-        public int getEventType ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEventType(); } finally { _l.exit(); } } }
-        public String getText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getText(); } finally { _l.exit(); } } }
-        public char[] getTextCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters(); } finally { _l.exit(); } } }
-        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } } }
-        public int getTextStart ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextStart(); } finally { _l.exit(); } } }
-        public int getTextLength ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextLength(); } finally { _l.exit(); } } }
-        public String getEncoding ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEncoding(); } finally { _l.exit(); } } }
-        public boolean hasText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasText(); } finally { _l.exit(); } } }
-        public Location getLocation ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocation(); } finally { _l.exit(); } } }
-        public QName getName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getName(); } finally { _l.exit(); } } }
-        public String getLocalName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocalName(); } finally { _l.exit(); } } }
-        public boolean hasName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasName(); } finally { _l.exit(); } } }
-        public String getNamespaceURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI(); } finally { _l.exit(); } } }
-        public String getPrefix ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix(); } finally { _l.exit(); } } }
-        public String getVersion ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getVersion(); } finally { _l.exit(); } } }
-        public boolean isStandalone ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStandalone(); } finally { _l.exit(); } } }
-        public boolean standaloneSet ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.standaloneSet(); } finally { _l.exit(); } } }
-        public String getCharacterEncodingScheme ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } } }
-        public String getPITarget ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPITarget(); } finally { _l.exit(); } } }
-        public String getPIData ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPIData(); } finally { _l.exit(); } } }
-        public String getPrefix ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } } }
-        public Iterator getPrefixes ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } } }
-        public int getCharacterOffset ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterOffset(); } finally { _l.exit(); } } }
-        public int getColumnNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getColumnNumber(); } finally { _l.exit(); } } }
-        public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } }
-        public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } }
-        public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } }
-        public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } }
+        public Object getProperty(java.lang.String name) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getProperty(name);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int next() throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.next();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    _xs.require(type, namespaceURI, localName);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getElementText() throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getElementText();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int nextTag() throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.nextTag();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean hasNext() throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.hasNext();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public void close() throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    _xs.close();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getNamespaceURI(String prefix) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getNamespaceURI(prefix);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isStartElement() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isStartElement();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isEndElement() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isEndElement();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isCharacters() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isCharacters();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isWhiteSpace() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isWhiteSpace();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributeValue(String namespaceURI, String localName) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeValue(namespaceURI, localName);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getAttributeCount() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeCount();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public QName getAttributeName(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeName(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributeNamespace(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeNamespace(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributeLocalName(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeLocalName(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributePrefix(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributePrefix(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributeType(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeType(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getAttributeValue(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getAttributeValue(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isAttributeSpecified(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isAttributeSpecified(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getNamespaceCount() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getNamespaceCount();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getNamespacePrefix(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getNamespacePrefix(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getNamespaceURI(int index) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getNamespaceURI(index);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public NamespaceContext getNamespaceContext() {
+            return this;
+        }
+
+        public int getEventType() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getEventType();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getText() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getText();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public char[] getTextCharacters() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getTextCharacters();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getTextCharacters(sourceStart, target, targetStart, length);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getTextStart() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getTextStart();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getTextLength() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getTextLength();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getEncoding() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getEncoding();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean hasText() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.hasText();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public Location getLocation() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLocation();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public QName getName() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getName();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getLocalName() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLocalName();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean hasName() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.hasName();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getNamespaceURI() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getNamespaceURI();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPrefix() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPrefix();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getVersion() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getVersion();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean isStandalone() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.isStandalone();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public boolean standaloneSet() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.standaloneSet();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getCharacterEncodingScheme() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getCharacterEncodingScheme();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPITarget() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPITarget();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPIData() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPIData();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPrefix(String namespaceURI) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPrefix(namespaceURI);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public Iterator getPrefixes(String namespaceURI) {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPrefixes(namespaceURI);
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getCharacterOffset() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getCharacterOffset();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getColumnNumber() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getColumnNumber();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public int getLineNumber() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLineNumber();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getLocationURI() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLocationURI();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPublicId() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPublicId();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getSystemId() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getSystemId();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
     }
 
-    private static final class UnsyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext
-    {
-        public UnsyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); }
+    private static final class UnsyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext {
+        public UnsyncedJsr173(Locale l, XMLStreamReaderBase xs) {
+            super(l, xs);
+        }
 
-        public Object getProperty ( java.lang.String name ) { try { _l.enter(); return _xs.getProperty( name ); } finally { _l.exit(); } }
-        public int next ( ) throws XMLStreamException { try { _l.enter(); return _xs.next(); } finally { _l.exit(); } }
-        public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { try { _l.enter(); _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } }
-        public String getElementText ( ) throws XMLStreamException { try { _l.enter(); return _xs.getElementText(); } finally { _l.exit(); } }
-        public int nextTag ( ) throws XMLStreamException { try { _l.enter(); return _xs.nextTag(); } finally { _l.exit(); } }
-        public boolean hasNext ( ) throws XMLStreamException { try { _l.enter(); return _xs.hasNext(); } finally { _l.exit(); } }
-        public void close ( ) throws XMLStreamException { try { _l.enter(); _xs.close(); } finally { _l.exit(); } }
-        public String getNamespaceURI ( String prefix ) { try { _l.enter(); return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } }
-        public boolean isStartElement ( ) { try { _l.enter(); return _xs.isStartElement(); } finally { _l.exit(); } }
-        public boolean isEndElement ( ) { try { _l.enter(); return _xs.isEndElement(); } finally { _l.exit(); } }
-        public boolean isCharacters ( ) { try { _l.enter(); return _xs.isCharacters(); } finally { _l.exit(); } }
-        public boolean isWhiteSpace ( ) { try { _l.enter(); return _xs.isWhiteSpace(); } finally { _l.exit(); } }
-        public String getAttributeValue ( String namespaceURI, String localName ) { try { _l.enter(); return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } }
-        public int getAttributeCount ( ) { try { _l.enter(); return _xs.getAttributeCount(); } finally { _l.exit(); } }
-        public QName getAttributeName ( int index ) { try { _l.enter(); return _xs.getAttributeName ( index ); } finally { _l.exit(); } }
-        public String getAttributeNamespace ( int index ) { try { _l.enter(); return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } }
-        public String getAttributeLocalName ( int index ) { try { _l.enter(); return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } }
-        public String getAttributePrefix ( int index ) { try { _l.enter(); return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } }
-        public String getAttributeType ( int index ) { try { _l.enter(); return _xs.getAttributeType ( index ); } finally { _l.exit(); } }
-        public String getAttributeValue ( int index ) { try { _l.enter(); return _xs.getAttributeValue ( index ); } finally { _l.exit(); } }
-        public boolean isAttributeSpecified ( int index ) { try { _l.enter(); return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } }
-        public int getNamespaceCount ( ) { try { _l.enter(); return _xs.getNamespaceCount(); } finally { _l.exit(); } }
-        public String getNamespacePrefix ( int index ) { try { _l.enter(); return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } }
-        public String getNamespaceURI ( int index ) { try { _l.enter(); return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } }
-        public NamespaceContext getNamespaceContext ( ) { return this; }
-        public int getEventType ( ) { try { _l.enter(); return _xs.getEventType(); } finally { _l.exit(); } }
-        public String getText ( ) { try { _l.enter(); return _xs.getText(); } finally { _l.exit(); } }
-        public char[] getTextCharacters ( ) { try { _l.enter(); return _xs.getTextCharacters(); } finally { _l.exit(); } }
-        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { try { _l.enter(); return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } }
-        public int getTextStart ( ) { try { _l.enter(); return _xs.getTextStart(); } finally { _l.exit(); } }
-        public int getTextLength ( ) { try { _l.enter(); return _xs.getTextLength(); } finally { _l.exit(); } }
-        public String getEncoding ( ) { try { _l.enter(); return _xs.getEncoding(); } finally { _l.exit(); } }
-        public boolean hasText ( ) { try { _l.enter(); return _xs.hasText(); } finally { _l.exit(); } }
-        public Location getLocation ( ) { try { _l.enter(); return _xs.getLocation(); } finally { _l.exit(); } }
-        public QName getName ( ) { try { _l.enter(); return _xs.getName(); } finally { _l.exit(); } }
-        public String getLocalName ( ) { try { _l.enter(); return _xs.getLocalName(); } finally { _l.exit(); } }
-        public boolean hasName ( ) { try { _l.enter(); return _xs.hasName(); } finally { _l.exit(); } }
-        public String getNamespaceURI ( ) { try { _l.enter(); return _xs.getNamespaceURI(); } finally { _l.exit(); } }
-        public String getPrefix ( ) { try { _l.enter(); return _xs.getPrefix(); } finally { _l.exit(); } }
-        public String getVersion ( ) { try { _l.enter(); return _xs.getVersion(); } finally { _l.exit(); } }
-        public boolean isStandalone ( ) { try { _l.enter(); return _xs.isStandalone(); } finally { _l.exit(); } }
-        public boolean standaloneSet ( ) { try { _l.enter(); return _xs.standaloneSet(); } finally { _l.exit(); } }
-        public String getCharacterEncodingScheme ( ) { try { _l.enter(); return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } }
-        public String getPITarget ( ) { try { _l.enter(); return _xs.getPITarget(); } finally { _l.exit(); } }
-        public String getPIData ( ) { try { _l.enter(); return _xs.getPIData(); } finally { _l.exit(); } }
-        public String getPrefix ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } }
-        public Iterator getPrefixes ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } }
-        public int getCharacterOffset ( ) { try { _l.enter(); return _xs.getCharacterOffset(); } finally { _l.exit(); } }
-        public int getColumnNumber ( ) { try { _l.enter(); return _xs.getColumnNumber(); } finally { _l.exit(); } }
-        public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } }
-        public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } }
-        public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } }
-        public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } }
+        public Object getProperty(java.lang.String name) {
+            try {
+                _l.enter();
+                return _xs.getProperty(name);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int next() throws XMLStreamException {
+            try {
+                _l.enter();
+                return _xs.next();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+            try {
+                _l.enter();
+                _xs.require(type, namespaceURI, localName);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getElementText() throws XMLStreamException {
+            try {
+                _l.enter();
+                return _xs.getElementText();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int nextTag() throws XMLStreamException {
+            try {
+                _l.enter();
+                return _xs.nextTag();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean hasNext() throws XMLStreamException {
+            try {
+                _l.enter();
+                return _xs.hasNext();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public void close() throws XMLStreamException {
+            try {
+                _l.enter();
+                _xs.close();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getNamespaceURI(String prefix) {
+            try {
+                _l.enter();
+                return _xs.getNamespaceURI(prefix);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isStartElement() {
+            try {
+                _l.enter();
+                return _xs.isStartElement();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isEndElement() {
+            try {
+                _l.enter();
+                return _xs.isEndElement();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isCharacters() {
+            try {
+                _l.enter();
+                return _xs.isCharacters();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isWhiteSpace() {
+            try {
+                _l.enter();
+                return _xs.isWhiteSpace();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributeValue(String namespaceURI, String localName) {
+            try {
+                _l.enter();
+                return _xs.getAttributeValue(namespaceURI, localName);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getAttributeCount() {
+            try {
+                _l.enter();
+                return _xs.getAttributeCount();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public QName getAttributeName(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributeName(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributeNamespace(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributeNamespace(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributeLocalName(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributeLocalName(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributePrefix(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributePrefix(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributeType(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributeType(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getAttributeValue(int index) {
+            try {
+                _l.enter();
+                return _xs.getAttributeValue(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isAttributeSpecified(int index) {
+            try {
+                _l.enter();
+                return _xs.isAttributeSpecified(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getNamespaceCount() {
+            try {
+                _l.enter();
+                return _xs.getNamespaceCount();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getNamespacePrefix(int index) {
+            try {
+                _l.enter();
+                return _xs.getNamespacePrefix(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getNamespaceURI(int index) {
+            try {
+                _l.enter();
+                return _xs.getNamespaceURI(index);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public NamespaceContext getNamespaceContext() {
+            return this;
+        }
+
+        public int getEventType() {
+            try {
+                _l.enter();
+                return _xs.getEventType();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getText() {
+            try {
+                _l.enter();
+                return _xs.getText();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public char[] getTextCharacters() {
+            try {
+                _l.enter();
+                return _xs.getTextCharacters();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+            try {
+                _l.enter();
+                return _xs.getTextCharacters(sourceStart, target, targetStart, length);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getTextStart() {
+            try {
+                _l.enter();
+                return _xs.getTextStart();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getTextLength() {
+            try {
+                _l.enter();
+                return _xs.getTextLength();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getEncoding() {
+            try {
+                _l.enter();
+                return _xs.getEncoding();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean hasText() {
+            try {
+                _l.enter();
+                return _xs.hasText();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public Location getLocation() {
+            try {
+                _l.enter();
+                return _xs.getLocation();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public QName getName() {
+            try {
+                _l.enter();
+                return _xs.getName();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getLocalName() {
+            try {
+                _l.enter();
+                return _xs.getLocalName();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean hasName() {
+            try {
+                _l.enter();
+                return _xs.hasName();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getNamespaceURI() {
+            try {
+                _l.enter();
+                return _xs.getNamespaceURI();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getPrefix() {
+            try {
+                _l.enter();
+                return _xs.getPrefix();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getVersion() {
+            try {
+                _l.enter();
+                return _xs.getVersion();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean isStandalone() {
+            try {
+                _l.enter();
+                return _xs.isStandalone();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public boolean standaloneSet() {
+            try {
+                _l.enter();
+                return _xs.standaloneSet();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getCharacterEncodingScheme() {
+            try {
+                _l.enter();
+                return _xs.getCharacterEncodingScheme();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getPITarget() {
+            try {
+                _l.enter();
+                return _xs.getPITarget();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getPIData() {
+            try {
+                _l.enter();
+                return _xs.getPIData();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public String getPrefix(String namespaceURI) {
+            try {
+                _l.enter();
+                return _xs.getPrefix(namespaceURI);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public Iterator getPrefixes(String namespaceURI) {
+            try {
+                _l.enter();
+                return _xs.getPrefixes(namespaceURI);
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getCharacterOffset() {
+            try {
+                _l.enter();
+                return _xs.getCharacterOffset();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getColumnNumber() {
+            try {
+                _l.enter();
+                return _xs.getColumnNumber();
+            } finally {
+                _l.exit();
+            }
+        }
+
+        public int getLineNumber() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLineNumber();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getLocationURI() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getLocationURI();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getPublicId() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getPublicId();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
+
+        public String getSystemId() {
+            synchronized (_l) {
+                _l.enter();
+                try {
+                    return _xs.getSystemId();
+                } finally {
+                    _l.exit();
+                }
+            }
+        }
     }
 }
 
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 de04bd0..942b0e7 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Locale.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Locale.java
@@ -44,8 +44,7 @@
 import java.util.Map;
 
 public final class Locale
-    implements DOMImplementation, SaajCallback, XmlLocale
-{
+    implements DOMImplementation, SaajCallback, XmlLocale {
     private static final XBLogger logger = XBLogFactory.getLogger(Locale.class);
 
     static final int ROOT = Cur.ROOT;
@@ -75,8 +74,7 @@
         "frag");
     static final QName _xmlFragment = new QName("xml-fragment");
 
-    private Locale(SchemaTypeLoader stl, XmlOptions options)
-    {
+    private Locale(SchemaTypeLoader stl, XmlOptions options) {
         options = XmlOptions.maskNull(options);
 
         //
@@ -88,7 +86,7 @@
         // Also - have a thread local setting for thread safety?  .. Perhaps something
         // in the type loader which defines whether ot not sync is on????
 
-        _noSync = options.hasOption(XmlOptions.UNSYNCHRONIZED);
+        _noSync = options.isUnsynchronized();
 
         _tempFrames = new Cur[_numTempFramesLeft = 8];
 
@@ -105,7 +103,7 @@
 
         _schemaTypeLoader = stl;
 
-        _validateOnSet = options.hasOption(XmlOptions.VALIDATE_ON_SET);
+        _validateOnSet = options.isValidateOnSet();
 
         //
         // Check for Saaj implementation request
@@ -113,11 +111,11 @@
 
         Object saajObj = options.get(Saaj.SAAJ_IMPL);
 
-        if (saajObj != null)
-        {
-            if (!(saajObj instanceof Saaj))
+        if (saajObj != null) {
+            if (!(saajObj instanceof Saaj)) {
                 throw new IllegalStateException(
                     "Saaj impl not correct type: " + saajObj);
+            }
 
             _saaj = (Saaj) saajObj;
 
@@ -133,49 +131,52 @@
     /**
      * This option is checked in XmlObjectBase._copy(XmlOptions), the locale is used as the synchronization domain.
      * useNewLocale = true: copy will use a new locale, false: copy will use the same locale as the source
-     * @deprecated Replace usages with CopyUseNewSynchronizationDomain option
+     *
      * @see org.apache.xmlbeans.XmlOptions#setCopyUseNewSynchronizationDomain(boolean)
+     * @deprecated Replace usages with CopyUseNewSynchronizationDomain option
      */
-    public static final String COPY_USE_NEW_LOCALE             = "COPY_USE_NEW_LOCALE";
+    public static final String COPY_USE_NEW_LOCALE = "COPY_USE_NEW_LOCALE";
 
-    static Locale getLocale(SchemaTypeLoader stl, XmlOptions options)
-    {
-        if (stl == null)
+    static Locale getLocale(SchemaTypeLoader stl, XmlOptions options) {
+        if (stl == null) {
             stl = XmlBeans.getContextTypeLoader();
+        }
 
         options = XmlOptions.maskNull(options);
 
         Locale l = null;
 
-        if (options.hasOption(USE_SAME_LOCALE))
-        {
+        if (options.hasOption(USE_SAME_LOCALE)) {
             Object source = options.get(USE_SAME_LOCALE);
 
-            if (source instanceof Locale)
+            if (source instanceof Locale) {
                 l = (Locale) source;
-            else if (source instanceof XmlTokenSource)
+            } else if (source instanceof XmlTokenSource) {
                 l = (Locale) ((XmlTokenSource) source).monitor();
-            else
+            } else {
                 throw new IllegalArgumentException(
                     "Source locale not understood: " + source);
+            }
 
-            if (l._schemaTypeLoader != stl)
+            if (l._schemaTypeLoader != stl) {
                 throw new IllegalArgumentException(
                     "Source locale does not support same schema type loader");
+            }
 
-            if (l._saaj != null && l._saaj != options.get(Saaj.SAAJ_IMPL))
+            if (l._saaj != null && l._saaj != options.get(Saaj.SAAJ_IMPL)) {
                 throw new IllegalArgumentException(
                     "Source locale does not support same saaj");
+            }
 
-            if (l._validateOnSet &&
-                !options.hasOption(XmlOptions.VALIDATE_ON_SET))
+            if (l._validateOnSet && !options.isValidateOnSet()) {
                 throw new IllegalArgumentException(
                     "Source locale does not support same validate on set");
+            }
 
             // TODO - other things to check?
-        }
-        else
+        } else {
             l = new Locale(stl, options);
+        }
 
         return l;
     }
@@ -184,13 +185,12 @@
     //
     //
 
-    static void associateSourceName(Cur c, XmlOptions options)
-    {
-        String sourceName = (String) XmlOptions.safeGet(options,
-            XmlOptions.DOCUMENT_SOURCE_NAME);
+    static void associateSourceName(Cur c, XmlOptions options) {
+        String sourceName = options == null ? null : options.getDocumentSourceName();
 
-        if (sourceName != null)
+        if (sourceName != null) {
             getDocProps(c, true).setSourceName(sourceName);
+        }
     }
 
     //
@@ -198,20 +198,17 @@
     //
 
     static void autoTypeDocument(Cur c, SchemaType requestedType,
-        XmlOptions options)
-        throws XmlException
-    {
+                                 XmlOptions options)
+        throws XmlException {
         assert c.isRoot();
 
         // The type in the options overrides all sniffing
 
         options = XmlOptions.maskNull(options);
 
-        SchemaType optionType = (SchemaType) options.get(
-            XmlOptions.DOCUMENT_TYPE);
+        SchemaType optionType = options.getDocumentType();
 
-        if (optionType != null)
-        {
+        if (optionType != null) {
             c.setType(optionType);
             return;
         }
@@ -221,24 +218,23 @@
         // An xsi:type can be used to pick a type out of the loader, or used to refine
         // a type with a name.
 
-        if (requestedType == null || requestedType.getName() != null)
-        {
+        if (requestedType == null || requestedType.getName() != null) {
             QName xsiTypeName = c.getXsiTypeName();
 
             SchemaType xsiSchemaType =
                 xsiTypeName == null ?
-                null : c._locale._schemaTypeLoader.findType(xsiTypeName);
+                    null : c._locale._schemaTypeLoader.findType(xsiTypeName);
 
             if (requestedType == null ||
-                requestedType.isAssignableFrom(xsiSchemaType))
+                requestedType.isAssignableFrom(xsiSchemaType)) {
                 type = xsiSchemaType;
+            }
         }
 
         // Look for a document element to establish type
 
         if (type == null &&
-            (requestedType == null || requestedType.isDocumentType()))
-        {
+            (requestedType == null || requestedType.isDocumentType())) {
             assert c.isRoot();
 
             c.push();
@@ -246,86 +242,85 @@
             QName docElemName =
                 !c.hasAttrs() && Locale.toFirstChildElement(c) &&
                 !Locale.toNextSiblingElement(c)
-                ? c.getName() : null;
+                    ? c.getName() : null;
 
             c.pop();
 
-            if (docElemName != null)
-            {
+            if (docElemName != null) {
                 type =
                     c._locale._schemaTypeLoader.findDocumentType(docElemName);
 
-                if (type != null && requestedType != null)
-                {
+                if (type != null && requestedType != null) {
                     QName requesteddocElemNameName = requestedType.getDocumentElementName();
 
                     if (!requesteddocElemNameName.equals(docElemName) &&
-                        !requestedType.isValidSubstitution(docElemName))
-                    {
+                        !requestedType.isValidSubstitution(docElemName)) {
                         throw
                             new XmlException("Element " +
-                            QNameHelper.pretty(docElemName) +
-                            " is not a valid " +
-                            QNameHelper.pretty(requesteddocElemNameName) +
-                            " document or a valid substitution.");
+                                             QNameHelper.pretty(docElemName) +
+                                             " is not a valid " +
+                                             QNameHelper.pretty(requesteddocElemNameName) +
+                                             " document or a valid substitution.");
                     }
                 }
             }
         }
 
-        if (type == null && requestedType == null)
-        {
+        if (type == null && requestedType == null) {
             c.push();
 
             type =
                 Locale.toFirstNormalAttr(c) && !Locale.toNextNormalAttr(c)
-                ?
-                c._locale._schemaTypeLoader.findAttributeType(c.getName()) :
-                null;
+                    ?
+                    c._locale._schemaTypeLoader.findAttributeType(c.getName()) :
+                    null;
 
             c.pop();
         }
 
-        if (type == null)
+        if (type == null) {
             type = requestedType;
+        }
 
-        if (type == null)
+        if (type == null) {
             type = XmlBeans.NO_TYPE;
+        }
 
         c.setType(type);
 
-        if (requestedType != null)
-        {
-            if (type.isDocumentType())
+        if (requestedType != null) {
+            if (type.isDocumentType()) {
                 verifyDocumentType(c, type.getDocumentElementName());
-            else if (type.isAttributeType())
+            } else if (type.isAttributeType()) {
                 verifyAttributeType(c, type.getAttributeTypeAttributeName());
+            }
         }
     }
 
-    private static boolean namespacesSame(QName n1, QName n2)
-    {
-        if (n1 == n2)
+    private static boolean namespacesSame(QName n1, QName n2) {
+        if (n1 == n2) {
             return true;
+        }
 
-        if (n1 == null || n2 == null)
+        if (n1 == null || n2 == null) {
             return false;
+        }
 
-        if (n1.getNamespaceURI() == n2.getNamespaceURI())
+        if (n1.getNamespaceURI() == n2.getNamespaceURI()) {
             return true;
+        }
 
-        if (n1.getNamespaceURI() == null || n2.getNamespaceURI() == null)
+        if (n1.getNamespaceURI() == null || n2.getNamespaceURI() == null) {
             return false;
+        }
 
         return n1.getNamespaceURI().equals(n2.getNamespaceURI());
     }
 
-    private static void addNamespace(StringBuffer sb, QName name)
-    {
-        if (name.getNamespaceURI() == null)
+    private static void addNamespace(StringBuffer sb, QName name) {
+        if (name.getNamespaceURI() == null) {
             sb.append("<no namespace>");
-        else
-        {
+        } else {
             sb.append("\"");
             sb.append(name.getNamespaceURI());
             sb.append("\"");
@@ -333,54 +328,43 @@
     }
 
     private static void verifyDocumentType(Cur c, QName docElemName)
-        throws XmlException
-    {
+        throws XmlException {
         assert c.isRoot();
 
         c.push();
 
-        try
-        {
+        try {
             StringBuffer sb = null;
 
             if (!Locale.toFirstChildElement(c) ||
-                Locale.toNextSiblingElement(c))
-            {
+                Locale.toNextSiblingElement(c)) {
                 sb = new StringBuffer();
 
                 sb.append("The document is not a ");
                 sb.append(QNameHelper.pretty(docElemName));
                 sb.append(
                     c.isRoot() ?
-                    ": no document element" : ": multiple document elements");
-            }
-            else
-            {
+                        ": no document element" : ": multiple document elements");
+            } else {
                 QName name = c.getName();
 
-                if (!name.equals(docElemName))
-                {
+                if (!name.equals(docElemName)) {
                     sb = new StringBuffer();
 
                     sb.append("The document is not a ");
                     sb.append(QNameHelper.pretty(docElemName));
 
-                    if (docElemName.getLocalPart().equals(name.getLocalPart()))
-                    {
+                    if (docElemName.getLocalPart().equals(name.getLocalPart())) {
                         sb.append(": document element namespace mismatch ");
                         sb.append("expected ");
                         addNamespace(sb, docElemName);
                         sb.append(" got ");
                         addNamespace(sb, name);
-                    }
-                    else if (namespacesSame(docElemName, name))
-                    {
+                    } else if (namespacesSame(docElemName, name)) {
                         sb.append(": document element local name mismatch ");
                         sb.append("expected " + docElemName.getLocalPart());
                         sb.append(" got " + name.getLocalPart());
-                    }
-                    else
-                    {
+                    } else {
                         sb.append(": document element mismatch ");
                         sb.append("got ");
                         sb.append(QNameHelper.pretty(name));
@@ -388,66 +372,52 @@
                 }
             }
 
-            if (sb != null)
-            {
+            if (sb != null) {
                 XmlError err = XmlError.forCursor(sb.toString(),
                     new Cursor(c));
                 throw new XmlException(err.toString(), null, err);
             }
-        }
-        finally
-        {
+        } finally {
             c.pop();
         }
     }
 
     private static void verifyAttributeType(Cur c, QName attrName)
-        throws XmlException
-    {
+        throws XmlException {
         assert c.isRoot();
 
         c.push();
 
-        try
-        {
+        try {
             StringBuffer sb = null;
 
-            if (!Locale.toFirstNormalAttr(c) || Locale.toNextNormalAttr(c))
-            {
+            if (!Locale.toFirstNormalAttr(c) || Locale.toNextNormalAttr(c)) {
                 sb = new StringBuffer();
 
                 sb.append("The document is not a ");
                 sb.append(QNameHelper.pretty(attrName));
                 sb.append(
                     c.isRoot() ? ": no attributes" : ": multiple attributes");
-            }
-            else
-            {
+            } else {
                 QName name = c.getName();
 
-                if (!name.equals(attrName))
-                {
+                if (!name.equals(attrName)) {
                     sb = new StringBuffer();
 
                     sb.append("The document is not a ");
                     sb.append(QNameHelper.pretty(attrName));
 
-                    if (attrName.getLocalPart().equals(name.getLocalPart()))
-                    {
+                    if (attrName.getLocalPart().equals(name.getLocalPart())) {
                         sb.append(": attribute namespace mismatch ");
                         sb.append("expected ");
                         addNamespace(sb, attrName);
                         sb.append(" got ");
                         addNamespace(sb, name);
-                    }
-                    else if (namespacesSame(attrName, name))
-                    {
+                    } else if (namespacesSame(attrName, name)) {
                         sb.append(": attribute local name mismatch ");
                         sb.append("expected " + attrName.getLocalPart());
                         sb.append(" got " + name.getLocalPart());
-                    }
-                    else
-                    {
+                    } else {
                         sb.append(": attribute element mismatch ");
                         sb.append("got ");
                         sb.append(QNameHelper.pretty(name));
@@ -455,27 +425,22 @@
                 }
             }
 
-            if (sb != null)
-            {
+            if (sb != null) {
                 XmlError err = XmlError.forCursor(sb.toString(),
                     new Cursor(c));
                 throw new XmlException(err.toString(), null, err);
             }
-        }
-        finally
-        {
+        } finally {
             c.pop();
         }
     }
 
-    static boolean isFragmentQName(QName name)
-    {
+    static boolean isFragmentQName(QName name) {
         return name.equals(Locale._openuriFragment) ||
-            name.equals(Locale._xmlFragment);
+               name.equals(Locale._xmlFragment);
     }
 
-    static boolean isFragment(Cur start, Cur end)
-    {
+    static boolean isFragment(Cur start, Cur end) {
         assert !end.isAttr();
 
         start.push();
@@ -484,21 +449,19 @@
         int numDocElems = 0;
         boolean isFrag = false;
 
-        while (!start.isSamePos(end))
-        {
+        while (!start.isSamePos(end)) {
             int k = start.kind();
 
-            if (k == ATTR)
+            if (k == ATTR) {
                 break;
+            }
 
-            if (k == TEXT && !isWhiteSpace(start.getCharsAsString()))
-            {
+            if (k == TEXT && !isWhiteSpace(start.getCharsAsString())) {
                 isFrag = true;
                 break;
             }
 
-            if (k == ELEM && ++numDocElems > 1)
-            {
+            if (k == ELEM && ++numDocElems > 1) {
                 isFrag = true;
                 break;
             }
@@ -507,8 +470,9 @@
 
             assert k != ATTR;
 
-            if (k != TEXT)
+            if (k != TEXT) {
                 start.toEnd();
+            }
 
             start.next();
         }
@@ -524,52 +488,44 @@
     //
 
     public static XmlObject newInstance(SchemaTypeLoader stl, SchemaType type,
-        XmlOptions options)
-    {
+                                        XmlOptions options) {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.newInstance(type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.newInstance(type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
-    private XmlObject newInstance(SchemaType type, XmlOptions options)
-    {
+    private XmlObject newInstance(SchemaType type, XmlOptions options) {
         options = XmlOptions.maskNull(options);
 
         Cur c = tempCur();
 
 
-        SchemaType sType = (SchemaType) options.get(XmlOptions.DOCUMENT_TYPE);
+        SchemaType sType = options.getDocumentType();
 
-        if (sType == null)
+        if (sType == null) {
             sType = type == null ? XmlObject.type : type;
-        if (sType.isDocumentType())
+        }
+        if (sType.isDocumentType()) {
             c.createDomDocumentRoot();
-        else
-             c.createRoot();
+        } else {
+            c.createRoot();
+        }
         c.setType(sType);
 
         XmlObject x = (XmlObject) c.getUser();
@@ -584,8 +540,7 @@
     //
 
     public static DOMImplementation newDomImplementation(SchemaTypeLoader stl,
-        XmlOptions options)
-    {
+                                                         XmlOptions options) {
         return (DOMImplementation) getLocale(stl, options);
     }
 
@@ -594,42 +549,32 @@
     //
 
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-        String xmlText, SchemaType type, XmlOptions options)
-        throws XmlException
-    {
+                                             String xmlText, SchemaType type, XmlOptions options)
+        throws XmlException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(xmlText, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(xmlText, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     private XmlObject parseToXmlObject(String xmlText, SchemaType type,
-        XmlOptions options)
-        throws XmlException
-    {
+                                       XmlOptions options)
+        throws XmlException {
         Cur c = parse(xmlText, type, options);
 
         XmlObject x = (XmlObject) c.getUser();
@@ -640,33 +585,24 @@
     }
 
     Cur parse(String s, SchemaType type, XmlOptions options)
-        throws XmlException
-    {
+        throws XmlException {
         Reader r = new StringReader(s);
 
-        try
-        {
+        try {
             Cur c = getSaxLoader(options).load(this, new InputSource(r),
                 options);
 
             autoTypeDocument(c, type, options);
 
             return c;
-        }
-        catch (IOException e)
-        {
-            assert false: "StringReader should not throw IOException";
+        } catch (IOException e) {
+            assert false : "StringReader should not throw IOException";
 
             throw new XmlException(e.getMessage(), e);
-        }
-        finally
-        {
-            try
-            {
+        } finally {
+            try {
                 r.close();
-            }
-            catch (IOException e)
-            {
+            } catch (IOException e) {
             }
         }
     }
@@ -679,53 +615,40 @@
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-        XMLInputStream xis, SchemaType type, XmlOptions options)
-        throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException
-    {
+                                             XMLInputStream xis, SchemaType type, XmlOptions options)
+        throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(xis, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(xis, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     /**
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     public XmlObject parseToXmlObject(XMLInputStream xis, SchemaType type,
-        XmlOptions options)
-        throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException
-    {
+                                      XmlOptions options)
+        throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {
         Cur c;
 
-        try
-        {
+        try {
             c = loadXMLInputStream(xis, options);
-        }
-        catch (org.apache.xmlbeans.xml.stream.XMLStreamException e)
-        {
+        } catch (org.apache.xmlbeans.xml.stream.XMLStreamException e) {
             throw new XmlException(e.getMessage(), e);
         }
 
@@ -743,50 +666,37 @@
     //
 
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-        XMLStreamReader xsr, SchemaType type, XmlOptions options)
-        throws XmlException
-    {
+                                             XMLStreamReader xsr, SchemaType type, XmlOptions options)
+        throws XmlException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(xsr, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(xsr, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     public XmlObject parseToXmlObject(XMLStreamReader xsr, SchemaType type,
-        XmlOptions options)
-        throws XmlException
-    {
+                                      XmlOptions options)
+        throws XmlException {
         Cur c;
 
-        try
-        {
+        try {
             c = loadXMLStreamReader(xsr, options);
-        }
-        catch (XMLStreamException e)
-        {
+        } catch (XMLStreamException e) {
             throw new XmlException(e.getMessage(), e);
         }
 
@@ -799,31 +709,27 @@
         return x;
     }
 
-    private static void lineNumber(XMLEvent xe, LoadContext context)
-    {
+    private static void lineNumber(XMLEvent xe, LoadContext context) {
         org.apache.xmlbeans.xml.stream.Location loc = xe.getLocation();
 
-        if (loc != null)
+        if (loc != null) {
             context.lineNumber(loc.getLineNumber(), loc.getColumnNumber(), -1);
+        }
     }
 
-    private static void lineNumber(XMLStreamReader xsr, LoadContext context)
-    {
+    private static void lineNumber(XMLStreamReader xsr, LoadContext context) {
         javax.xml.stream.Location loc = xsr.getLocation();
 
-        if (loc != null)
-        {
+        if (loc != null) {
             context.lineNumber(loc.getLineNumber(), loc.getColumnNumber(),
                 loc.getCharacterOffset());
         }
     }
 
-    private void doAttributes(XMLStreamReader xsr, LoadContext context)
-    {
+    private void doAttributes(XMLStreamReader xsr, LoadContext context) {
         int n = xsr.getAttributeCount();
 
-        for (int a = 0; a < n; a++)
-        {
+        for (int a = 0; a < n; a++) {
             context.attr(xsr.getAttributeLocalName(a),
                 xsr.getAttributeNamespace(a),
                 xsr.getAttributePrefix(a),
@@ -831,20 +737,19 @@
         }
     }
 
-    private void doNamespaces(XMLStreamReader xsr, LoadContext context)
-    {
+    private void doNamespaces(XMLStreamReader xsr, LoadContext context) {
         int n = xsr.getNamespaceCount();
 
-        for (int a = 0; a < n; a++)
-        {
+        for (int a = 0; a < n; a++) {
             String prefix = xsr.getNamespacePrefix(a);
 
-            if (prefix == null || prefix.length() == 0)
+            if (prefix == null || prefix.length() == 0) {
                 context.attr("xmlns", _xmlnsUri, null,
                     xsr.getNamespaceURI(a));
-            else
+            } else {
                 context.attr(prefix, _xmlnsUri, "xmlns",
                     xsr.getNamespaceURI(a));
+            }
         }
 
     }
@@ -853,27 +758,23 @@
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
     private Cur loadXMLInputStream(XMLInputStream xis, XmlOptions options)
-        throws org.apache.xmlbeans.xml.stream.XMLStreamException
-    {
+        throws org.apache.xmlbeans.xml.stream.XMLStreamException {
         options = XmlOptions.maskNull(options);
 
-        boolean lineNums = options.hasOption(XmlOptions.LOAD_LINE_NUMBERS);
+        boolean lineNums = options.isLoadLineNumbers();
 
         XMLEvent x = xis.peek();
 
-        if (x != null && x.getType() == XMLEvent.START_ELEMENT)
-        {
-            Map nsMap = ((StartElement) x).getNamespaceMap();
+        if (x != null && x.getType() == XMLEvent.START_ELEMENT) {
+            Map<String, String> nsMap = ((StartElement) x).getNamespaceMap();
 
-            if (nsMap != null && nsMap.size() > 0)
-            {
-                Map namespaces = new HashMap();
+            if (nsMap != null && nsMap.size() > 0) {
 
-                namespaces.putAll(nsMap);
+                Map<String, String> namespaces = new HashMap<>(nsMap);
 
                 options = new XmlOptions(options);
 
-                options.put(XmlOptions.LOAD_ADDITIONAL_NAMESPACES, namespaces);
+                options.setLoadAdditionalNamespaces(namespaces);
             }
         }
 
@@ -885,128 +786,132 @@
         LoadContext context = new Cur.CurLoadContext(this, options);
 
         events:
-        for (XMLEvent xe = xis.next(); xe != null; xe = xis.next())
-        {
-            switch (xe.getType())
-            {
-            case XMLEvent.START_DOCUMENT:
-                StartDocument doc = (StartDocument) xe;
+        for (XMLEvent xe = xis.next(); xe != null; xe = xis.next()) {
+            switch (xe.getType()) {
+                case XMLEvent.START_DOCUMENT:
+                    StartDocument doc = (StartDocument) xe;
 
-                systemId = doc.getSystemId();
-                encoding = doc.getCharacterEncodingScheme();
-                version = doc.getVersion();
-                standAlone = doc.isStandalone();
-                standAlone = doc.isStandalone();
+                    systemId = doc.getSystemId();
+                    encoding = doc.getCharacterEncodingScheme();
+                    version = doc.getVersion();
+                    standAlone = doc.isStandalone();
+                    standAlone = doc.isStandalone();
 
-                if (lineNums)
-                    lineNumber(xe, context);
+                    if (lineNums) {
+                        lineNumber(xe, context);
+                    }
 
-                break;
-
-            case XMLEvent.END_DOCUMENT:
-                if (lineNums)
-                    lineNumber(xe, context);
-
-                break events;
-
-            case XMLEvent.NULL_ELEMENT:
-                if (!xis.hasNext())
-                    break events;
-                break;
-
-            case XMLEvent.START_ELEMENT:
-                context.startElement(XMLNameHelper.getQName(xe.getName()));
-
-                if (lineNums)
-                    lineNumber(xe, context);
-
-                for (AttributeIterator ai = ((StartElement) xe).getAttributes();
-                     ai.hasNext();)
-                {
-                    Attribute attr = ai.next();
-
-                    context.attr(XMLNameHelper.getQName(attr.getName()),
-                        attr.getValue());
-                }
-
-                for (AttributeIterator ai = ((StartElement) xe).getNamespaces()
-                    ; ai.hasNext();)
-                {
-                    Attribute attr = ai.next();
-
-                    XMLName name = attr.getName();
-                    String local = name.getLocalName();
-
-                    if (name.getPrefix() == null && local.equals("xmlns"))
-                        local = "";
-
-                    context.xmlns(local, attr.getValue());
-                }
-
-                break;
-
-            case XMLEvent.END_ELEMENT:
-                context.endElement();
-
-                if (lineNums)
-                    lineNumber(xe, context);
-
-                break;
-
-            case XMLEvent.SPACE:
-                if (((Space) xe).ignorable())
                     break;
 
-                // Fall through
-
-            case XMLEvent.CHARACTER_DATA:
-                CharacterData cd = (CharacterData) xe;
-
-                if (cd.hasContent())
-                {
-                    context.text(cd.getContent());
-
-                    if (lineNums)
+                case XMLEvent.END_DOCUMENT:
+                    if (lineNums) {
                         lineNumber(xe, context);
-                }
+                    }
 
-                break;
+                    break events;
 
-            case XMLEvent.COMMENT:
-                org.apache.xmlbeans.xml.stream.Comment comment =
-                    (org.apache.xmlbeans.xml.stream.Comment) xe;
+                case XMLEvent.NULL_ELEMENT:
+                    if (!xis.hasNext()) {
+                        break events;
+                    }
+                    break;
 
-                if (comment.hasContent())
-                {
-                    context.comment(comment.getContent());
+                case XMLEvent.START_ELEMENT:
+                    context.startElement(XMLNameHelper.getQName(xe.getName()));
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xe, context);
-                }
+                    }
 
-                break;
+                    for (AttributeIterator ai = ((StartElement) xe).getAttributes();
+                         ai.hasNext(); ) {
+                        Attribute attr = ai.next();
 
-            case XMLEvent.PROCESSING_INSTRUCTION:
-                ProcessingInstruction procInstr = (ProcessingInstruction) xe;
+                        context.attr(XMLNameHelper.getQName(attr.getName()),
+                            attr.getValue());
+                    }
 
-                context.procInst(procInstr.getTarget(), procInstr.getData());
+                    for (AttributeIterator ai = ((StartElement) xe).getNamespaces()
+                         ; ai.hasNext(); ) {
+                        Attribute attr = ai.next();
 
-                if (lineNums)
-                    lineNumber(xe, context);
+                        XMLName name = attr.getName();
+                        String local = name.getLocalName();
 
-                break;
+                        if (name.getPrefix() == null && local.equals("xmlns")) {
+                            local = "";
+                        }
+
+                        context.xmlns(local, attr.getValue());
+                    }
+
+                    break;
+
+                case XMLEvent.END_ELEMENT:
+                    context.endElement();
+
+                    if (lineNums) {
+                        lineNumber(xe, context);
+                    }
+
+                    break;
+
+                case XMLEvent.SPACE:
+                    if (((Space) xe).ignorable()) {
+                        break;
+                    }
+
+                    // Fall through
+
+                case XMLEvent.CHARACTER_DATA:
+                    CharacterData cd = (CharacterData) xe;
+
+                    if (cd.hasContent()) {
+                        context.text(cd.getContent());
+
+                        if (lineNums) {
+                            lineNumber(xe, context);
+                        }
+                    }
+
+                    break;
+
+                case XMLEvent.COMMENT:
+                    org.apache.xmlbeans.xml.stream.Comment comment =
+                        (org.apache.xmlbeans.xml.stream.Comment) xe;
+
+                    if (comment.hasContent()) {
+                        context.comment(comment.getContent());
+
+                        if (lineNums) {
+                            lineNumber(xe, context);
+                        }
+                    }
+
+                    break;
+
+                case XMLEvent.PROCESSING_INSTRUCTION:
+                    ProcessingInstruction procInstr = (ProcessingInstruction) xe;
+
+                    context.procInst(procInstr.getTarget(), procInstr.getData());
+
+                    if (lineNums) {
+                        lineNumber(xe, context);
+                    }
+
+                    break;
 
                 // These are ignored
-            case XMLEvent.ENTITY_REFERENCE:
-            case XMLEvent.START_PREFIX_MAPPING:
-            case XMLEvent.END_PREFIX_MAPPING:
-            case XMLEvent.CHANGE_PREFIX_MAPPING:
-            case XMLEvent.XML_EVENT:
-                break;
+                case XMLEvent.ENTITY_REFERENCE:
+                case XMLEvent.START_PREFIX_MAPPING:
+                case XMLEvent.END_PREFIX_MAPPING:
+                case XMLEvent.CHANGE_PREFIX_MAPPING:
+                case XMLEvent.XML_EVENT:
+                    break;
 
-            default :
-                throw new RuntimeException(
-                    "Unhandled xml event type: " + xe.getTypeAsString());
+                default:
+                    throw new RuntimeException(
+                        "Unhandled xml event type: " + xe.getTypeAsString());
             }
         }
 
@@ -1025,11 +930,10 @@
     }
 
     private Cur loadXMLStreamReader(XMLStreamReader xsr, XmlOptions options)
-        throws XMLStreamException
-    {
+        throws XMLStreamException {
         options = XmlOptions.maskNull(options);
 
-        boolean lineNums = options.hasOption(XmlOptions.LOAD_LINE_NUMBERS);
+        boolean lineNums = options.isLoadLineNumbers();
 
         String encoding = null, version = null;
         boolean standAlone = false;
@@ -1038,41 +942,39 @@
         int depth = 0;
 
         events:
-        for (int eventType = xsr.getEventType(); ; eventType = xsr.next())
-        {
-            switch (eventType)
-            {
-            case XMLStreamReader.START_DOCUMENT:
-                {
+        for (int eventType = xsr.getEventType(); ; eventType = xsr.next()) {
+            switch (eventType) {
+                case XMLStreamReader.START_DOCUMENT: {
                     depth++;
 
                     encoding = xsr.getCharacterEncodingScheme();
                     version = xsr.getVersion();
                     standAlone = xsr.isStandalone();
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break;
                 }
 
-            case XMLStreamReader.END_DOCUMENT:
-                {
+                case XMLStreamReader.END_DOCUMENT: {
                     depth--;
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break events;
                 }
 
-            case XMLStreamReader.START_ELEMENT:
-                {
+                case XMLStreamReader.START_ELEMENT: {
                     depth++;
                     context.startElement(xsr.getName());
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     doAttributes(xsr, context);
                     doNamespaces(xsr, context);
@@ -1080,80 +982,78 @@
                     break;
                 }
 
-            case XMLStreamReader.END_ELEMENT:
-                {
+                case XMLStreamReader.END_ELEMENT: {
                     depth--;
                     context.endElement();
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break;
                 }
 
-            case XMLStreamReader.CHARACTERS:
-            case XMLStreamReader.CDATA:
-                {
+                case XMLStreamReader.CHARACTERS:
+                case XMLStreamReader.CDATA: {
                     context.text(xsr.getTextCharacters(), xsr.getTextStart(),
                         xsr.getTextLength());
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break;
                 }
 
-            case XMLStreamReader.COMMENT:
-                {
+                case XMLStreamReader.COMMENT: {
                     String comment = xsr.getText();
 
                     context.comment(comment);
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break;
                 }
 
-            case XMLStreamReader.PROCESSING_INSTRUCTION:
-                {
+                case XMLStreamReader.PROCESSING_INSTRUCTION: {
                     context.procInst(xsr.getPITarget(), xsr.getPIData());
 
-                    if (lineNums)
+                    if (lineNums) {
                         lineNumber(xsr, context);
+                    }
 
                     break;
                 }
 
-            case XMLStreamReader.ATTRIBUTE:
-                {
+                case XMLStreamReader.ATTRIBUTE: {
                     doAttributes(xsr, context);
                     break;
                 }
 
-            case XMLStreamReader.NAMESPACE:
-                {
+                case XMLStreamReader.NAMESPACE: {
                     doNamespaces(xsr, context);
                     break;
                 }
 
-            case XMLStreamReader.ENTITY_REFERENCE:
-                {
+                case XMLStreamReader.ENTITY_REFERENCE: {
                     context.text(xsr.getText());
                     break;
                 }
 
-            case XMLStreamReader.SPACE:
-            case XMLStreamReader.DTD:
-                break;
+                case XMLStreamReader.SPACE:
+                case XMLStreamReader.DTD:
+                    break;
 
-            default :
-                throw new RuntimeException(
-                    "Unhandled xml event type: " + eventType);
+                default:
+                    throw new RuntimeException(
+                        "Unhandled xml event type: " + eventType);
             }
 
-            if (!xsr.hasNext() || depth <= 0)
+            if (!xsr.hasNext() || depth <= 0) {
                 break;
+            }
         }
 
         Cur c = context.finish();
@@ -1174,42 +1074,32 @@
     //
 
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-        InputStream is, SchemaType type, XmlOptions options)
-        throws XmlException, IOException
-    {
+                                             InputStream is, SchemaType type, XmlOptions options)
+        throws XmlException, IOException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(is, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(is, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     private XmlObject parseToXmlObject(InputStream is, SchemaType type,
-        XmlOptions options)
-        throws XmlException, IOException
-    {
+                                       XmlOptions options)
+        throws XmlException, IOException {
         Cur c = getSaxLoader(options).load(this, new InputSource(is),
             options);
 
@@ -1227,42 +1117,32 @@
     //
 
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl,
-        Reader reader, SchemaType type, XmlOptions options)
-        throws XmlException, IOException
-    {
+                                             Reader reader, SchemaType type, XmlOptions options)
+        throws XmlException, IOException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(reader, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(reader, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     private XmlObject parseToXmlObject(Reader reader, SchemaType type,
-        XmlOptions options)
-        throws XmlException, IOException
-    {
+                                       XmlOptions options)
+        throws XmlException, IOException {
         Cur c = getSaxLoader(options).load(this, new InputSource(reader),
             options);
 
@@ -1280,42 +1160,32 @@
     //
 
     public static XmlObject parseToXmlObject(SchemaTypeLoader stl, Node node,
-        SchemaType type, XmlOptions options)
-        throws XmlException
-    {
+                                             SchemaType type, XmlOptions options)
+        throws XmlException {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.parseToXmlObject(node, type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.parseToXmlObject(node, type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
     public XmlObject parseToXmlObject(Node node, SchemaType type,
-        XmlOptions options)
-        throws XmlException
-    {
+                                      XmlOptions options)
+        throws XmlException {
         LoadContext context = new Cur.CurLoadContext(this, options);
 
         loadNode(node, context);
@@ -1333,49 +1203,44 @@
         return x;
     }
 
-    private void loadNodeChildren(Node n, LoadContext context)
-    {
-        for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling())
+    private void loadNodeChildren(Node n, LoadContext context) {
+        for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling()) {
             loadNode(c, context);
+        }
     }
 
-    void loadNode(Node n, LoadContext context)
-    {
-        switch (n.getNodeType())
-        {
-        case Node.DOCUMENT_NODE:
-        case Node.DOCUMENT_FRAGMENT_NODE:
-        case Node.ENTITY_REFERENCE_NODE:
-            {
+    void loadNode(Node n, LoadContext context) {
+        switch (n.getNodeType()) {
+            case Node.DOCUMENT_NODE:
+            case Node.DOCUMENT_FRAGMENT_NODE:
+            case Node.ENTITY_REFERENCE_NODE: {
                 loadNodeChildren(n, context);
 
                 break;
             }
-        case Node.ELEMENT_NODE:
-            {
+            case Node.ELEMENT_NODE: {
                 context.startElement(
                     makeQualifiedQName(n.getNamespaceURI(), n.getNodeName()));
 
                 NamedNodeMap attrs = n.getAttributes();
 
-                for (int i = 0; i < attrs.getLength(); i++)
-                {
+                for (int i = 0; i < attrs.getLength(); i++) {
                     Node a = attrs.item(i);
 
                     String attrName = a.getNodeName();
                     String attrValue = a.getNodeValue();
 
-                    if (attrName.toLowerCase().startsWith("xmlns"))
-                    {
-                        if (attrName.length() == 5)
+                    if (attrName.toLowerCase().startsWith("xmlns")) {
+                        if (attrName.length() == 5) {
                             context.xmlns(null, attrValue);
-                        else
+                        } else {
                             context.xmlns(attrName.substring(6), attrValue);
-                    }
-                    else
+                        }
+                    } else {
                         context.attr(
                             makeQualifiedQName(a.getNamespaceURI(), attrName),
                             attrValue);
+                    }
                 }
 
                 loadNodeChildren(n, context);
@@ -1384,34 +1249,29 @@
 
                 break;
             }
-        case Node.TEXT_NODE:
-        case Node.CDATA_SECTION_NODE:
-            {
+            case Node.TEXT_NODE:
+            case Node.CDATA_SECTION_NODE: {
                 context.text(n.getNodeValue());
                 break;
             }
-        case Node.COMMENT_NODE:
-            {
+            case Node.COMMENT_NODE: {
                 context.comment(n.getNodeValue());
                 break;
             }
-        case Node.PROCESSING_INSTRUCTION_NODE:
-            {
+            case Node.PROCESSING_INSTRUCTION_NODE: {
                 context.procInst(n.getNodeName(), n.getNodeValue());
                 break;
             }
-        case Node.DOCUMENT_TYPE_NODE:
-        case Node.ENTITY_NODE:
-        case Node.NOTATION_NODE:
-            {
+            case Node.DOCUMENT_TYPE_NODE:
+            case Node.ENTITY_NODE:
+            case Node.NOTATION_NODE: {
                 Node next = n.getNextSibling();
                 if (next != null) {
                     loadNode(next, context);
                 }
                 break;
             }
-        case Node.ATTRIBUTE_NODE:
-            {
+            case Node.ATTRIBUTE_NODE: {
                 throw new RuntimeException("Unexpected node");
             }
         }
@@ -1423,10 +1283,8 @@
 
     private class XmlSaxHandlerImpl
         extends SaxHandler
-        implements XmlSaxHandler
-    {
-        XmlSaxHandlerImpl(Locale l, SchemaType type, XmlOptions options)
-        {
+        implements XmlSaxHandler {
+        XmlSaxHandlerImpl(Locale l, SchemaType type, XmlOptions options) {
             super(null);
 
             _options = options;
@@ -1442,36 +1300,31 @@
             initSaxHandler(l, saxHandlerOptions);
         }
 
-        public ContentHandler getContentHandler()
-        {
+        public ContentHandler getContentHandler() {
             return _context == null ? null : this;
         }
 
-        public LexicalHandler getLexicalHandler()
-        {
+        public LexicalHandler getLexicalHandler() {
             return _context == null ? null : this;
         }
 
-        public void bookmarkLastEvent(XmlBookmark mark)
-        {
+        public void bookmarkLastEvent(XmlBookmark mark) {
             _context.bookmarkLastNonAttr(mark);
         }
 
-        public void bookmarkLastAttr(QName attrName, XmlBookmark mark)
-        {
+        public void bookmarkLastAttr(QName attrName, XmlBookmark mark) {
             _context.bookmarkLastAttr(attrName, mark);
         }
 
         public XmlObject getObject()
-            throws XmlException
-        {
-            if (_context == null)
+            throws XmlException {
+            if (_context == null) {
                 return null;
+            }
 
             _locale.enter();
 
-            try
-            {
+            try {
                 Cur c = _context.finish();
 
                 autoTypeDocument(c, _type, _options);
@@ -1483,9 +1336,7 @@
                 _context = null;
 
                 return x;
-            }
-            finally
-            {
+            } finally {
                 _locale.exit();
             }
         }
@@ -1495,39 +1346,29 @@
     }
 
     public static XmlSaxHandler newSaxHandler(SchemaTypeLoader stl,
-        SchemaType type, XmlOptions options)
-    {
+                                              SchemaType type, XmlOptions options) {
         Locale l = getLocale(stl, options);
 
-        if (l.noSync())
-        {
+        if (l.noSync()) {
             l.enter();
-            try
-            {
+            try {
                 return l.newSaxHandler(type, options);
-            }
-            finally
-            {
+            } finally {
                 l.exit();
             }
-        }
-        else
-            synchronized (l)
-            {
+        } else {
+            synchronized (l) {
                 l.enter();
-                try
-                {
+                try {
                     return l.newSaxHandler(type, options);
-                }
-                finally
-                {
+                } finally {
                     l.exit();
                 }
             }
+        }
     }
 
-    public XmlSaxHandler newSaxHandler(SchemaType type, XmlOptions options)
-    {
+    public XmlSaxHandler newSaxHandler(SchemaType type, XmlOptions options) {
         return new XmlSaxHandlerImpl(this, type, options);
     }
 
@@ -1535,28 +1376,25 @@
     // used by the parser.  This factory would probably come from my
     // high speed parser.  Otherwise, use a thread local on
 
-    QName makeQName(String uri, String localPart)
-    {
+    QName makeQName(String uri, String localPart) {
         assert localPart != null && localPart.length() > 0;
         // TODO - make sure name is a well formed name?
 
         return _qnameFactory.getQName(uri, localPart);
     }
 
-    QName makeQNameNoCheck(String uri, String localPart)
-    {
+    QName makeQNameNoCheck(String uri, String localPart) {
         return _qnameFactory.getQName(uri, localPart);
     }
 
-    QName makeQName(String uri, String local, String prefix)
-    {
+    QName makeQName(String uri, String local, String prefix) {
         return _qnameFactory.getQName(uri, local, prefix == null ? "" : prefix);
     }
 
-    QName makeQualifiedQName(String uri, String qname)
-    {
-        if (qname == null)
+    QName makeQualifiedQName(String uri, String qname) {
+        if (qname == null) {
             qname = "";
+        }
 
         int i = qname.indexOf(':');
 
@@ -1569,45 +1407,41 @@
     }
 
     static private class DocProps
-        extends XmlDocumentProperties
-    {
+        extends XmlDocumentProperties {
         private HashMap _map = new HashMap();
 
-        public Object put(Object key, Object value)
-        {
+        public Object put(Object key, Object value) {
             return _map.put(key, value);
         }
 
-        public Object get(Object key)
-        {
+        public Object get(Object key) {
             return _map.get(key);
         }
 
-        public Object remove(Object key)
-        {
+        public Object remove(Object key) {
             return _map.remove(key);
         }
     }
 
-    static XmlDocumentProperties getDocProps(Cur c, boolean ensure)
-    {
+    static XmlDocumentProperties getDocProps(Cur c, boolean ensure) {
         c.push();
 
-        while (c.toParent())
+        while (c.toParent()) {
             ;
+        }
 
         DocProps props = (DocProps) c.getBookmark(DocProps.class);
 
-        if (props == null && ensure)
+        if (props == null && ensure) {
             c.setBookmark(DocProps.class, props = new DocProps());
+        }
 
         c.pop();
 
         return props;
     }
 
-    interface ChangeListener
-    {
+    interface ChangeListener {
         void notifyChange();
 
         void setNextChangeListener(ChangeListener listener);
@@ -1615,29 +1449,27 @@
         ChangeListener getNextChangeListener();
     }
 
-    void registerForChange(ChangeListener listener)
-    {
-        if (listener.getNextChangeListener() == null)
-        {
-            if (_changeListeners == null)
+    void registerForChange(ChangeListener listener) {
+        if (listener.getNextChangeListener() == null) {
+            if (_changeListeners == null) {
                 listener.setNextChangeListener(listener);
-            else
+            } else {
                 listener.setNextChangeListener(_changeListeners);
+            }
 
             _changeListeners = listener;
         }
     }
 
-    void notifyChange()
-    {
+    void notifyChange() {
         // First, notify the registered listeners ...
 
-        while (_changeListeners != null)
-        {
+        while (_changeListeners != null) {
             _changeListeners.notifyChange();
 
-            if (_changeListeners.getNextChangeListener() == _changeListeners)
+            if (_changeListeners.getNextChangeListener() == _changeListeners) {
                 _changeListeners.setNextChangeListener(null);
+            }
 
             ChangeListener next = _changeListeners.getNextChangeListener();
 
@@ -1656,32 +1488,32 @@
     // Cursor helpers
     //
 
-    static String getTextValue(Cur c)
-    {
+    static String getTextValue(Cur c) {
         assert c.isNode();
 
-        if (!c.hasChildren())
+        if (!c.hasChildren()) {
             return c.getValueAsString();
+        }
 
         StringBuffer sb = new StringBuffer();
 
         c.push();
 
-        for (c.next(); !c.isAtEndOfLastPush(); c.next())
-            if (c.isText())
-            {
-                if ( (c._xobj.isComment() || c._xobj.isProcinst() ) && c._pos<c._xobj._cchValue )
+        for (c.next(); !c.isAtEndOfLastPush(); c.next()) {
+            if (c.isText()) {
+                if ((c._xobj.isComment() || c._xobj.isProcinst()) && c._pos < c._xobj._cchValue) {
                     continue;
+                }
                 CharUtil.getString(sb, c.getChars(-1), c._offSrc, c._cchSrc);
             }
+        }
 
         c.pop();
 
         return sb.toString();
     }
 
-    static int getTextValue(Cur c, int wsr, char[] chars, int off, int maxCch)
-    {
+    static int getTextValue(Cur c, int wsr, char[] chars, int off, int maxCch) {
         // TODO - hack impl for now ... improve
 
         assert c.isNode();
@@ -1690,46 +1522,48 @@
 
         int n = s.length();
 
-        if (n > maxCch)
+        if (n > maxCch) {
             n = maxCch;
+        }
 
-        if (n <= 0)
+        if (n <= 0) {
             return 0;
+        }
 
         s.getChars(0, n, chars, off);
 
         return n;
     }
 
-    static String applyWhiteSpaceRule(String s, int wsr)
-    {
+    static String applyWhiteSpaceRule(String s, int wsr) {
         int l = s == null ? 0 : s.length();
 
-        if (l == 0 || wsr == WS_PRESERVE)
+        if (l == 0 || wsr == WS_PRESERVE) {
             return s;
+        }
 
         char ch;
 
-        if (wsr == WS_REPLACE)
-        {
-            for (int i = 0; i < l; i++)
-                if ((ch = s.charAt(i)) == '\n' || ch == '\r' || ch == '\t')
+        if (wsr == WS_REPLACE) {
+            for (int i = 0; i < l; i++) {
+                if ((ch = s.charAt(i)) == '\n' || ch == '\r' || ch == '\t') {
                     return processWhiteSpaceRule(s, wsr);
-        }
-        else if (wsr == Locale.WS_COLLAPSE)
-        {
+                }
+            }
+        } else if (wsr == Locale.WS_COLLAPSE) {
             if (CharUtil.isWhiteSpace(s.charAt(0)) ||
-                CharUtil.isWhiteSpace(s.charAt(l - 1)))
+                CharUtil.isWhiteSpace(s.charAt(l - 1))) {
                 return processWhiteSpaceRule(s, wsr);
+            }
 
             boolean lastWasWhite = false;
 
-            for (int i = 1; i < l; i++)
-            {
+            for (int i = 1; i < l; i++) {
                 boolean isWhite = CharUtil.isWhiteSpace(s.charAt(i));
 
-                if (isWhite && lastWasWhite)
+                if (isWhite && lastWasWhite) {
                     return processWhiteSpaceRule(s, wsr);
+                }
 
                 lastWasWhite = isWhite;
             }
@@ -1738,8 +1572,7 @@
         return s;
     }
 
-    static String processWhiteSpaceRule(String s, int wsr)
-    {
+    static String processWhiteSpaceRule(String s, int wsr) {
         ScrubBuffer sb = getScrubBuffer(wsr);
 
         sb.scrub(s, 0, s.length());
@@ -1747,44 +1580,40 @@
         return sb.getResultAsString();
     }
 
-    static final class ScrubBuffer
-    {
-        ScrubBuffer()
-        {
+    static final class ScrubBuffer {
+        ScrubBuffer() {
             _sb = new StringBuffer();
         }
 
-        void init(int wsr)
-        {
+        void init(int wsr) {
             _sb.delete(0, _sb.length());
 
             _wsr = wsr;
             _state = START_STATE;
         }
 
-        void scrub(Object src, int off, int cch)
-        {
-            if (cch == 0)
+        void scrub(Object src, int off, int cch) {
+            if (cch == 0) {
                 return;
+            }
 
-            if (_wsr == Locale.WS_PRESERVE)
-            {
+            if (_wsr == Locale.WS_PRESERVE) {
                 CharUtil.getString(_sb, src, off, cch);
                 return;
             }
 
             char[] chars;
 
-            if (src instanceof char[])
+            if (src instanceof char[]) {
                 chars = (char[]) src;
-            else
-            {
-                if (cch <= _srcBuf.length)
+            } else {
+                if (cch <= _srcBuf.length) {
                     chars = _srcBuf;
-                else if (cch <= 16384)
+                } else if (cch <= 16384) {
                     chars = _srcBuf = new char[16384];
-                else
+                } else {
                     chars = new char[cch];
+                }
 
                 CharUtil.getChars(chars, 0, src, off, cch);
                 off = 0;
@@ -1792,25 +1621,23 @@
 
             int start = 0;
 
-            for (int i = 0; i < cch; i++)
-            {
+            for (int i = 0; i < cch; i++) {
                 char ch = chars[off + i];
 
-                if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')
-                {
+                if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') {
                     _sb.append(chars, off + start, i - start);
 
                     start = i + 1;
 
-                    if (_wsr == Locale.WS_REPLACE)
+                    if (_wsr == Locale.WS_REPLACE) {
                         _sb.append(' ');
-                    else if (_state == NOSPACE_STATE)
+                    } else if (_state == NOSPACE_STATE) {
                         _state = SPACE_SEEN_STATE;
-                }
-                else
-                {
-                    if (_state == SPACE_SEEN_STATE)
+                    }
+                } else {
+                    if (_state == SPACE_SEEN_STATE) {
                         _sb.append(' ');
+                    }
 
                     _state = NOSPACE_STATE;
                 }
@@ -1819,8 +1646,7 @@
             _sb.append(chars, off + start, cch - start);
         }
 
-        String getResultAsString()
-        {
+        String getResultAsString() {
             return _sb.toString();
         }
 
@@ -1837,10 +1663,8 @@
     }
 
     private static ThreadLocal tl_scrubBuffer =
-        new ThreadLocal()
-        {
-            protected Object initialValue()
-            {
+        new ThreadLocal() {
+            protected Object initialValue() {
                 return new SoftReference(new ScrubBuffer());
             }
         };
@@ -1849,12 +1673,10 @@
         tl_scrubBuffer.remove();
     }
 
-    static ScrubBuffer getScrubBuffer(int wsr)
-    {
+    static ScrubBuffer getScrubBuffer(int wsr) {
         SoftReference softRef = (SoftReference) tl_scrubBuffer.get();
         ScrubBuffer scrubBuffer = (ScrubBuffer) (softRef).get();
-        if (scrubBuffer == null)
-        {
+        if (scrubBuffer == null) {
             scrubBuffer = new ScrubBuffer();
             tl_scrubBuffer.set(new SoftReference(scrubBuffer));
         }
@@ -1863,42 +1685,35 @@
         return scrubBuffer;
     }
 
-    static boolean pushToContainer(Cur c)
-    {
+    static boolean pushToContainer(Cur c) {
         c.push();
 
-        for (; ;)
-        {
-            switch (c.kind())
-            {
-            case ROOT:
-            case ELEM:
-                return true;
-            case -ROOT:
-            case -ELEM:
-                c.pop();
-                return false;
-            case COMMENT:
-            case PROCINST:
-                c.skip();
-                break;
-            default                      :
-                c.nextWithAttrs();
-                break;
+        for (; ; ) {
+            switch (c.kind()) {
+                case ROOT:
+                case ELEM:
+                    return true;
+                case -ROOT:
+                case -ELEM:
+                    c.pop();
+                    return false;
+                case COMMENT:
+                case PROCINST:
+                    c.skip();
+                    break;
+                default:
+                    c.nextWithAttrs();
+                    break;
             }
         }
     }
 
-    static boolean toFirstNormalAttr(Cur c)
-    {
+    static boolean toFirstNormalAttr(Cur c) {
         c.push();
 
-        if (c.toFirstAttr())
-        {
-            do
-            {
-                if (!c.isXmlns())
-                {
+        if (c.toFirstAttr()) {
+            do {
+                if (!c.isXmlns()) {
                     c.popButStay();
                     return true;
                 }
@@ -1911,21 +1726,19 @@
         return false;
     }
 
-    static boolean toPrevNormalAttr(Cur c)
-    {
-        if (c.isAttr())
-        {
+    static boolean toPrevNormalAttr(Cur c) {
+        if (c.isAttr()) {
             c.push();
 
-            for (; ;)
-            {
+            for (; ; ) {
                 assert c.isAttr();
 
                 // See if I can move backward.  If I'm at the first attr, prev must return
                 // false and not move.
 
-                if (!c.prev())
+                if (!c.prev()) {
                     break;
+                }
 
                 // Skip past the text value or attr begin
 
@@ -1933,11 +1746,11 @@
 
                 // I might have skipped over text above
 
-                if (!c.isAttr())
+                if (!c.isAttr()) {
                     c.prev();
+                }
 
-                if (c.isNormalAttr())
-                {
+                if (c.isNormalAttr()) {
                     c.popButStay();
                     return true;
                 }
@@ -1949,14 +1762,11 @@
         return false;
     }
 
-    static boolean toNextNormalAttr(Cur c)
-    {
+    static boolean toNextNormalAttr(Cur c) {
         c.push();
 
-        while (c.toNextAttr())
-        {
-            if (!c.isXmlns())
-            {
+        while (c.toNextAttr()) {
+            if (!c.isXmlns()) {
                 c.popButStay();
                 return true;
             }
@@ -1967,26 +1777,25 @@
         return false;
     }
 
-    Xobj findNthChildElem(Xobj parent, QName name, QNameSet set, int n)
-    {
+    Xobj findNthChildElem(Xobj parent, QName name, QNameSet set, int n) {
         // only one of (set or name) is not null
         // or both are null for a wildcard
         assert (name == null || set == null);
         assert n >= 0;
 
-        if (parent == null)
+        if (parent == null) {
             return null;
+        }
 
         int da = _nthCache_A.distance(parent, name, set, n);
         int db = _nthCache_B.distance(parent, name, set, n);
 
         Xobj x =
             da <= db
-            ? _nthCache_A.fetch(parent, name, set, n)
-            : _nthCache_B.fetch(parent, name, set, n);
+                ? _nthCache_A.fetch(parent, name, set, n)
+                : _nthCache_B.fetch(parent, name, set, n);
 
-        if (da == db)
-        {
+        if (da == db) {
             nthCache temp = _nthCache_A;
             _nthCache_A = _nthCache_B;
             _nthCache_B = temp;
@@ -1995,38 +1804,32 @@
         return x;
     }
 
-    int count(Xobj parent, QName name, QNameSet set)
-    {
+    int count(Xobj parent, QName name, QNameSet set) {
         int n = 0;
 
         for (Xobj x = findNthChildElem(parent, name, set, 0);
-             x != null; x = x._nextSibling)
-        {
-            if (x.isElem())
-            {
-                if (set == null)
-                {
-                    if (x._name.equals(name))
+             x != null; x = x._nextSibling) {
+            if (x.isElem()) {
+                if (set == null) {
+                    if (x._name.equals(name)) {
                         n++;
-                }
-                else if (set.contains(x._name))
+                    }
+                } else if (set.contains(x._name)) {
                     n++;
+                }
             }
         }
 
         return n;
     }
 
-    static boolean toChild(Cur c, QName name, int n)
-    {
-        if (n >= 0 && pushToContainer(c))
-        {
+    static boolean toChild(Cur c, QName name, int n) {
+        if (n >= 0 && pushToContainer(c)) {
             Xobj x = c._locale.findNthChildElem(c._xobj, name, null, n);
 
             c.pop();
 
-            if (x != null)
-            {
+            if (x != null) {
                 c.moveTo(x);
                 return true;
             }
@@ -2035,8 +1838,7 @@
         return false;
     }
 
-    static boolean toFirstChildElement(Cur c)
-    {
+    static boolean toFirstChildElement(Cur c) {
 //        if (!pushToContainer(c))
 //            return false;
 //
@@ -2051,32 +1853,29 @@
 //        return true;
 
         Xobj originalXobj = c._xobj;
-        int  originalPos  = c._pos;
+        int originalPos = c._pos;
 
         loop:
-        for (; ;)
-        {
-            switch (c.kind())
-            {
-            case ROOT:
-            case ELEM:
-                break loop;
-            case -ROOT:
-            case -ELEM:
-                c.moveTo(originalXobj, originalPos);
-                return false;
-            case COMMENT:
-            case PROCINST:
-                c.skip();
-                break;
-            default:
-                c.nextWithAttrs();
-                break;
+        for (; ; ) {
+            switch (c.kind()) {
+                case ROOT:
+                case ELEM:
+                    break loop;
+                case -ROOT:
+                case -ELEM:
+                    c.moveTo(originalXobj, originalPos);
+                    return false;
+                case COMMENT:
+                case PROCINST:
+                    c.skip();
+                    break;
+                default:
+                    c.nextWithAttrs();
+                    break;
             }
         }
 
-        if (!c.toFirstChild() || (!c.isElem() && !toNextSiblingElement(c)))
-        {
+        if (!c.toFirstChild() || (!c.isElem() && !toNextSiblingElement(c))) {
             c.moveTo(originalXobj, originalPos);
             return false;
         }
@@ -2084,13 +1883,12 @@
         return true;
     }
 
-    static boolean toLastChildElement(Cur c)
-    {
-        if (!pushToContainer(c))
+    static boolean toLastChildElement(Cur c) {
+        if (!pushToContainer(c)) {
             return false;
+        }
 
-        if (!c.toLastChild() || (!c.isElem() && !toPrevSiblingElement(c)))
-        {
+        if (!c.toLastChild() || (!c.isElem() && !toPrevSiblingElement(c))) {
             c.pop();
             return false;
         }
@@ -2100,10 +1898,10 @@
         return true;
     }
 
-    static boolean toPrevSiblingElement(Cur cur)
-    {
-        if (!cur.hasParent())
+    static boolean toPrevSiblingElement(Cur cur) {
+        if (!cur.hasParent()) {
             return false;
+        }
 
         Cur c = cur.tempCur();
 
@@ -2111,20 +1909,19 @@
 
         int k = c.kind();
 
-        if (k != ATTR)
-        {
-            for (; ;)
-            {
-                if (!c.prev())
+        if (k != ATTR) {
+            for (; ; ) {
+                if (!c.prev()) {
                     break;
+                }
 
                 k = c.kind();
 
-                if (k == ROOT || k == ELEM)
+                if (k == ROOT || k == ELEM) {
                     break;
+                }
 
-                if (c.kind() == -ELEM)
-                {
+                if (c.kind() == -ELEM) {
                     c.toParent();
 
                     cur.moveToCur(c);
@@ -2140,33 +1937,31 @@
         return moved;
     }
 
-    static boolean toNextSiblingElement(Cur c)
-    {
-        if (!c.hasParent())
+    static boolean toNextSiblingElement(Cur c) {
+        if (!c.hasParent()) {
             return false;
+        }
 
         c.push();
 
         int k = c.kind();
 
-        if (k == ATTR)
-        {
+        if (k == ATTR) {
             c.toParent();
             c.next();
-        }
-        else if (k == ELEM)
+        } else if (k == ELEM) {
             c.skip();
+        }
 
-        while ((k = c.kind()) >= 0)
-        {
-            if (k == ELEM)
-            {
+        while ((k = c.kind()) >= 0) {
+            if (k == ELEM) {
                 c.popButStay();
                 return true;
             }
 
-            if (k > 0)
+            if (k > 0) {
                 c.toEnd();
+            }
 
             c.next();
         }
@@ -2176,30 +1971,27 @@
         return false;
     }
 
-    static boolean toNextSiblingElement(Cur c, Xobj parent)
-    {
+    static boolean toNextSiblingElement(Cur c, Xobj parent) {
         Xobj originalXobj = c._xobj;
         int originalPos = c._pos;
 
         int k = c.kind();
 
-        if (k == ATTR)
-        {
+        if (k == ATTR) {
             c.moveTo(parent);
             c.next();
-        }
-        else if (k == ELEM)
+        } else if (k == ELEM) {
             c.skip();
+        }
 
-        while ((k = c.kind()) >= 0)
-        {
-            if (k == ELEM)
-            {
+        while ((k = c.kind()) >= 0) {
+            if (k == ELEM) {
                 return true;
             }
 
-            if (k > 0)
+            if (k > 0) {
                 c.toEnd();
+            }
 
             c.next();
         }
@@ -2209,21 +2001,17 @@
         return false;
     }
 
-    static void applyNamespaces(Cur c, Map namespaces)
-    {
+    static void applyNamespaces(Cur c, Map namespaces) {
         assert c.isContainer();
 
         java.util.Iterator i = namespaces.keySet().iterator();
 
-        while (i.hasNext())
-        {
+        while (i.hasNext()) {
             String prefix = (String) i.next();
 
             // Usually, this is the predefined xml namespace
-            if (!prefix.toLowerCase().startsWith("xml"))
-            {
-                if (c.namespaceForPrefix(prefix, false) == null)
-                {
+            if (!prefix.toLowerCase().startsWith("xml")) {
+                if (c.namespaceForPrefix(prefix, false) == null) {
                     c.push();
 
                     c.next();
@@ -2238,38 +2026,38 @@
         }
     }
 
-    static Map getAllNamespaces(Cur c, Map filleMe)
-    {
+    static Map<String,String> getAllNamespaces(Cur c, Map<String,String> filleMe) {
         assert c.isNode();
 
         c.push();
 
-        if (!c.isContainer())
+        if (!c.isContainer()) {
             c.toParent();
+        }
 
         assert c.isContainer();
 
-        do
-        {
+        do {
             QName cName = c.getName();
 
-            while (c.toNextAttr())
-            {
-                if (c.isXmlns())
-                {
+            while (c.toNextAttr()) {
+                if (c.isXmlns()) {
                     String prefix = c.getXmlnsPrefix();
                     String uri = c.getXmlnsUri();
 
-                    if (filleMe == null)
-                        filleMe = new HashMap();
+                    if (filleMe == null) {
+                        filleMe = new HashMap<>();
+                    }
 
-                    if (!filleMe.containsKey(prefix))
+                    if (!filleMe.containsKey(prefix)) {
                         filleMe.put(prefix, uri);
+                    }
                 }
             }
 
-            if (!c.isContainer())
+            if (!c.isContainer()) {
                 c.toParentRaw();
+            }
         }
         while (c.toParentRaw());
 
@@ -2278,15 +2066,12 @@
         return filleMe;
     }
 
-    class nthCache
-    {
-        private boolean namesSame(QName pattern, QName name)
-        {
+    class nthCache {
+        private boolean namesSame(QName pattern, QName name) {
             return pattern == null || pattern.equals(name);
         }
 
-        private boolean setsSame(QNameSet patternSet, QNameSet set)
-        {
+        private boolean setsSame(QNameSet patternSet, QNameSet set) {
             // value equality is probably too expensive. Since the use case
             // involves QNameSets that are generated by the compiler, we
             // can use identity comparison.
@@ -2295,42 +2080,39 @@
         }
 
         private boolean nameHit(QName namePattern, QNameSet setPattern,
-            QName name)
-        {
+                                QName name) {
             return
                 setPattern == null
-                ? namesSame(namePattern, name)
-                : setPattern.contains(name);
+                    ? namesSame(namePattern, name)
+                    : setPattern.contains(name);
         }
 
-        private boolean cacheSame(QName namePattern, QNameSet setPattern)
-        {
+        private boolean cacheSame(QName namePattern, QNameSet setPattern) {
             return
                 setPattern == null
-                ? namesSame(namePattern, _name)
-                : setsSame(setPattern, _set);
+                    ? namesSame(namePattern, _name)
+                    : setsSame(setPattern, _set);
         }
 
-        int distance(Xobj parent, QName name, QNameSet set, int n)
-        {
+        int distance(Xobj parent, QName name, QNameSet set, int n) {
             assert n >= 0;
 
-            if (_version != Locale.this.version())
+            if (_version != Locale.this.version()) {
                 return Integer.MAX_VALUE - 1;
+            }
 
-            if (parent != _parent || !cacheSame(name, set))
+            if (parent != _parent || !cacheSame(name, set)) {
                 return Integer.MAX_VALUE;
+            }
 
             return n > _n ? n - _n : _n - n;
         }
 
-        Xobj fetch(Xobj parent, QName name, QNameSet set, int n)
-        {
+        Xobj fetch(Xobj parent, QName name, QNameSet set, int n) {
             assert n >= 0;
 
             if (_version != Locale.this.version() || _parent != parent ||
-                !cacheSame(name, set) || n == 0)
-            {
+                !cacheSame(name, set) || n == 0) {
                 _version = Locale.this.version();
                 _parent = parent;
                 _name = name;
@@ -2339,10 +2121,8 @@
 
                 loop:
                 for (Xobj x = parent._firstChild;
-                     x != null; x = x._nextSibling)
-                {
-                    if (x.isElem() && nameHit(name, set, x._name))
-                    {
+                     x != null; x = x._nextSibling) {
+                    if (x.isElem() && nameHit(name, set, x._name)) {
                         _child = x;
                         _n = 0;
 
@@ -2351,20 +2131,18 @@
                 }
             }
 
-            if (_n < 0)
+            if (_n < 0) {
                 return null;
+            }
 
-            if (n > _n)
-            {
-                while (n > _n)
-                {
-                    for (Xobj x = _child._nextSibling; ; x = x._nextSibling)
-                    {
-                        if (x == null)
+            if (n > _n) {
+                while (n > _n) {
+                    for (Xobj x = _child._nextSibling; ; x = x._nextSibling) {
+                        if (x == null) {
                             return null;
+                        }
 
-                        if (x.isElem() && nameHit(name, set, x._name))
-                        {
+                        if (x.isElem() && nameHit(name, set, x._name)) {
                             _child = x;
                             _n++;
 
@@ -2372,18 +2150,14 @@
                         }
                     }
                 }
-            }
-            else if (n < _n)
-            {
-                while (n < _n)
-                {
-                    for (Xobj x = _child._prevSibling; ; x = x._prevSibling)
-                    {
-                        if (x == null)
+            } else if (n < _n) {
+                while (n < _n) {
+                    for (Xobj x = _child._prevSibling; ; x = x._prevSibling) {
+                        if (x == null) {
                             return null;
+                        }
 
-                        if (x.isElem() && nameHit(name, set, x._name))
-                        {
+                        if (x.isElem() && nameHit(name, set, x._name)) {
                             _child = x;
                             _n--;
 
@@ -2408,12 +2182,12 @@
     //
     //
 
-    Dom findDomNthChild ( Dom parent, int n )
-    {
+    Dom findDomNthChild(Dom parent, int n) {
         assert n >= 0;
 
-        if (parent == null)
+        if (parent == null) {
             return null;
+        }
 
         int da = _domNthCache_A.distance(parent, n);
         int db = _domNthCache_B.distance(parent, n);
@@ -2422,27 +2196,24 @@
         // the "better" cache should never walk more than 1/2 len
         Dom x = null;
         boolean bInvalidate = (db - _domNthCache_B._len / 2 > 0) &&
-            (db - _domNthCache_B._len / 2 - domNthCache.BLITZ_BOUNDARY > 0);
+                              (db - _domNthCache_B._len / 2 - domNthCache.BLITZ_BOUNDARY > 0);
         boolean aInvalidate = (da - _domNthCache_A._len / 2 > 0) &&
-            (da - _domNthCache_A._len / 2 - domNthCache.BLITZ_BOUNDARY > 0);
-        if (da <= db)
-            if (!aInvalidate)
+                              (da - _domNthCache_A._len / 2 - domNthCache.BLITZ_BOUNDARY > 0);
+        if (da <= db) {
+            if (!aInvalidate) {
                 x = _domNthCache_A.fetch(parent, n);
-            else
-            {
+            } else {
                 _domNthCache_B._version = -1;//blitz the cache
                 x = _domNthCache_B.fetch(parent, n);
             }
-        else if (!bInvalidate)
+        } else if (!bInvalidate) {
             x = _domNthCache_B.fetch(parent, n);
-        else
-        {
+        } else {
             _domNthCache_A._version = -1;//blitz the cache
             x = _domNthCache_A.fetch(parent, n);
         }
 
-        if (da == db)
-        {
+        if (da == db) {
             domNthCache temp = _domNthCache_A;
             _domNthCache_A = _domNthCache_B;
             _domNthCache_B = temp;
@@ -2451,21 +2222,20 @@
         return x;
     }
 
-    int domLength ( Dom parent )
-    {
-        if (parent == null)
+    int domLength(Dom parent) {
+        if (parent == null) {
             return 0;
+        }
 
-        int da = _domNthCache_A.distance( parent, 0 );
-        int db = _domNthCache_B.distance( parent, 0 );
+        int da = _domNthCache_A.distance(parent, 0);
+        int db = _domNthCache_B.distance(parent, 0);
 
         int len =
             da <= db
-            ? _domNthCache_A.length( parent )
-            : _domNthCache_B.length( parent );
+                ? _domNthCache_A.length(parent)
+                : _domNthCache_B.length(parent);
 
-        if (da == db)
-        {
+        if (da == db) {
             domNthCache temp = _domNthCache_A;
             _domNthCache_A = _domNthCache_B;
             _domNthCache_B = temp;
@@ -2474,39 +2244,37 @@
         return len;
     }
 
-    void invalidateDomCaches ( Dom d )
-    {
-        if (_domNthCache_A._parent == d)
+    void invalidateDomCaches(Dom d) {
+        if (_domNthCache_A._parent == d) {
             _domNthCache_A._version = -1;
-        if (_domNthCache_B._parent == d)
+        }
+        if (_domNthCache_B._parent == d) {
             _domNthCache_B._version = -1;
+        }
     }
 
-    boolean isDomCached ( Dom d )
-    {
+    boolean isDomCached(Dom d) {
         return _domNthCache_A._parent == d || _domNthCache_B._parent == d;
     }
 
-    class domNthCache
-    {
+    class domNthCache {
 
-        int distance ( Dom parent, int n )
-        {
+        int distance(Dom parent, int n) {
             assert n >= 0;
 
-            if (_version != Locale.this.version())
+            if (_version != Locale.this.version()) {
                 return Integer.MAX_VALUE - 1;
+            }
 
-            if (parent != _parent)
+            if (parent != _parent) {
                 return Integer.MAX_VALUE;
+            }
 
             return n > _n ? n - _n : _n - n;
         }
 
-        int length ( Dom parent )
-        {
-            if (_version != Locale.this.version() || _parent != parent)
-            {
+        int length(Dom parent) {
+            if (_version != Locale.this.version() || _parent != parent) {
                 _parent = parent;
                 _version = Locale.this.version();
                 _child = null;
@@ -2514,17 +2282,13 @@
                 _len = -1;
             }
 
-            if (_len == -1)
-            {
+            if (_len == -1) {
                 Dom x = null;
 
-                if (_child != null && _n != -1)
-                {
+                if (_child != null && _n != -1) {
                     x = _child;
                     _len = _n;
-                }
-                else
-                {
+                } else {
                     x = DomImpl.firstChild(_parent);
                     _len = 0;
 
@@ -2533,8 +2297,7 @@
                     _n = 0;
                 }
 
-                for (; x != null; x = DomImpl.nextSibling(x) )
-                {
+                for (; x != null; x = DomImpl.nextSibling(x)) {
                     _len++;
                 }
             }
@@ -2543,23 +2306,19 @@
             return _len;
         }
 
-        Dom fetch ( Dom parent, int n )
-        {
+        Dom fetch(Dom parent, int n) {
             assert n >= 0;
 
-            if (_version != Locale.this.version() || _parent != parent)
-            {
+            if (_version != Locale.this.version() || _parent != parent) {
                 _parent = parent;
                 _version = Locale.this.version();
                 _child = null;
                 _n = -1;
                 _len = -1;
 
-                for (Dom x = DomImpl.firstChild(_parent); x != null; x = DomImpl.nextSibling(x) )
-                {
+                for (Dom x = DomImpl.firstChild(_parent); x != null; x = DomImpl.nextSibling(x)) {
                     _n++;
-                    if (_child == null && n == _n )
-                    {
+                    if (_child == null && n == _n) {
                         _child = x;
                         break;
                     }
@@ -2568,17 +2327,16 @@
                 return _child;
             }
 
-            if (_n < 0)
+            if (_n < 0) {
                 return null;
+            }
 
-            if (n > _n)
-            {
-                while ( n > _n )
-                {
-                    for (Dom x = DomImpl.nextSibling(_child); ; x = DomImpl.nextSibling(x) )
-                    {
-                        if (x == null)
+            if (n > _n) {
+                while (n > _n) {
+                    for (Dom x = DomImpl.nextSibling(_child); ; x = DomImpl.nextSibling(x)) {
+                        if (x == null) {
                             return null;
+                        }
 
                         _child = x;
                         _n++;
@@ -2586,15 +2344,12 @@
                         break;
                     }
                 }
-            }
-            else if (n < _n)
-            {
-                while ( n < _n )
-                {
-                    for (Dom x = DomImpl.prevSibling(_child); ; x = DomImpl.prevSibling(x) )
-                    {
-                        if (x == null)
+            } else if (n < _n) {
+                while (n < _n) {
+                    for (Dom x = DomImpl.prevSibling(_child); ; x = DomImpl.prevSibling(x)) {
+                        if (x == null) {
                             return null;
+                        }
 
                         _child = x;
                         _n--;
@@ -2608,32 +2363,30 @@
         }
 
         public static final int BLITZ_BOUNDARY = 40; //walk small lists
-	 private long  _version;
-        private Dom   _parent;
-        private Dom   _child;
-        private int   _n;
-        private int   _len;
+        private long _version;
+        private Dom _parent;
+        private Dom _child;
+        private int _n;
+        private int _len;
     }
 
     //
     //
     //
 
-    CharUtil getCharUtil()
-    {
-        if (_charUtil == null)
+    CharUtil getCharUtil() {
+        if (_charUtil == null) {
             _charUtil = new CharUtil(1024);
+        }
 
         return _charUtil;
     }
 
-    long version()
-    {
+    long version() {
         return _versionAll;
     }
 
-    Cur weakCur(Object o)
-    {
+    Cur weakCur(Object o) {
         assert o != null && !(o instanceof Ref);
 
         Cur c = getCur();
@@ -2646,19 +2399,17 @@
         return c;
     }
 
-    final ReferenceQueue refQueue()
-    {
-        if (_refQueue == null)
+    final ReferenceQueue refQueue() {
+        if (_refQueue == null) {
             _refQueue = new ReferenceQueue();
+        }
 
         return _refQueue;
     }
 
     final static class Ref
-        extends PhantomReference
-    {
-        Ref(Cur c, Object obj)
-        {
+        extends PhantomReference {
+        Ref(Cur c, Object obj) {
             super(obj, c._locale.refQueue());
 
             _cur = c;
@@ -2667,13 +2418,11 @@
         Cur _cur;
     }
 
-    Cur tempCur()
-    {
+    Cur tempCur() {
         return tempCur(null);
     }
 
-    Cur tempCur(String id)
-    {
+    Cur tempCur(String id) {
         Cur c = getCur();
 
         assert c._tempFrame == -1;
@@ -2689,8 +2438,7 @@
         c._nextTemp = next;
         assert c._prevTemp == null;
 
-        if (next != null)
-        {
+        if (next != null) {
             assert next._prevTemp == null;
             next._prevTemp = c;
         }
@@ -2703,16 +2451,14 @@
         return c;
     }
 
-    Cur getCur()
-    {
+    Cur getCur() {
         assert _curPool == null || _curPoolCount > 0;
 
         Cur c;
 
-        if (_curPool == null)
+        if (_curPool == null) {
             c = new Cur(this);
-        else
-        {
+        } else {
             _curPool = _curPool.listRemove(c = _curPool);
             _curPoolCount--;
         }
@@ -2728,10 +2474,8 @@
         return c;
     }
 
-    void embedCurs()
-    {
-        for (Cur c; (c = _registered) != null;)
-        {
+    void embedCurs() {
+        for (Cur c; (c = _registered) != null; ) {
             assert c._xobj != null;
 
             _registered = c.listRemove(_registered);
@@ -2740,36 +2484,31 @@
         }
     }
 
-    TextNode createTextNode()
-    {
+    TextNode createTextNode() {
         return _saaj == null ? new TextNode(this) : new SaajTextNode(this);
     }
 
-    CdataNode createCdataNode()
-    {
+    CdataNode createCdataNode() {
         return _saaj == null ?
             new CdataNode(this) : new SaajCdataNode(this);
     }
 
-    boolean entered()
-    {
+    boolean entered() {
         return _tempFrames.length - _numTempFramesLeft > 0;
     }
 
-    public void enter(Locale otherLocale)
-    {
+    public void enter(Locale otherLocale) {
         enter();
 
-        if (otherLocale != this)
+        if (otherLocale != this) {
             otherLocale.enter();
+        }
     }
 
-    public void enter()
-    {
+    public void enter() {
         assert _numTempFramesLeft >= 0;
 
-        if (--_numTempFramesLeft <= 0)
-        {
+        if (--_numTempFramesLeft <= 0) {
             Cur[] newTempFrames = new Cur[_tempFrames.length * 2];
             //move this assignment down so if array allocation fails, error is not masked
             _numTempFramesLeft = _tempFrames.length;
@@ -2778,129 +2517,125 @@
             _tempFrames = newTempFrames;
         }
 
-        if (++_entryCount > 1000)
-        {
+        if (++_entryCount > 1000) {
             pollQueue();
             _entryCount = 0;
         }
     }
 
-    private void pollQueue()
-    {
-        if (_refQueue != null)
-        {
-            for (; ;)
-            {
+    private void pollQueue() {
+        if (_refQueue != null) {
+            for (; ; ) {
                 Ref ref = (Ref) _refQueue.poll();
 
-                if (ref == null)
+                if (ref == null) {
                     break;
+                }
 
-                if (ref._cur != null)
+                if (ref._cur != null) {
                     ref._cur.release();
+                }
             }
         }
     }
 
-    public void exit(Locale otherLocale)
-    {
+    public void exit(Locale otherLocale) {
         exit();
 
-        if (otherLocale != this)
+        if (otherLocale != this) {
             otherLocale.exit();
+        }
     }
 
-    public void exit()
-    {
+    public void exit() {
         // assert _numTempFramesLeft >= 0;
         //asserts computed frame fits between 0 and _tempFrames.length
         assert _numTempFramesLeft >= 0 &&
-            (_numTempFramesLeft <= _tempFrames.length - 1):
+               (_numTempFramesLeft <= _tempFrames.length - 1) :
             " Temp frames mismanaged. Impossible stack frame. Unsynchronized: " +
             noSync();
 
         int frame = _tempFrames.length - ++_numTempFramesLeft;
 
-        while (_tempFrames[frame] != null)
+        while (_tempFrames[frame] != null) {
             _tempFrames[frame].release();
+        }
     }
 
     //
     //
     //
 
-    public boolean noSync()
-    {
+    public boolean noSync() {
         return _noSync;
     }
 
-    public boolean sync()
-    {
+    public boolean sync() {
         return !_noSync;
     }
 
-    static final boolean isWhiteSpace(String s)
-    {
+    static final boolean isWhiteSpace(String s) {
         int l = s.length();
 
-        while (l-- > 0)
-            if (!CharUtil.isWhiteSpace(s.charAt(l)))
+        while (l-- > 0) {
+            if (!CharUtil.isWhiteSpace(s.charAt(l))) {
                 return false;
+            }
+        }
 
         return true;
     }
 
-    static final boolean isWhiteSpace(StringBuffer sb)
-    {
+    static final boolean isWhiteSpace(StringBuffer sb) {
         int l = sb.length();
 
-        while (l-- > 0)
-            if (!CharUtil.isWhiteSpace(sb.charAt(l)))
+        while (l-- > 0) {
+            if (!CharUtil.isWhiteSpace(sb.charAt(l))) {
                 return false;
+            }
+        }
 
         return true;
     }
 
-    static boolean beginsWithXml(String name)
-    {
-        if (name.length() < 3)
+    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'))
-        {
+            ((ch = name.charAt(2)) == 'l' || ch == 'L')) {
             return true;
         }
 
         return false;
     }
 
-    static boolean isXmlns(QName name)
-    {
+    static boolean isXmlns(QName name) {
         String prefix = name.getPrefix();
 
-        if (prefix.equals("xmlns"))
+        if (prefix.equals("xmlns")) {
             return true;
+        }
 
         return prefix.length() == 0 && name.getLocalPart().equals("xmlns");
     }
 
-    QName createXmlns(String prefix)
-    {
-        if (prefix == null)
+    QName createXmlns(String prefix) {
+        if (prefix == null) {
             prefix = "";
+        }
 
         return
             prefix.length() == 0
-            ? makeQName(_xmlnsUri, "xmlns", "")
-            : makeQName(_xmlnsUri, prefix, "xmlns");
+                ? makeQName(_xmlnsUri, "xmlns", "")
+                : makeQName(_xmlnsUri, prefix, "xmlns");
     }
 
-    static String xmlnsPrefix(QName name)
-    {
+    static String xmlnsPrefix(QName name) {
         return name.getPrefix().equals("xmlns") ? name.getLocalPart() : "";
     }
 
@@ -2908,10 +2643,9 @@
     // Loading/parsing
     //
 
-    static abstract class LoadContext
-    {
+    static abstract class LoadContext {
         protected abstract void startDTD(String name, String publicId,
-            String systemId);
+                                         String systemId);
 
         protected abstract void endDTD();
 
@@ -2922,7 +2656,7 @@
         protected abstract void attr(QName name, String value);
 
         protected abstract void attr(String local, String uri, String prefix,
-            String value);
+                                     String value);
 
         protected abstract void xmlns(String prefix, String uri);
 
@@ -2945,67 +2679,69 @@
         protected abstract void bookmarkLastNonAttr(XmlBookmark bm);
 
         protected abstract void bookmarkLastAttr(QName attrName,
-            XmlBookmark bm);
+                                                 XmlBookmark bm);
 
         protected abstract void lineNumber(int line, int column, int offset);
 
-        protected void addIdAttr(String eName, String aName){
-            if ( _idAttrs == null )
+        protected void addIdAttr(String eName, String aName) {
+            if (_idAttrs == null) {
                 _idAttrs = new java.util.Hashtable();
-            _idAttrs.put(aName,eName);
+            }
+            _idAttrs.put(aName, eName);
         }
 
-        protected boolean isAttrOfTypeId(QName aqn, QName eqn){
-            if (_idAttrs == null)
+        protected boolean isAttrOfTypeId(QName aqn, QName eqn) {
+            if (_idAttrs == null) {
                 return false;
+            }
             String pre = aqn.getPrefix();
             String lName = aqn.getLocalPart();
-            String urnName = "".equals(pre)?lName:pre + ":" + lName;
+            String urnName = "".equals(pre) ? lName : pre + ":" + lName;
             String eName = (String) _idAttrs.get(urnName);
-            if (eName == null ) return false;
+            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;
+            urnName = "".equals(pre) ? lName : pre + ":" + lName;
             return eName.equals(urnName);
         }
+
         private java.util.Hashtable _idAttrs;
     }
 
     private static class DefaultEntityResolver
-        implements EntityResolver
-    {
-        public InputSource resolveEntity(String publicId, String systemId)
-        {
+        implements EntityResolver {
+        public InputSource resolveEntity(String publicId, String systemId) {
             return new InputSource(new StringReader(""));
         }
     }
 
-    private static SaxLoader getSaxLoader(XmlOptions options) throws XmlException
-    {
+    private static SaxLoader getSaxLoader(XmlOptions options) throws XmlException {
         options = XmlOptions.maskNull(options);
 
         EntityResolver er = null;
 
-        if (!options.hasOption(XmlOptions.LOAD_USE_DEFAULT_RESOLVER))
-        {
-            er = (EntityResolver) options.get(XmlOptions.ENTITY_RESOLVER);
+        if (!options.isLoadUseDefaultResolver()) {
+            er = options.getEntityResolver();
 
-            if (er == null)
+            if (er == null) {
                 er = ResolverUtil.getGlobalEntityResolver();
+            }
 
-            if (er == null)
+            if (er == null) {
                 er = new DefaultEntityResolver();
+            }
         }
 
-        XMLReader xr = (XMLReader) options.get(
-            XmlOptions.LOAD_USE_XMLREADER);
+        XMLReader xr = options.getLoadUseXMLReader();
 
         if (xr == null) {
             try {
                 xr = SAXHelper.newXMLReader(new XmlOptionsBean(options));
-            } catch(Exception e) {
+            } catch (Exception e) {
                 throw new XmlException("Problem creating XMLReader", e);
             }
         }
@@ -3014,24 +2750,22 @@
 
         // I've noticed that most XMLReaders don't like a null EntityResolver...
 
-        if (er != null)
+        if (er != null) {
             xr.setEntityResolver(er);
+        }
 
         return sl;
     }
 
     private static class XmlReaderSaxLoader
-        extends SaxLoader
-    {
-        XmlReaderSaxLoader(XMLReader xr)
-        {
+        extends SaxLoader {
+        XmlReaderSaxLoader(XMLReader xr) {
             super(xr, null);
         }
     }
 
     private static abstract class SaxHandler
-        implements ContentHandler, LexicalHandler , DeclHandler, DTDHandler
-    {
+        implements ContentHandler, LexicalHandler, DeclHandler, DTDHandler {
         protected Locale _locale;
 
         protected LoadContext _context;
@@ -3045,86 +2779,75 @@
         private int _entityBytes = 0;
         private int _insideEntity = 0;
 
-        SaxHandler(Locator startLocator)
-        {
+        SaxHandler(Locator startLocator) {
             _startLocator = startLocator;
         }
 
-        SaxHandler()
-        {
+        SaxHandler() {
             this(null);
         }
 
-        void initSaxHandler(Locale l, final XmlOptions options)
-        {
+        void initSaxHandler(Locale l, final XmlOptions options) {
             _locale = l;
 
             XmlOptions safeOptions = XmlOptions.maskNull(options);
 
             _context = new Cur.CurLoadContext(_locale, safeOptions);
 
-            _wantLineNumbers = safeOptions.hasOption(XmlOptions.LOAD_LINE_NUMBERS);
-            _wantLineNumbersAtEndElt = safeOptions.hasOption(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT);
-            _wantCdataBookmarks = safeOptions.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS);
+            _wantLineNumbers = safeOptions.isLoadLineNumbers();
+            _wantLineNumbersAtEndElt = safeOptions.isLoadLineNumbersEndElement();
+            _wantCdataBookmarks = safeOptions.isUseCDataBookmarks();
 
-            if (safeOptions.hasOption(XmlOptions.LOAD_ENTITY_BYTES_LIMIT))
-                _entityBytesLimit = (Integer) (safeOptions.get(XmlOptions.LOAD_ENTITY_BYTES_LIMIT));
+            Integer limit = safeOptions.getLoadEntityBytesLimit();
+            if (limit != null) {
+                _entityBytesLimit = limit;
+            }
         }
 
-        public void startDocument()
-            throws SAXException
-        {
+        public void startDocument() throws SAXException {
             // Do nothing ... start of document is implicit
         }
 
         public void endDocument()
-            throws SAXException
-        {
+            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)
+                                 Attributes atts)
+            throws SAXException {
+            if (local.length() == 0) {
                 local = qName;
+            }
 
             // Out current parser does not error when a
             // namespace is used and not defined.  Check for these here
 
-            if (qName.indexOf(':') >= 0 && uri.length() == 0)
-            {
+            if (qName.indexOf(':') >= 0 && uri.length() == 0) {
                 XmlError err =
                     XmlError.forMessage("Use of undefined namespace prefix: " +
-                    qName.substring(0, qName.indexOf(':')));
+                                        qName.substring(0, qName.indexOf(':')));
 
                 throw new XmlRuntimeException(err.toString(), null, err);
             }
 
             _context.startElement(_locale.makeQualifiedQName(uri, qName));
 
-            if (_wantLineNumbers && _startLocator != null)
-            {
+            if (_wantLineNumbers && _startLocator != null) {
                 _context.bookmark(
                     new XmlLineNumber(_startLocator.getLineNumber(),
                         _startLocator.getColumnNumber() - 1, -1));
             }
 
-            for (int i = 0, len = atts.getLength(); i < len; i++)
-            {
+            for (int i = 0, len = atts.getLength(); i < len; i++) {
                 String aqn = atts.getQName(i);
 
-                if (aqn.equals("xmlns"))
-                {
+                if (aqn.equals("xmlns")) {
                     _context.xmlns("", atts.getValue(i));
-                }
-                else if (aqn.startsWith("xmlns:"))
-                {
+                } else if (aqn.startsWith("xmlns:")) {
                     String prefix = aqn.substring(6);
 
-                    if (prefix.length() == 0)
-                    {
+                    if (prefix.length() == 0) {
                         XmlError err =
                             XmlError.forMessage("Prefix not specified",
                                 XmlError.SEVERITY_ERROR);
@@ -3135,12 +2858,11 @@
 
                     String attrUri = atts.getValue(i);
 
-                    if (attrUri.length() == 0)
-                    {
+                    if (attrUri.length() == 0) {
                         XmlError err =
                             XmlError.forMessage(
                                 "Prefix can't be mapped to no namespace: " +
-                            prefix,
+                                prefix,
                                 XmlError.SEVERITY_ERROR);
 
                         throw new XmlRuntimeException(err.toString(), null,
@@ -3148,16 +2870,13 @@
                     }
 
                     _context.xmlns(prefix, attrUri);
-                }
-                else
-                {
+                } else {
                     int colon = aqn.indexOf(':');
 
-                    if (colon < 0)
+                    if (colon < 0) {
                         _context.attr(aqn, atts.getURI(i), null,
                             atts.getValue(i));
-                    else
-                    {
+                    } else {
                         _context.attr(aqn.substring(colon + 1), atts.getURI(i), aqn.substring(
                             0, colon),
                             atts.getValue(i));
@@ -3167,12 +2886,10 @@
         }
 
         public void endElement(String namespaceURI, String localName,
-            String qName)
-            throws SAXException
-        {
+                               String qName)
+            throws SAXException {
             _context.endElement();
-            if (_wantLineNumbersAtEndElt && _startLocator != null)
-            {
+            if (_wantLineNumbersAtEndElt && _startLocator != null) {
                 _context.bookmark(
                     new XmlLineNumber(_startLocator.getLineNumber(),
                         _startLocator.getColumnNumber() - 1, -1));
@@ -3180,19 +2897,17 @@
         }
 
         public void characters(char ch[], int start, int length)
-            throws SAXException
-        {
+            throws SAXException {
             _context.text(ch, start, length);
 
-            if (_wantCdataBookmarks && _insideCDATA && _startLocator != null)
+            if (_wantCdataBookmarks && _insideCDATA && _startLocator != null) {
                 _context.bookmarkLastNonAttr(CDataBookmark.CDATA_BOOKMARK);
+            }
 
-            if (_insideEntity!=0)
-            {
-                if ((_entityBytes += length) > _entityBytesLimit)
-                {
+            if (_insideEntity != 0) {
+                if ((_entityBytes += length) > _entityBytesLimit) {
                     XmlError err = XmlError.forMessage(XmlErrorCodes.EXCEPTION_EXCEEDED_ENTITY_BYTES,
-                            new Integer[]{_entityBytesLimit});
+                        new Integer[]{_entityBytesLimit});
 
                     throw new SAXException(err.getMessage());
                 }
@@ -3200,40 +2915,33 @@
         }
 
         public void ignorableWhitespace(char ch[], int start, int length)
-            throws SAXException
-        {
+            throws SAXException {
         }
 
         public void comment(char ch[], int start, int length)
-            throws SAXException
-        {
+            throws SAXException {
             _context.comment(ch, start, length);
         }
 
         public void processingInstruction(String target, String data)
-            throws SAXException
-        {
+            throws SAXException {
             _context.procInst(target, data);
         }
 
         public void startDTD(String name, String publicId, String systemId)
-            throws SAXException
-        {
+            throws SAXException {
             _context.startDTD(name, publicId, systemId);
         }
 
         public void endDTD()
-            throws SAXException
-        {
+            throws SAXException {
             _context.endDTD();
         }
 
         public void startPrefixMapping(String prefix, String uri)
-            throws SAXException
-        {
+            throws SAXException {
             if (beginsWithXml(prefix) &&
-                !("xml".equals(prefix) && _xml1998Uri.equals(uri)))
-            {
+                !("xml".equals(prefix) && _xml1998Uri.equals(uri))) {
                 XmlError err =
                     XmlError.forMessage(
                         "Prefix can't begin with XML: " + prefix,
@@ -3244,43 +2952,36 @@
         }
 
         public void endPrefixMapping(String prefix)
-            throws SAXException
-        {
+            throws SAXException {
         }
 
         public void skippedEntity(String name)
-            throws SAXException
-        {
+            throws SAXException {
 //            throw new RuntimeException( "Not impl: skippedEntity" );
         }
 
         public void startCDATA()
-            throws SAXException
-        {
+            throws SAXException {
             _insideCDATA = true;
         }
 
         public void endCDATA()
-            throws SAXException
-        {
+            throws SAXException {
             _insideCDATA = false;
         }
 
         public void startEntity(String name)
-            throws SAXException
-        {
+            throws SAXException {
             _insideEntity++;
         }
 
         public void endEntity(String name)
-            throws SAXException
-        {
+            throws SAXException {
             _insideEntity--;
-            assert _insideEntity>=0;
+            assert _insideEntity >= 0;
 
-            if (_insideEntity==0)
-            {
-                _entityBytes=0;
+            if (_insideEntity == 0) {
+                _entityBytes = 0;
             }
         }
 
@@ -3291,37 +2992,38 @@
         }
 
         //DeclHandler
-        public void attributeDecl(String eName, String aName, String type, String valueDefault, String value){
-             if (type.equals("ID")){
-                 _context.addIdAttr(eName,aName);
-             }
+        public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) {
+            if (type.equals("ID")) {
+                _context.addIdAttr(eName, aName);
+            }
         }
-        public void elementDecl(String name, String model){
-         }
-        public void externalEntityDecl(String name, String publicId, String systemId){
-         }
-        public void internalEntityDecl(String name, String value){
-         }
+
+        public void elementDecl(String name, String model) {
+        }
+
+        public void externalEntityDecl(String name, String publicId, String systemId) {
+        }
+
+        public void internalEntityDecl(String name, String value) {
+        }
 
         //DTDHandler
-        public void notationDecl(String name, String publicId, String systemId){
+        public void notationDecl(String name, String publicId, String systemId) {
         }
-        public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName){
+
+        public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) {
         }
     }
 
     private static abstract class SaxLoader
         extends SaxHandler
-        implements ErrorHandler
-    {
-        SaxLoader(XMLReader xr, Locator startLocator)
-        {
+        implements ErrorHandler {
+        SaxLoader(XMLReader xr, Locator startLocator) {
             super(startLocator);
 
             _xr = xr;
 
-            try
-            {
+            try {
                 _xr.setFeature(
                     "http://xml.org/sax/features/namespace-prefixes", true);
                 _xr.setFeature("http://xml.org/sax/features/namespaces", true);
@@ -3331,40 +3033,33 @@
                 _xr.setContentHandler(this);
                 _xr.setDTDHandler(this);
                 _xr.setErrorHandler(this);
-            }
-            catch (Throwable e) {
+            } catch (Throwable e) {
                 throw new RuntimeException(e.getMessage(), e);
             }
-            try
-            {
+            try {
                 _xr.setProperty("http://xml.org/sax/properties/declaration-handler", this);
-            }
-            catch (Throwable e) {
+            } catch (Throwable e) {
                 logger.log(XBLogger.WARN, "SAX Declaration Handler is not supported", e);
             }
         }
 
-        void setEntityResolver(EntityResolver er)
-        {
+        void setEntityResolver(EntityResolver er) {
             _xr.setEntityResolver(er);
         }
 
-        void postLoad(Cur c)
-        {
+        void postLoad(Cur c) {
             // fix garbage collection of Locale -> Xobj -> STL
             _locale = null;
             _context = null;
         }
 
         public Cur load(Locale l, InputSource is, XmlOptions options)
-            throws XmlException, IOException
-        {
+            throws XmlException, IOException {
             is.setSystemId("file://");
 
             initSaxHandler(l, options);
 
-            try
-            {
+            try {
                 _xr.parse(is);
 
                 Cur c = _context.finish();
@@ -3374,35 +3069,26 @@
                 postLoad(c);
 
                 return c;
-            }
-            catch (XmlRuntimeException e)
-            {
+            } catch (XmlRuntimeException e) {
                 _context.abort();
 
                 throw new XmlException(e);
-            }
-            catch (SAXParseException e)
-            {
+            } catch (SAXParseException e) {
                 _context.abort();
 
                 XmlError err =
                     XmlError.forLocation(e.getMessage(),
-                        (String) XmlOptions.safeGet(options,
-                            XmlOptions.DOCUMENT_SOURCE_NAME),
+                        options == null ? null : options.getDocumentSourceName(),
                         e.getLineNumber(), e.getColumnNumber(), -1);
 
                 throw new XmlException(err.toString(), e, err);
-            }
-            catch (SAXException e)
-            {
+            } catch (SAXException e) {
                 _context.abort();
 
                 XmlError err = XmlError.forMessage(e.getMessage());
 
                 throw new XmlException(err.toString(), e, err);
-            }
-            catch (RuntimeException e)
-            {
+            } catch (RuntimeException e) {
                 _context.abort();
 
                 throw e;
@@ -3410,20 +3096,17 @@
         }
 
         public void fatalError(SAXParseException e)
-            throws SAXException
-        {
+            throws SAXException {
             throw e;
         }
 
         public void error(SAXParseException e)
-            throws SAXException
-        {
+            throws SAXException {
             throw e;
         }
 
         public void warning(SAXParseException e)
-            throws SAXException
-        {
+            throws SAXException {
             throw e;
         }
 
@@ -3431,64 +3114,49 @@
     }
 
     private Dom load(InputSource is, XmlOptions options)
-        throws XmlException, IOException
-    {
+        throws XmlException, IOException {
         return getSaxLoader(options).load(this, is, options).getDom();
     }
 
     public Dom load(Reader r)
-        throws XmlException, IOException
-    {
+        throws XmlException, IOException {
         return load(r, null);
     }
 
     public Dom load(Reader r, XmlOptions options)
-        throws XmlException, IOException
-    {
+        throws XmlException, IOException {
         return load(new InputSource(r), options);
     }
 
     public Dom load(InputStream in)
-        throws XmlException, IOException
-    {
+        throws XmlException, IOException {
         return load(in, null);
     }
 
     public Dom load(InputStream in, XmlOptions options)
-        throws XmlException, IOException
-    {
+        throws XmlException, IOException {
         return load(new InputSource(in), options);
     }
 
     public Dom load(String s)
-        throws XmlException
-    {
+        throws XmlException {
         return load(s, null);
     }
 
     public Dom load(String s, XmlOptions options)
-        throws XmlException
-    {
+        throws XmlException {
         Reader r = new StringReader(s);
 
-        try
-        {
+        try {
             return load(r, options);
-        }
-        catch (IOException e)
-        {
-            assert false: "StringReader should not throw IOException";
+        } catch (IOException e) {
+            assert false : "StringReader should not throw IOException";
 
             throw new XmlException(e.getMessage(), e);
-        }
-        finally
-        {
-            try
-            {
+        } finally {
+            try {
                 r.close();
-            }
-            catch (IOException e)
-            {
+            } catch (IOException e) {
             }
         }
     }
@@ -3498,26 +3166,22 @@
     //
 
     public Document createDocument(String uri, String qname,
-        DocumentType doctype)
-    {
+                                   DocumentType doctype) {
         return DomImpl._domImplementation_createDocument(this, uri, qname,
             doctype);
     }
 
     public DocumentType createDocumentType(String qname, String publicId,
-        String systemId)
-    {
+                                           String systemId) {
         throw new RuntimeException("Not implemented");
 //        return DomImpl._domImplementation_createDocumentType( this, qname, publicId, systemId );
     }
 
-    public boolean hasFeature(String feature, String version)
-    {
+    public boolean hasFeature(String feature, String version) {
         return DomImpl._domImplementation_hasFeature(this, feature, version);
     }
 
-    public Object getFeature(String feature, String version)
-    {
+    public Object getFeature(String feature, String version) {
         throw new RuntimeException("DOM Level 3 Not implemented");
     }
 
@@ -3525,34 +3189,31 @@
     // Dom methods
     //
 
-    private static Dom checkNode(Node n)
-    {
-        if (n == null)
+    private static Dom checkNode(Node n) {
+        if (n == null) {
             throw new IllegalArgumentException("Node is null");
+        }
 
-        if (!(n instanceof Dom))
+        if (!(n instanceof Dom)) {
             throw new IllegalArgumentException("Node is not an XmlBeans node");
+        }
 
         return (Dom) n;
     }
 
-    public static XmlCursor nodeToCursor(Node n)
-    {
+    public static XmlCursor nodeToCursor(Node n) {
         return DomImpl._getXmlCursor(checkNode(n));
     }
 
-    public static XmlObject nodeToXmlObject(Node n)
-    {
+    public static XmlObject nodeToXmlObject(Node n) {
         return DomImpl._getXmlObject(checkNode(n));
     }
 
-    public static XMLStreamReader nodeToXmlStream(Node n)
-    {
+    public static XMLStreamReader nodeToXmlStream(Node n) {
         return DomImpl._getXmlStreamReader(checkNode(n));
     }
 
-    public static Node streamToNode(XMLStreamReader xs)
-    {
+    public static Node streamToNode(XMLStreamReader xs) {
         return Jsr173.nodeFromStream(xs);
     }
 
@@ -3560,22 +3221,19 @@
     // SaajCallback methods
     //
 
-    public void setSaajData(Node n, Object o)
-    {
+    public void setSaajData(Node n, Object o) {
         assert n instanceof Dom;
 
         DomImpl.saajCallback_setSaajData((Dom) n, o);
     }
 
-    public Object getSaajData(Node n)
-    {
+    public Object getSaajData(Node n) {
         assert n instanceof Dom;
 
         return DomImpl.saajCallback_getSaajData((Dom) n);
     }
 
-    public Element createSoapElement(QName name, QName parentName)
-    {
+    public Element createSoapElement(QName name, QName parentName) {
         assert _ownerDoc != null;
 
         return DomImpl.saajCallback_createSoapElement(_ownerDoc, name,
@@ -3583,8 +3241,7 @@
     }
 
     public Element importSoapElement(Document doc, Element elem, boolean deep,
-        QName parentName)
-    {
+                                     QName parentName) {
         assert doc instanceof Dom;
 
         return DomImpl.saajCallback_importSoapElement((Dom) doc, elem, deep,
@@ -3593,23 +3250,19 @@
 
 
     private static final class DefaultQNameFactory
-        implements QNameFactory
-    {
+        implements QNameFactory {
         private QNameCache _cache = XmlBeans.getQNameCache();
 
-        public QName getQName(String uri, String local)
-        {
+        public QName getQName(String uri, String local) {
             return _cache.getName(uri, local, "");
         }
 
-        public QName getQName(String uri, String local, String prefix)
-        {
+        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)
-        {
+                              char[] localSrc, int localPos, int localCch) {
             return
                 _cache.getName(new String(uriSrc, uriPos, uriCch),
                     new String(localSrc, localPos, localCch),
@@ -3617,9 +3270,8 @@
         }
 
         public QName getQName(char[] uriSrc, int uriPos, int uriCch,
-            char[] localSrc, int localPos, int localCch,
-            char[] prefixSrc, int prefixPos, int prefixCch)
-        {
+                              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),
@@ -3629,23 +3281,19 @@
 
 
     private static final class LocalDocumentQNameFactory
-        implements QNameFactory
-    {
-        private QNameCache _cache = new QNameCache( 32 );
+        implements QNameFactory {
+        private QNameCache _cache = new QNameCache(32);
 
-        public QName getQName(String uri, String local)
-        {
+        public QName getQName(String uri, String local) {
             return _cache.getName(uri, local, "");
         }
 
-        public QName getQName(String uri, String local, String prefix)
-        {
+        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)
-        {
+                              char[] localSrc, int localPos, int localCch) {
             return
                 _cache.getName(new String(uriSrc, uriPos, uriCch),
                     new String(localSrc, localPos, localCch),
@@ -3653,9 +3301,8 @@
         }
 
         public QName getQName(char[] uriSrc, int uriPos, int uriCch,
-            char[] localSrc, int localPos, int localCch,
-            char[] prefixSrc, int prefixPos, int prefixCch)
-        {
+                              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),
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Path.java b/src/main/java/org/apache/xmlbeans/impl/store/Path.java
index 505cdc4..7ab6242 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Path.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Path.java
@@ -18,8 +18,8 @@
 import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.DefaultClassLoaderResourceLoader;
 import org.apache.xmlbeans.impl.common.XPath;
-import org.apache.xmlbeans.impl.common.XPathExecutionContext;
 import org.apache.xmlbeans.impl.common.XPath.XPathCompileException;
+import org.apache.xmlbeans.impl.common.XPathExecutionContext;
 import org.w3c.dom.Node;
 
 import java.io.BufferedReader;
@@ -51,10 +51,10 @@
     private static final int USE_XQRL2002 = 0x08;
     private static final int USE_XDK = 0x10;
 
-    private static final Map<String,WeakReference<Path>> _xbeanPathCache = new WeakHashMap<>();
-    private static final Map<String,WeakReference<Path>> _xdkPathCache = new WeakHashMap<>();
-    private static final Map<String,WeakReference<Path>> _xqrlPathCache = new WeakHashMap<>();
-    private static final Map<String,WeakReference<Path>> _xqrl2002PathCache = new WeakHashMap<>();
+    private static final Map<String, WeakReference<Path>> _xbeanPathCache = new WeakHashMap<>();
+    private static final Map<String, WeakReference<Path>> _xdkPathCache = new WeakHashMap<>();
+    private static final Map<String, WeakReference<Path>> _xqrlPathCache = new WeakHashMap<>();
+    private static final Map<String, WeakReference<Path>> _xqrl2002PathCache = new WeakHashMap<>();
 
     private static Method _xdkCompilePath;
     private static Method _xqrlCompilePath;
@@ -109,8 +109,9 @@
 
         options = XmlOptions.maskNull(options);
 
-        if (options.hasOption(XmlOptions.XQUERY_CURRENT_NODE_VAR)) {
-            currentNodeVar = (String) options.get(XmlOptions.XQUERY_CURRENT_NODE_VAR);
+        String cnv = options.getXqueryCurrentNodeVar();
+        if (cnv != null) {
+            currentNodeVar = cnv;
 
             if (currentNodeVar.startsWith("$")) {
                 throw new IllegalArgumentException("Omit the '$' prefix for the current node variable");
@@ -141,7 +142,7 @@
                                 String currentVar, String delIntfName) {
         Path path = null;
         WeakReference<Path> pathWeakRef = null;
-        Map<String,String> namespaces = (force & USE_DELEGATE) != 0 ? new HashMap<>() : null;
+        Map<String, String> namespaces = (force & USE_DELEGATE) != 0 ? new HashMap<>() : null;
         lock.readLock().lock();
         try {
             if ((force & USE_XBEAN) != 0) {
@@ -261,7 +262,7 @@
     }
 
     static private Path getCompiledPathXbean(String pathExpr,
-                                             String currentVar, Map<String,String> namespaces) {
+                                             String currentVar, Map<String, String> namespaces) {
         Path path = XbeanPath.create(pathExpr, currentVar, namespaces);
         if (path != null) {
             _xbeanPathCache.put(path._pathKey, new WeakReference<>(path));
@@ -270,7 +271,7 @@
         return path;
     }
 
-    static private Path getCompiledPathDelegate(String pathExpr, String currentVar, Map<String,String> namespaces, String delIntfName) {
+    static private Path getCompiledPathDelegate(String pathExpr, String currentVar, Map<String, String> namespaces, String delIntfName) {
         if (namespaces == null) {
             namespaces = new HashMap<>();
         }
@@ -301,7 +302,7 @@
     //
 
     private static final class XbeanPath extends Path {
-        static Path create(String pathExpr, String currentVar, Map<String,String> namespaces) {
+        static Path create(String pathExpr, String currentVar, Map<String, String> namespaces) {
             try {
                 return new XbeanPath(pathExpr, currentVar,
                     XPath.compileXPath(pathExpr, currentVar, namespaces));
@@ -337,7 +338,7 @@
 
         private final String _currentVar;
         private final XPath _compiledPath;
-        public Map<String,String> namespaces;
+        public Map<String, String> namespaces;
     }
 
     private static Path createXdkCompiledPath(String pathExpr, String currentVar) {
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Query.java b/src/main/java/org/apache/xmlbeans/impl/store/Query.java
index 7fc8643..11c45fb 100644
--- a/src/main/java/org/apache/xmlbeans/impl/store/Query.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Query.java
@@ -312,19 +312,14 @@
                     ;
                 }
 
-                Map bindings = (Map) XmlOptions.maskNull(_options).
-                    get(XmlOptions.XQUERY_VARIABLE_MAP);
-                List resultsList;
-                resultsList = _engine.execQuery(_cur.getDom(), bindings);
-
-                assert resultsList.size() > -1;
+                Map<String, Object> bindings = XmlOptions.maskNull(_options).getXqueryVariables();
+                List resultsList = _engine.execQuery(_cur.getDom(), bindings);
 
                 XmlObject[] result = new XmlObject[resultsList.size()];
                 int i;
                 for (i = 0; i < resultsList.size(); i++) {
                     //copy objects into the locale
-                    Locale l = Locale.getLocale(_cur._locale._schemaTypeLoader,
-                        _options);
+                    Locale l = Locale.getLocale(_cur._locale._schemaTypeLoader, _options);
 
                     l.enter();
                     Object node = resultsList.get(i);
@@ -388,12 +383,8 @@
                     ;
                 }
 
-                Map bindings = (Map) XmlOptions.maskNull(_options).
-                    get(XmlOptions.XQUERY_VARIABLE_MAP);
-                List resultsList;
-                resultsList = _engine.execQuery(_cur.getDom(), bindings);
-
-                assert resultsList.size() > -1;
+                Map<String, Object> bindings = XmlOptions.maskNull(_options).getXqueryVariables();
+                List resultsList = _engine.execQuery(_cur.getDom(), bindings);
 
                 int i;
                 _engine = null;
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 49f7498..58b9f4c 100755
--- a/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Saver.java
@@ -15,37 +15,21 @@
 
 package org.apache.xmlbeans.impl.store;
 
-import javax.xml.namespace.QName;
-
 import org.apache.xmlbeans.SystemProperties;
 import org.apache.xmlbeans.XmlDocumentProperties;
-import org.apache.xmlbeans.XmlOptions;
 import org.apache.xmlbeans.XmlOptionCharEscapeMap;
-import org.apache.xmlbeans.xml.stream.*;
-
+import org.apache.xmlbeans.XmlOptions;
 import org.apache.xmlbeans.impl.common.*;
-
-import java.io.Writer;
-import java.io.Reader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-
+import org.apache.xmlbeans.xml.stream.CharacterData;
+import org.apache.xmlbeans.xml.stream.*;
 import org.xml.sax.ContentHandler;
-import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.SAXException;
-
+import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.AttributesImpl;
 
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.LinkedHashMap;
-import java.util.ConcurrentModificationException;
+import javax.xml.namespace.QName;
+import java.io.*;
+import java.util.*;
 
 abstract class Saver {
     static final int ROOT = Cur.ROOT;
@@ -55,7 +39,32 @@
     static final int PROCINST = Cur.PROCINST;
     static final int TEXT = Cur.TEXT;
 
-    protected abstract boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues);
+
+    private final Locale _locale;
+    private final long _version;
+
+    private SaveCur _cur;
+
+    private List<String> _ancestorNamespaces;
+    private final Map<String, String> _suggestedPrefixes;
+    protected XmlOptionCharEscapeMap _replaceChar;
+    private final boolean _useDefaultNamespace;
+    private Map<String, String> _preComputedNamespaces;
+    private final boolean _saveNamespacesFirst;
+
+    private final ArrayList<QName> _attrNames = new ArrayList<>();
+    private final ArrayList<String> _attrValues = new ArrayList<>();
+
+    private final ArrayList<String> _namespaceStack = new ArrayList<>();
+    private int _currentMapping;
+    private final HashMap<String, String> _uriMap = new HashMap<>();
+    private final HashMap<String, String> _prefixMap = new HashMap<>();
+    private String _initialDefaultUri;
+
+    static final String _newLine = SystemProperties.getProperty("line.separator", "\n");
+
+
+    protected abstract boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues);
 
     protected abstract void emitFinish(SaveCur c);
 
@@ -84,31 +93,19 @@
         _locale = c._locale;
         _version = _locale.version();
 
-        _namespaceStack = new ArrayList();
-        _uriMap = new HashMap();
-        _prefixMap = new HashMap();
-
-        _attrNames = new ArrayList();
-        _attrValues = new ArrayList();
-
         // Define implicit xml prefixed namespace
 
         addMapping("xml", Locale._xml1998Uri);
 
-        if (options.hasOption(XmlOptions.SAVE_IMPLICIT_NAMESPACES)) {
-            Map m = (Map) options.get(XmlOptions.SAVE_IMPLICIT_NAMESPACES);
-
-            for (Iterator i = m.keySet().iterator(); i.hasNext(); ) {
-                String prefix = (String) i.next();
-                addMapping(prefix, (String) m.get(prefix));
+        Map<String, String> m = options.getSaveImplicitNamespaces();
+        if (m != null) {
+            for (String prefix : m.keySet()) {
+                addMapping(prefix, m.get(prefix));
             }
         }
 
         // define character map for escaped replacements
-        if (options.hasOption(XmlOptions.SAVE_SUBSTITUTE_CHARACTERS)) {
-            _replaceChar = (XmlOptionCharEscapeMap)
-                    options.get(XmlOptions.SAVE_SUBSTITUTE_CHARACTERS);
-        }
+        _replaceChar = options.getSaveSubstituteCharacters();
 
         // If the default prefix has not been mapped, do so now
 
@@ -117,43 +114,39 @@
             addMapping("", _initialDefaultUri);
         }
 
-        if (options.hasOption(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES) &&
-                !(this instanceof SynthNamespaceSaver)) {
+        if (options.isSaveAggressiveNamespaces() && !(this instanceof SynthNamespaceSaver)) {
             SynthNamespaceSaver saver = new SynthNamespaceSaver(c, options);
 
-            while (saver.process())
-                ;
+            //noinspection StatementWithEmptyBody
+            while (saver.process()) { }
 
-            if (!saver._synthNamespaces.isEmpty())
+            if (!saver._synthNamespaces.isEmpty()) {
                 _preComputedNamespaces = saver._synthNamespaces;
+            }
         }
 
-        _useDefaultNamespace =
-                options.hasOption(XmlOptions.SAVE_USE_DEFAULT_NAMESPACE);
+        _useDefaultNamespace = options.isUseDefaultNamespace();
 
-        _saveNamespacesFirst = options.hasOption(XmlOptions.SAVE_NAMESPACES_FIRST);
+        _saveNamespacesFirst = options.isSaveNamespacesFirst();
 
-        if (options.hasOption(XmlOptions.SAVE_SUGGESTED_PREFIXES))
-            _suggestedPrefixes = (Map) options.get(XmlOptions.SAVE_SUGGESTED_PREFIXES);
+
+        _suggestedPrefixes = options.getSaveSuggestedPrefixes();
 
         _ancestorNamespaces = _cur.getAncestorNamespaces();
     }
 
     private static SaveCur createSaveCur(Cur c, XmlOptions options) {
-        QName synthName = (QName) options.get(XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT);
+        QName synthName = options.getSaveSyntheticDocumentElement();
 
         QName fragName = synthName;
 
         if (fragName == null) {
-            fragName =
-                    options.hasOption(XmlOptions.SAVE_USE_OPEN_FRAGMENT)
-                            ? Locale._openuriFragment
-                            : Locale._xmlFragment;
+            fragName = options.isSaveUseOpenFrag()
+                ? Locale._openuriFragment
+                : Locale._xmlFragment;
         }
 
-        boolean saveInner =
-                options.hasOption(XmlOptions.SAVE_INNER) &&
-                        !options.hasOption(XmlOptions.SAVE_OUTER);
+        boolean saveInner = options.isSaveInner() && !options.isSaveOuter();
 
         Cur start = c.tempCur();
         Cur end = c.tempCur();
@@ -166,12 +159,13 @@
             case ROOT: {
                 positionToInner(c, start, end);
 
-                if (Locale.isFragment(start, end))
+                if (Locale.isFragment(start, end)) {
                     cur = new FragSaveCur(start, end, fragName);
-                else if (synthName != null)
+                } else if (synthName != null) {
                     cur = new FragSaveCur(start, end, synthName);
-                else
+                } else {
                     cur = new DocSaveCur(c);
+                }
 
                 break;
             }
@@ -181,8 +175,8 @@
                     positionToInner(c, start, end);
 
                     cur =
-                            new FragSaveCur(
-                                    start, end, Locale.isFragment(start, end) ? fragName : synthName);
+                        new FragSaveCur(
+                            start, end, Locale.isFragment(start, end) ? fragName : synthName);
                 } else if (synthName != null) {
                     positionToInner(c, start, end);
 
@@ -220,8 +214,6 @@
                 start.moveToCur(c);
                 end.moveToCur(c);
             } else {
-                assert k == COMMENT || k == PROCINST;
-
                 start.moveToCur(c);
                 end.moveToCur(c);
                 end.skip();
@@ -230,13 +222,15 @@
             cur = new FragSaveCur(start, end, fragName);
         }
 
-        String filterPI = (String) options.get(XmlOptions.SAVE_FILTER_PROCINST);
+        String filterPI = options.getSaveFilterProcinst();
 
-        if (filterPI != null)
+        if (filterPI != null) {
             cur = new FilterPiSaveCur(cur, filterPI);
+        }
 
-        if (options.hasOption(XmlOptions.SAVE_PRETTY_PRINT))
+        if (options.isSavePrettyPrint()) {
             cur = new PrettySaveCur(cur, options);
+        }
 
         start.release();
         end.release();
@@ -249,8 +243,9 @@
 
         start.moveToCur(c);
 
-        if (!start.toFirstAttr())
+        if (!start.toFirstAttr()) {
             start.next();
+        }
 
         end.moveToCur(c);
         end.toEnd();
@@ -262,12 +257,13 @@
      */
     static boolean isBadChar(char ch) {
         return !(
-                Character.isHighSurrogate(ch) ||
-                        Character.isLowSurrogate(ch) ||
-                        (ch >= 0x20 && ch <= 0xD7FF) ||
-                        (ch >= 0xE000 && ch <= 0xFFFD) ||
-                        (ch >= 0x10000 && ch <= 0x10FFFF) ||
-                        (ch == 0x9) || (ch == 0xA) || (ch == 0xD)
+            Character.isHighSurrogate(ch) ||
+            Character.isLowSurrogate(ch) ||
+            (ch >= 0x20 && ch <= 0xD7FF) ||
+            (ch >= 0xE000 && ch <= 0xFFFD) ||
+            // TODO: ch >= 0x10000 && ch <= 0x10FFFF is always false for a char, use codepoints/ints
+            (ch >= 0x10000 && ch <= 0x10FFFF) ||
+            (ch == 0x9) || (ch == 0xA) || (ch == 0xD)
         );
     }
 
@@ -286,11 +282,13 @@
     protected final boolean process() {
         assert _locale.entered();
 
-        if (_cur == null)
+        if (_cur == null) {
             return false;
+        }
 
-        if (_version != _locale.version())
+        if (_version != _locale.version()) {
             throw new ConcurrentModificationException("Document changed during save");
+        }
 
         switch (_cur.kind()) {
             case ROOT: {
@@ -338,12 +336,12 @@
         return true;
     }
 
-    private final void processFinish() {
+    private void processFinish() {
         emitFinish(_cur);
         popMappings();
     }
 
-    private final void processRoot() {
+    private void processRoot() {
         assert _cur.isRoot();
 
         XmlDocumentProperties props = _cur.getDocProps();
@@ -357,10 +355,11 @@
         if (systemId != null || docTypeName != null) {
             if (docTypeName == null) {
                 _cur.push();
-                while (!_cur.isElem() && _cur.next())
-                    ;
-                if (_cur.isElem())
+                //noinspection StatementWithEmptyBody
+                while (!_cur.isElem() && _cur.next()) { }
+                if (_cur.isElem()) {
                     docTypeName = _cur.getName().getLocalPart();
+                }
                 _cur.pop();
             }
 
@@ -391,7 +390,7 @@
         emitStartDoc(_cur);
     }
 
-    private final void processElement() {
+    private void processElement() {
         assert _cur.isElem() && _cur.getName() != null;
 
         QName name = _cur.getName();
@@ -454,9 +453,9 @@
         // namespaces are mapped on the first container which has a name.
 
         if (_preComputedNamespaces != null) {
-            for (Iterator i = _preComputedNamespaces.keySet().iterator(); i.hasNext(); ) {
-                String uri = (String) i.next();
-                String prefix = (String) _preComputedNamespaces.get(uri);
+            for (Map.Entry<String,String> entry : _preComputedNamespaces.entrySet()) {
+                String uri = entry.getKey();
+                String prefix = entry.getValue();
                 boolean considerDefault = prefix.length() == 0 && !ensureDefaultEmpty;
 
                 ensureMapping(uri, prefix, considerDefault, false);
@@ -481,17 +480,12 @@
     //    Mapping
     //
 
-    boolean hasMappings() {
-        int i = _namespaceStack.size();
-
-        return i > 0 && _namespaceStack.get(i - 1) != null;
-    }
-
     void iterateMappings() {
         _currentMapping = _namespaceStack.size();
 
-        while (_currentMapping > 0 && _namespaceStack.get(_currentMapping - 1) != null)
+        while (_currentMapping > 0 && _namespaceStack.get(_currentMapping - 1) != null) {
             _currentMapping -= 8;
+        }
     }
 
     boolean hasMapping() {
@@ -504,32 +498,33 @@
 
     String mappingPrefix() {
         assert hasMapping();
-        return (String) _namespaceStack.get(_currentMapping + 6);
+        return _namespaceStack.get(_currentMapping + 6);
     }
 
     String mappingUri() {
         assert hasMapping();
-        return (String) _namespaceStack.get(_currentMapping + 7);
+        return _namespaceStack.get(_currentMapping + 7);
     }
 
-    private final void pushMappings(SaveCur c, boolean ensureDefaultEmpty) {
+    private void pushMappings(SaveCur c, boolean ensureDefaultEmpty) {
         assert c.isContainer();
 
         _namespaceStack.add(null);
 
         c.push();
 
-        namespaces:
-        for (boolean A = c.toFirstAttr(); A; A = c.toNextAttr())
-            if (c.isXmlns())
+        for (boolean A = c.toFirstAttr(); A; A = c.toNextAttr()) {
+            if (c.isXmlns()) {
                 addNewFrameMapping(c.getXmlnsPrefix(), c.getXmlnsUri(), ensureDefaultEmpty);
+            }
+        }
 
         c.pop();
 
         if (_ancestorNamespaces != null) {
             for (int i = 0; i < _ancestorNamespaces.size(); i += 2) {
-                String prefix = (String) _ancestorNamespaces.get(i);
-                String uri = (String) _ancestorNamespaces.get(i + 1);
+                String prefix = _ancestorNamespaces.get(i);
+                String uri = _ancestorNamespaces.get(i + 1);
 
                 addNewFrameMapping(prefix, uri, ensureDefaultEmpty);
             }
@@ -538,41 +533,45 @@
         }
 
         if (ensureDefaultEmpty) {
-            String defaultUri = (String) _prefixMap.get("");
+            String defaultUri = _prefixMap.get("");
 
             // I map the default to "" at the very beginning
             assert defaultUri != null;
 
-            if (defaultUri.length() > 0)
+            if (defaultUri.length() > 0) {
                 addMapping("", "");
+            }
         }
     }
 
-    private final void addNewFrameMapping(String prefix, String uri, boolean ensureDefaultEmpty) {
+    private void addNewFrameMapping(String prefix, String uri, boolean ensureDefaultEmpty) {
         // If the prefix maps to "", this don't include this mapping 'cause it's not well formed.
         // Also, if we want to make sure that the default namespace is always "", then check that
         // here as well.
 
         if ((prefix.length() == 0 || uri.length() > 0) &&
-                (!ensureDefaultEmpty || prefix.length() > 0 || uri.length() == 0)) {
+            (!ensureDefaultEmpty || prefix.length() > 0 || uri.length() == 0)) {
             // Make sure the prefix is not already mapped in this frame
 
-            for (iterateMappings(); hasMapping(); nextMapping())
-                if (mappingPrefix().equals(prefix))
+            for (iterateMappings(); hasMapping(); nextMapping()) {
+                if (mappingPrefix().equals(prefix)) {
                     return;
+                }
+            }
 
             // Also make sure that the prefix declaration is not redundant
             // This has the side-effect of making it impossible to set a
             // redundant prefix declaration, but seems that it's better
             // to just never issue a duplicate prefix declaration.
-            if (uri.equals(getNamespaceForPrefix(prefix)))
+            if (uri.equals(getNamespaceForPrefix(prefix))) {
                 return;
+            }
 
             addMapping(prefix, uri);
         }
     }
 
-    private final void addMapping(String prefix, String uri) {
+    private void addMapping(String prefix, String uri) {
         assert uri != null;
         assert prefix != null;
 
@@ -580,16 +579,16 @@
         // that uri will either go out of scope or be mapped to another
         // prefix.
 
-        String renameUri = (String) _prefixMap.get(prefix);
+        String renameUri = _prefixMap.get(prefix);
         String renamePrefix = null;
 
         if (renameUri != null) {
             // See if this prefix is already mapped to this uri.  If
             // so, then add to the stack, but there is nothing to rename
 
-            if (renameUri.equals(uri))
+            if (renameUri.equals(uri)) {
                 renameUri = null;
-            else {
+            } else {
                 int i = _namespaceStack.size();
 
                 while (i > 0) {
@@ -599,10 +598,11 @@
                     }
 
                     if (_namespaceStack.get(i - 7).equals(renameUri)) {
-                        renamePrefix = (String) _namespaceStack.get(i - 8);
+                        renamePrefix = _namespaceStack.get(i - 8);
 
-                        if (renamePrefix == null || !renamePrefix.equals(prefix))
+                        if (renamePrefix == null || !renamePrefix.equals(prefix)) {
                             break;
+                        }
                     }
 
                     i -= 8;
@@ -632,42 +632,47 @@
         _uriMap.put(uri, prefix);
         _prefixMap.put(prefix, uri);
 
-        if (renameUri != null)
+        if (renameUri != null) {
             _uriMap.put(renameUri, renamePrefix);
+        }
     }
 
-    private final void popMappings() {
+    private void popMappings() {
         for (; ; ) {
             int i = _namespaceStack.size();
 
-            if (i == 0)
+            if (i == 0) {
                 break;
+            }
 
             if (_namespaceStack.get(i - 1) == null) {
                 _namespaceStack.remove(i - 1);
                 break;
             }
 
-            Object oldUri = _namespaceStack.get(i - 7);
-            Object oldPrefix = _namespaceStack.get(i - 8);
+            String oldUri = _namespaceStack.get(i - 7);
+            String oldPrefix = _namespaceStack.get(i - 8);
 
-            if (oldPrefix == null)
+            if (oldPrefix == null) {
                 _uriMap.remove(oldUri);
-            else
+            } else {
                 _uriMap.put(oldUri, oldPrefix);
+            }
 
             oldPrefix = _namespaceStack.get(i - 4);
             oldUri = _namespaceStack.get(i - 3);
 
-            if (oldUri == null)
+            if (oldUri == null) {
                 _prefixMap.remove(oldPrefix);
-            else
+            } else {
                 _prefixMap.put(oldPrefix, oldUri);
+            }
 
-            String uri = (String) _namespaceStack.get(i - 5);
+            String uri = _namespaceStack.get(i - 5);
 
-            if (uri != null)
+            if (uri != null) {
                 _uriMap.put(uri, _namespaceStack.get(i - 6));
+            }
 
             // Hahahahahaha -- :-(
             _namespaceStack.remove(i - 1);
@@ -681,58 +686,22 @@
         }
     }
 
-    private final void dumpMappings() {
-        for (int i = _namespaceStack.size(); i > 0; ) {
-            if (_namespaceStack.get(i - 1) == null) {
-                System.out.println("----------------");
-                i--;
-                continue;
-            }
-
-            System.out.print("Mapping: ");
-            System.out.print(_namespaceStack.get(i - 2));
-            System.out.print(" -> ");
-            System.out.print(_namespaceStack.get(i - 1));
-            System.out.println();
-
-            System.out.print("Prefix Undo: ");
-            System.out.print(_namespaceStack.get(i - 4));
-            System.out.print(" -> ");
-            System.out.print(_namespaceStack.get(i - 3));
-            System.out.println();
-
-            System.out.print("Uri Rename: ");
-            System.out.print(_namespaceStack.get(i - 5));
-            System.out.print(" -> ");
-            System.out.print(_namespaceStack.get(i - 6));
-            System.out.println();
-
-            System.out.print("UriUndo: ");
-            System.out.print(_namespaceStack.get(i - 7));
-            System.out.print(" -> ");
-            System.out.print(_namespaceStack.get(i - 8));
-            System.out.println();
-
-            System.out.println();
-
-            i -= 8;
-        }
-    }
-
-    private final String ensureMapping(
-            String uri, String candidatePrefix,
-            boolean considerCreatingDefault, boolean mustHavePrefix) {
+    private void ensureMapping(
+        String uri, String candidatePrefix,
+        boolean considerCreatingDefault, boolean mustHavePrefix) {
         assert uri != null;
 
         // Can be called for no-namespaced things
 
-        if (uri.length() == 0)
-            return null;
+        if (uri.length() == 0) {
+            return;
+        }
 
-        String prefix = (String) _uriMap.get(uri);
+        String prefix = _uriMap.get(uri);
 
-        if (prefix != null && (prefix.length() > 0 || !mustHavePrefix))
-            return prefix;
+        if (prefix != null && (prefix.length() > 0 || !mustHavePrefix)) {
+            return;
+        }
 
         //
         // I try prefixes from a number of places, in order:
@@ -743,23 +712,25 @@
         //  4) ns#++
         //
 
-        if (candidatePrefix != null && candidatePrefix.length() == 0)
+        if (candidatePrefix != null && candidatePrefix.length() == 0) {
             candidatePrefix = null;
+        }
 
-        if (candidatePrefix == null || !tryPrefix(candidatePrefix)) {
+        if (!tryPrefix(candidatePrefix)) {
             if (_suggestedPrefixes != null &&
-                    _suggestedPrefixes.containsKey(uri) &&
-                    tryPrefix((String) _suggestedPrefixes.get(uri))) {
-                candidatePrefix = (String) _suggestedPrefixes.get(uri);
-            } else if (considerCreatingDefault && _useDefaultNamespace && tryPrefix(""))
+                _suggestedPrefixes.containsKey(uri) &&
+                tryPrefix(_suggestedPrefixes.get(uri))) {
+                candidatePrefix = _suggestedPrefixes.get(uri);
+            } else if (considerCreatingDefault && _useDefaultNamespace && tryPrefix("")) {
                 candidatePrefix = "";
-            else {
+            } else {
                 String basePrefix = QNameHelper.suggestPrefix(uri);
                 candidatePrefix = basePrefix;
 
                 for (int i = 1; ; i++) {
-                    if (tryPrefix(candidatePrefix))
+                    if (tryPrefix(candidatePrefix)) {
                         break;
+                    }
 
                     candidatePrefix = basePrefix + i;
                 }
@@ -771,26 +742,26 @@
         syntheticNamespace(candidatePrefix, uri, considerCreatingDefault);
 
         addMapping(candidatePrefix, uri);
-
-        return candidatePrefix;
     }
 
     protected final String getUriMapping(String uri) {
-        assert _uriMap.get(uri) != null;
-        return (String) _uriMap.get(uri);
+        assert _uriMap.containsKey(uri);
+        return _uriMap.get(uri);
     }
 
     String getNonDefaultUriMapping(String uri) {
-        String prefix = (String) _uriMap.get(uri);
+        String prefix = _uriMap.get(uri);
 
-        if (prefix != null && prefix.length() > 0)
+        if (prefix != null && prefix.length() > 0) {
             return prefix;
+        }
 
-        for (Iterator keys = _prefixMap.keySet().iterator(); keys.hasNext(); ) {
-            prefix = (String) keys.next();
+        for (String s : _prefixMap.keySet()) {
+            prefix = s;
 
-            if (prefix.length() > 0 && _prefixMap.get(prefix).equals(uri))
+            if (prefix.length() > 0 && _prefixMap.get(prefix).equals(uri)) {
                 return prefix;
+            }
         }
 
         assert false : "Could not find non-default mapping";
@@ -798,11 +769,12 @@
         return null;
     }
 
-    private final boolean tryPrefix(String prefix) {
-        if (prefix == null || Locale.beginsWithXml(prefix))
+    private boolean tryPrefix(String prefix) {
+        if (prefix == null || Locale.beginsWithXml(prefix)) {
             return false;
+        }
 
-        String existingUri = (String) _prefixMap.get(prefix);
+        String existingUri = _prefixMap.get(prefix);
 
         // If the prefix is currently mapped, then try another prefix.  A
         // special case is that of trying to map the default prefix ("").
@@ -811,19 +783,16 @@
         // strings because I want to test for the specific initial default
         // uri I added when I initialized the saver.
 
-        if (existingUri != null && (prefix.length() > 0 || existingUri != _initialDefaultUri))
-            return false;
-
-        return true;
+        return existingUri == null || (prefix.length() <= 0 && Objects.equals(existingUri, _initialDefaultUri));
     }
 
     public final String getNamespaceForPrefix(String prefix) {
         assert !prefix.equals("xml") || _prefixMap.get(prefix).equals(Locale._xml1998Uri);
 
-        return (String) _prefixMap.get(prefix);
+        return _prefixMap.get(prefix);
     }
 
-    protected Map getPrefixMap() {
+    protected Map<String,String> getPrefixMap() {
         return _prefixMap;
     }
 
@@ -832,19 +801,19 @@
     //
 
     static final class SynthNamespaceSaver extends Saver {
-        LinkedHashMap _synthNamespaces = new LinkedHashMap();
+        LinkedHashMap<String,String> _synthNamespaces = new LinkedHashMap<>();
 
         SynthNamespaceSaver(Cur c, XmlOptions options) {
             super(c, options);
         }
 
         protected void syntheticNamespace(
-                String prefix, String uri, boolean considerCreatingDefault) {
+            String prefix, String uri, boolean considerCreatingDefault) {
             _synthNamespaces.put(uri, considerCreatingDefault ? "" : prefix);
         }
 
         protected boolean emitElement(
-                SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+            SaveCur c, List<QName> attrNames, List<String> attrValues) {
             return false;
         }
 
@@ -878,66 +847,77 @@
         TextSaver(Cur c, XmlOptions options, String encoding) {
             super(c, options);
 
-            boolean noSaveDecl =
-                    options != null && options.hasOption(XmlOptions.SAVE_NO_XML_DECL);
+            boolean noSaveDecl = options != null && options.isSaveNoXmlDecl();
 
-            if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD))
-                _cdataLengthThreshold = ((Integer) options.get(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD)).intValue();
+            if (options != null && options.getSaveCDataLengthThreshold() != null) {
+                _cdataLengthThreshold = options.getSaveCDataLengthThreshold();
+            }
 
-            if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD))
-                _cdataEntityCountThreshold = ((Integer) options.get(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD)).intValue();
+            if (options != null && options.getSaveCDataEntityCountThreshold() != null) {
+                _cdataEntityCountThreshold = options.getSaveCDataEntityCountThreshold();
+            }
 
-            if (options != null && options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS))
+            if (options != null && options.isUseCDataBookmarks()) {
                 _useCDataBookmarks = true;
+            }
 
-            if (options != null && options.hasOption(XmlOptions.SAVE_PRETTY_PRINT))
+            if (options != null && options.isSavePrettyPrint()) {
                 _isPrettyPrint = true;
+            }
 
             _in = _out = 0;
             _free = 0;
 
+            //noinspection ConstantConditions
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             if (encoding != null && !noSaveDecl) {
                 XmlDocumentProperties props = Locale.getDocProps(c, false);
 
                 String version = props == null ? null : props.getVersion();
 
-                if (version == null)
+                if (version == null) {
                     version = "1.0";
+                }
 
                 Boolean standalone = null;
-                if (props != null && props.get(XmlDocumentProperties.STANDALONE) != null)
+                if (props != null && props.get(XmlDocumentProperties.STANDALONE) != null) {
                     standalone = props.getStandalone();
+                }
 
                 emit("<?xml version=\"");
                 emit(version);
-                emit( "\" encoding=\"" + encoding + "\"");
-                if (standalone != null)
-                    emit( " standalone=\"" + (standalone.booleanValue() ? "yes" : "no") + "\"");
-                emit( "?>" + _newLine );
+                emit("\" encoding=\"" + encoding + "\"");
+                if (standalone != null) {
+                    emit(" standalone=\"" + (standalone ? "yes" : "no") + "\"");
+                }
+                emit("?>" + _newLine);
             }
         }
 
-        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+        @Override
+        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
             assert c.isElem();
 
             emit('<');
             emitName(c.getName(), false);
 
-            if (saveNamespacesFirst())
+            if (saveNamespacesFirst()) {
                 emitNamespacesHelper();
+            }
 
-            for (int i = 0; i < attrNames.size(); i++)
-                emitAttrHelper((QName) attrNames.get(i), (String) attrValues.get(i));
+            for (int i = 0; i < attrNames.size(); i++) {
+                emitAttrHelper(attrNames.get(i), attrValues.get(i));
+            }
 
-            if (!saveNamespacesFirst())
+            if (!saveNamespacesFirst()) {
                 emitNamespacesHelper();
+            }
 
             if (!c.hasChildren() && !c.hasText()) {
                 emit('/', '>');
@@ -1044,7 +1024,7 @@
         private void emitLiteral(String literal) {
             // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral
             // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral
-            if (literal.indexOf("\"") < 0) {
+            if (!literal.contains("\"")) {
                 emit('\"');
                 emit(literal);
                 emit('\"');
@@ -1096,8 +1076,9 @@
                 String prefix = name.getPrefix();
                 String mappedUri = getNamespaceForPrefix(prefix);
 
-                if (mappedUri == null || !mappedUri.equals(uri))
+                if (mappedUri == null || !mappedUri.equals(uri)) {
                     prefix = 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.
@@ -1106,8 +1087,9 @@
                 // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                 // here
 
-                if (needsPrefix && prefix.length() == 0)
+                if (needsPrefix && prefix.length() == 0) {
                     prefix = getNonDefaultUriMapping(uri);
+                }
 
                 if (prefix.length() > 0) {
                     emit(prefix);
@@ -1122,11 +1104,11 @@
 
         private void emit(char ch) {
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             preEmit(1);
 
@@ -1134,17 +1116,17 @@
 
             _in = (_in + 1) % _buf.length;
 
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
         }
 
         private void emit(char ch1, char ch2) {
-            if (preEmit(2))
+            if (preEmit(2)) {
                 return;
+            }
 
             _buf[_in] = ch1;
             _in = (_in + 1) % _buf.length;
@@ -1152,26 +1134,26 @@
             _buf[_in] = ch2;
             _in = (_in + 1) % _buf.length;
 
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
         }
 
         private void emit(String s) {
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             int cch = s == null ? 0 : s.length();
 
-            if (preEmit(cch))
+            if (preEmit(cch) || s == null) {
                 return;
+            }
 
             int chunk;
 
@@ -1184,12 +1166,11 @@
                 _in = (_in + cch) % _buf.length;
             }
 
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
         }
 
         private void emit(SaveCur c) {
@@ -1197,8 +1178,9 @@
                 Object src = c.getChars();
                 int cch = c._cchSrc;
 
-                if (preEmit(cch))
+                if (preEmit(cch)) {
                     return;
+                }
 
                 int chunk;
 
@@ -1210,26 +1192,29 @@
                     CharUtil.getChars(_buf, 0, src, c._offSrc + chunk, cch - chunk);
                     _in = (_in + cch) % _buf.length;
                 }
-            } else
+            } else {
                 preEmit(0);
+            }
         }
 
         private boolean preEmit(int cch) {
             assert cch >= 0;
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             _lastEmitCch = cch;
 
-            if (cch == 0)
+            if (cch == 0) {
                 return true;
+            }
 
-            if (_free <= cch)
+            if (_free <= cch) {
                 resize(cch, -1);
+            }
 
             assert cch <= _free;
 
@@ -1241,7 +1226,7 @@
 
             if (used == 0) {
                 assert _in == _out;
-                assert _free == _buf.length;
+                assert _buf == null || _free == _buf.length;
                 _in = _out = 0;
             }
 
@@ -1249,14 +1234,13 @@
 
             _free -= cch;
 
-            assert _free >= 0;
             assert _buf == null || _free == (_in >= _out ? _buf.length - (_in - _out) : _out - _in) - cch : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out) - cch) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in - cch) ||                  // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length - cch) ||                 // no data, all buffer free
-                    (_out == _in && _free == 0)                                    // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out) - cch) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in - cch) ||                  // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length - cch) ||                 // no data, all buffer free
+                   (_out == _in && _free == 0)                                    // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             return false;
         }
@@ -1264,8 +1248,9 @@
         private void entitizeContent(boolean forceCData) {
             assert _free >= 0;
 
-            if (_lastEmitCch == 0)
+            if (_lastEmitCch == 0) {
                 return;
+            }
 
             int i = _lastEmitIn;
             final int n = _buf.length;
@@ -1278,22 +1263,25 @@
             for (int cch = _lastEmitCch; cch > 0; cch--) {
                 char ch = _buf[i];
 
-                if (ch == '<' || ch == '&')
+                if (ch == '<' || ch == '&') {
                     count++;
-                else if (prevPrevChar == ']' && prevChar == ']' && ch == '>')
+                } else if (prevPrevChar == ']' && prevChar == ']' && ch == '>') {
                     hasCharToBeReplaced = true;
-                else if (isBadChar(ch) || isEscapedChar(ch) || (!_isPrettyPrint && ch == '\r'))
+                } else if (isBadChar(ch) || isEscapedChar(ch) || (!_isPrettyPrint && ch == '\r')) {
                     hasCharToBeReplaced = true;
+                }
 
-                if (++i == n)
+                if (++i == n) {
                     i = 0;
+                }
 
                 prevPrevChar = prevChar;
                 prevChar = ch;
             }
 
-            if (!forceCData && count == 0 && !hasCharToBeReplaced && count < _cdataEntityCountThreshold)
+            if (!forceCData && count == 0 && !hasCharToBeReplaced && count < _cdataEntityCountThreshold) {
                 return;
+            }
 
             i = _lastEmitIn;
 
@@ -1309,24 +1297,27 @@
 
                 lastWasBracket = _buf[i] == ']';
 
-                if (++i == _buf.length)
+                if (++i == _buf.length) {
                     i = 0;
+                }
 
                 for (int cch = _lastEmitCch - 2; cch > 0; cch--) {
                     char ch = _buf[i];
 
-                    if (ch == '>' && secondToLastWasBracket && lastWasBracket)
+                    if (ch == '>' && secondToLastWasBracket && lastWasBracket) {
                         i = replace(i, "]]>><![CDATA[");
-                    else if (isBadChar(ch))
+                    } else if (isBadChar(ch)) {
                         i = replace(i, "?");
-                    else
+                    } else {
                         i++;
+                    }
 
                     secondToLastWasBracket = lastWasBracket;
                     lastWasBracket = ch == ']';
 
-                    if (i == _buf.length)
+                    if (i == _buf.length) {
                         i = 0;
+                    }
                 }
 
                 emit("]]>");
@@ -1337,56 +1328,63 @@
                     ch_1 = ch;
                     ch = _buf[i];
 
-                    if (ch == '<')
+                    if (ch == '<') {
                         i = replace(i, "&lt;");
-                    else if (ch == '&')
+                    } else if (ch == '&') {
                         i = replace(i, "&amp;");
-                    else if (ch == '>' && ch_1 == ']' && ch_2 == ']')
+                    } else if (ch == '>' && ch_1 == ']' && ch_2 == ']') {
                         i = replace(i, "&gt;");
-                    else if (isBadChar(ch))
+                    } else if (isBadChar(ch)) {
                         i = replace(i, "?");
-                    else if (!_isPrettyPrint && ch == '\r')
+                    } else if (!_isPrettyPrint && ch == '\r') {
                         i = replace(i, "&#13;");
-                    else if (isEscapedChar(ch))
+                    } else if (isEscapedChar(ch)) {
                         i = replace(i, _replaceChar.getEscapedString(ch));
-                    else
+                    } else {
                         i++;
+                    }
 
-                    if (i == _buf.length)
+                    if (i == _buf.length) {
                         i = 0;
+                    }
                 }
             }
         }
 
         private void entitizeAttrValue(boolean replaceEscapedChar) {
-            if (_lastEmitCch == 0)
+            if (_lastEmitCch == 0) {
                 return;
+            }
 
             int i = _lastEmitIn;
 
             for (int cch = _lastEmitCch; cch > 0; cch--) {
                 char ch = _buf[i];
 
-                if (ch == '<')
+                if (ch == '<') {
                     i = replace(i, "&lt;");
-                else if (ch == '&')
+                } else if (ch == '&') {
                     i = replace(i, "&amp;");
-                else if (ch == '"')
+                } else if (ch == '"') {
                     i = replace(i, "&quot;");
-                else if (isEscapedChar(ch)) {
-                    if (replaceEscapedChar)
+                } else if (isEscapedChar(ch)) {
+                    if (replaceEscapedChar) {
                         i = replace(i, _replaceChar.getEscapedString(ch));
-                } else
+                    }
+                } else {
                     i++;
+                }
 
-                if (i == _buf.length)
+                if (i == _buf.length) {
                     i = 0;
+                }
             }
         }
 
         private void entitizeComment() {
-            if (_lastEmitCch == 0)
+            if (_lastEmitCch == 0) {
                 return;
+            }
 
             int i = _lastEmitIn;
 
@@ -1395,9 +1393,9 @@
             for (int cch = _lastEmitCch; cch > 0; cch--) {
                 char ch = _buf[i];
 
-                if (isBadChar(ch))
+                if (isBadChar(ch)) {
                     i = replace(i, "?");
-                else if (ch == '-') {
+                } else if (ch == '-') {
                     if (lastWasDash) {
                         // Replace "--" with "- " to make well formed
                         i = replace(i, " ");
@@ -1411,21 +1409,24 @@
                     i++;
                 }
 
-                if (i == _buf.length)
+                if (i == _buf.length) {
                     i = 0;
+                }
             }
 
             // Because I have only replaced chars with single chars,
             // _lastEmitIn will still be ok
 
             int offset = (_lastEmitIn + _lastEmitCch - 1) % _buf.length;
-            if (_buf[offset] == '-')
-                i = replace(offset, " ");
+            if (_buf[offset] == '-') {
+                replace(offset, " ");
+            }
         }
 
         private void entitizeProcinst() {
-            if (_lastEmitCch == 0)
+            if (_lastEmitCch == 0) {
                 return;
+            }
 
             int i = _lastEmitIn;
 
@@ -1434,15 +1435,17 @@
             for (int cch = _lastEmitCch; cch > 0; cch--) {
                 char ch = _buf[i];
 
-                if (isBadChar(ch))
+                if (isBadChar(ch)) {
                     i = replace(i, "?");
+                }
 
                 if (ch == '>') {
                     // TODO - Had to convert to a space here ... imples not well formed XML
-                    if (lastWasQuestion)
+                    if (lastWasQuestion) {
                         i = replace(i, " ");
-                    else
+                    } else {
                         i++;
+                    }
 
                     lastWasQuestion = false;
                 } else {
@@ -1450,8 +1453,9 @@
                     i++;
                 }
 
-                if (i == _buf.length)
+                if (i == _buf.length) {
                     i = 0;
+                }
             }
         }
 
@@ -1474,8 +1478,9 @@
 
             assert _free >= 0;
 
-            if (dCch > _free)
+            if (dCch > _free) {
                 i = resize(dCch, i);
+            }
 
             assert _free >= 0;
 
@@ -1516,12 +1521,11 @@
             _free -= dCch;
 
             assert _free >= 0;
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             return (i + dCch + 1) % _buf.length;
         }
@@ -1534,14 +1538,17 @@
             // atleast one character so we can determine if we're at the
             // end of the stream.
 
-            if (cch <= 0)
+            if (cch <= 0) {
                 cch = 1;
+            }
 
             int available = getAvailable();
 
-            for (; available < cch; available = getAvailable())
-                if (!process())
+            for (; available < cch; available = getAvailable()) {
+                if (!process()) {
                     break;
+                }
+            }
 
             assert available == getAvailable();
 
@@ -1560,17 +1567,18 @@
             assert cch > 0;
             assert cch >= _free;
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             int newLen = _buf == null ? _initialBufSize : _buf.length * 2;
             int used = getAvailable();
 
-            while (newLen - used < cch)
+            while (newLen - used < cch) {
                 newLen *= 2;
+            }
 
             char[] newBuf = new char[newLen];
 
@@ -1598,19 +1606,21 @@
             _buf = newBuf;
 
             assert _free >= 0;
+            //noinspection ConstantConditions
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             return i;
         }
 
         public int read() {
-            if (ensure(1) == 0)
+            if (ensure(1) == 0) {
                 return -1;
+            }
 
             assert getAvailable() > 0;
 
@@ -1619,12 +1629,11 @@
             _out = (_out + 1) % _buf.length;
             _free++;
 
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             return ch;
         }
@@ -1636,23 +1645,26 @@
 
             int n;
 
-            if ((n = ensure(len)) == 0)
+            if ((n = ensure(len)) == 0) {
                 return -1;
+            }
 
-            if (cbuf == null || len <= 0)
+            if (cbuf == null || len <= 0) {
                 return 0;
+            }
 
-            if (n < len)
+            if (n < len) {
                 len = n;
+            }
 
             if (_out < _in) {
                 System.arraycopy(_buf, _out, cbuf, off, len);
             } else {
                 int chunk = _buf.length - _out;
 
-                if (chunk >= len)
+                if (chunk >= len) {
                     System.arraycopy(_buf, _out, cbuf, off, len);
-                else {
+                } else {
                     System.arraycopy(_buf, _out, cbuf, off, chunk);
                     System.arraycopy(_buf, 0, cbuf, off + chunk, len - chunk);
                 }
@@ -1661,12 +1673,11 @@
             _out = (_out + len) % _buf.length;
             _free += len;
 
-            assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+            assert (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             assert _free >= 0;
 
@@ -1675,8 +1686,9 @@
 
         public int write(Writer writer, int cchMin) {
             while (getAvailable() < cchMin) {
-                if (!process())
+                if (!process()) {
                     break;
+                }
             }
 
             int charsAvailable = getAvailable();
@@ -1703,11 +1715,11 @@
                 _in = 0;
             }
             assert _buf == null ||
-                    (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
-                    (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
-                    (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
-                    (_out == _in && _free == 0)                               // buffer full
-                    : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
+                   (_out < _in && _free == _buf.length - (_in - _out)) || // data in the middle, free on the edges
+                   (_out > _in && _free == _out - _in) ||                   // data on the edges, free in the middle
+                   (_out == _in && _free == _buf.length) ||                  // no data, all buffer free
+                   (_out == _in && _free == 0)                               // buffer full
+                : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free;
 
             return charsAvailable;
         }
@@ -1717,8 +1729,8 @@
             // as well use my buffer here.  Fill the whole sucker up and
             // create a String!
 
-            while (process())
-                ;
+            //noinspection StatementWithEmptyBody
+            while (process()) { }
 
             assert _out == 0;
 
@@ -1753,13 +1765,13 @@
     }
 
     static final class OptimizedForSpeedSaver
-            extends Saver {
+        extends Saver {
         Writer _w;
-        private char[] _buf = new char[1024];
+        private final char[] _buf = new char[1024];
 
 
         static private class SaverIOException
-                extends RuntimeException {
+            extends RuntimeException {
             SaverIOException(IOException e) {
                 super(e);
             }
@@ -1772,11 +1784,11 @@
         }
 
         static void save(Cur cur, Writer writer)
-                throws IOException {
+            throws IOException {
             try {
                 Saver saver = new OptimizedForSpeedSaver(cur, writer);
-                while (saver.process()) {
-                }
+                //noinspection StatementWithEmptyBody
+                while (saver.process()) { }
             } catch (SaverIOException e) {
                 throw (IOException) e.getCause();
             }
@@ -1817,17 +1829,19 @@
             }
         }
 
-        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
             assert c.isElem();
 
             emit('<');
             emitName(c.getName(), false);
 
-            for (int i = 0; i < attrNames.size(); i++)
-                emitAttrHelper((QName) attrNames.get(i), (String) attrValues.get(i));
+            for (int i = 0; i < attrNames.size(); i++) {
+                emitAttrHelper(attrNames.get(i), attrValues.get(i));
+            }
 
-            if (!saveNamespacesFirst())
+            if (!saveNamespacesFirst()) {
                 emitNamespacesHelper();
+            }
 
             if (!c.hasChildren() && !c.hasText()) {
                 emit('/', '>');
@@ -1957,8 +1971,9 @@
                 String prefix = name.getPrefix();
                 String mappedUri = getNamespaceForPrefix(prefix);
 
-                if (mappedUri == null || !mappedUri.equals(uri))
+                if (mappedUri == null || !mappedUri.equals(uri)) {
                     prefix = 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.
@@ -1967,8 +1982,9 @@
                 // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                 // here
 
-                if (needsPrefix && prefix.length() == 0)
+                if (needsPrefix && prefix.length() == 0) {
                     prefix = getNonDefaultUriMapping(uri);
+                }
 
                 if (prefix.length() > 0) {
                     emit(prefix);
@@ -1987,21 +2003,22 @@
             for (int i = 0; i < len; i++) {
                 char ch = attVal.charAt(i);
 
-                if (ch == '<')
+                if (ch == '<') {
                     emit("&lt;");
-                else if (ch == '&')
+                } else if (ch == '&') {
                     emit("&amp;");
-                else if (ch == '"')
+                } else if (ch == '"') {
                     emit("&quot;");
-                else
+                } else {
                     emit(ch);
+                }
             }
         }
 
         private void emitLiteral(String literal) {
             // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral
             // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral
-            if (literal.indexOf("\"") < 0) {
+            if (!literal.contains("\"")) {
                 emit('\"');
                 emit(literal);
                 emit('\"');
@@ -2019,9 +2036,8 @@
             int cch = c._cchSrc;
             int off = c._offSrc;
             int index = 0;
-            int indexLimit = 0;
             while (index < cch) {
-                indexLimit = index + 512 > cch ? cch : index + 512;
+                int indexLimit = Math.min(index + 512, cch);
                 CharUtil.getChars(_buf, 0, src, off + index, indexLimit - index);
                 entitizeAndWriteText(indexLimit - index);
                 index = indexLimit;
@@ -2035,9 +2051,8 @@
             int cch = c._cchSrc;
             int off = c._offSrc;
             int index = 0;
-            int indexLimit = 0;
             while (index < cch) {
-                indexLimit = index + 512 > cch ? cch : 512;
+                int indexLimit = index + 512 > cch ? cch : 512;
                 CharUtil.getChars(_buf, 0, src, off + index, indexLimit);
                 entitizeAndWritePIText(indexLimit - index);
                 index = indexLimit;
@@ -2051,9 +2066,8 @@
             int cch = c._cchSrc;
             int off = c._offSrc;
             int index = 0;
-            int indexLimit = 0;
             while (index < cch) {
-                indexLimit = index + 512 > cch ? cch : 512;
+                int indexLimit = index + 512 > cch ? cch : 512;
                 CharUtil.getChars(_buf, 0, src, off + index, indexLimit);
                 entitizeAndWriteCommentText(indexLimit - index);
                 index = indexLimit;
@@ -2086,9 +2100,9 @@
             for (int i = 0; i < bufLimit; i++) {
                 char ch = _buf[i];
 
-                if (isBadChar(ch))
+                if (isBadChar(ch)) {
                     _buf[i] = '?';
-                else if (ch == '-') {
+                } else if (ch == '-') {
                     if (lastWasDash) {
                         // Replace "--" with "- " to make well formed
                         _buf[i] = ' ';
@@ -2100,12 +2114,14 @@
                     lastWasDash = false;
                 }
 
-                if (i == _buf.length)
+                if (i == _buf.length) {
                     i = 0;
+                }
             }
 
-            if (_buf[bufLimit - 1] == '-')
+            if (_buf[bufLimit - 1] == '-') {
                 _buf[bufLimit - 1] = ' ';
+            }
 
             emit(_buf, 0, bufLimit);
         }
@@ -2123,8 +2139,9 @@
 
                 if (ch == '>') {
                     // Had to convert to a space here ... imples not well formed XML
-                    if (lastWasQuestion)
+                    if (lastWasQuestion) {
                         _buf[i] = ' ';
+                    }
 
                     lastWasQuestion = false;
                 } else {
@@ -2142,11 +2159,11 @@
             _closed = false;
         }
 
-        public void close() throws IOException {
+        public void close() {
             _closed = true;
         }
 
-        public boolean ready() throws IOException {
+        public boolean ready() {
             return !_closed;
         }
 
@@ -2160,12 +2177,14 @@
                 } finally {
                     _locale.exit();
                 }
-            } else synchronized (_locale) {
-                _locale.enter();
-                try {
-                    return _textSaver.read();
-                } finally {
-                    _locale.exit();
+            } else {
+                synchronized (_locale) {
+                    _locale.enter();
+                    try {
+                        return _textSaver.read();
+                    } finally {
+                        _locale.exit();
+                    }
                 }
             }
         }
@@ -2180,12 +2199,14 @@
                 } finally {
                     _locale.exit();
                 }
-            } else synchronized (_locale) {
-                _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();
+                    }
                 }
             }
         }
@@ -2200,23 +2221,26 @@
                 } finally {
                     _locale.exit();
                 }
-            } else synchronized (_locale) {
-                _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();
+                    }
                 }
             }
         }
 
         private void checkClosed() throws IOException {
-            if (_closed)
+            if (_closed) {
                 throw new IOException("Reader has been closed");
+            }
         }
 
-        private Locale _locale;
-        private TextSaver _textSaver;
+        private final Locale _locale;
+        private final TextSaver _textSaver;
         private boolean _closed;
     }
 
@@ -2236,26 +2260,32 @@
 
             XmlDocumentProperties props = Locale.getDocProps(c, false);
 
-            if (props != null && props.getEncoding() != null)
+            if (props != null && props.getEncoding() != null) {
                 encoding = EncodingMap.getIANA2JavaMapping(props.getEncoding());
+            }
 
-            if (options.hasOption(XmlOptions.CHARACTER_ENCODING))
-                encoding = (String) options.get(XmlOptions.CHARACTER_ENCODING);
+            String enc = options.getCharacterEncoding();
+            if (enc != null) {
+                encoding = enc;
+            }
 
             if (encoding != null) {
                 String ianaEncoding = EncodingMap.getJava2IANAMapping(encoding);
 
-                if (ianaEncoding != null)
+                if (ianaEncoding != null) {
                     encoding = ianaEncoding;
+                }
             }
 
-            if (encoding == null)
+            if (encoding == null) {
                 encoding = EncodingMap.getJava2IANAMapping("UTF8");
+            }
 
-            String javaEncoding = EncodingMap.getIANA2JavaMapping(encoding);
+            String javaEncoding = (encoding == null) ? null : EncodingMap.getIANA2JavaMapping(encoding);
 
-            if (javaEncoding == null)
+            if (javaEncoding == null) {
                 throw new IllegalStateException("Unknown encoding: " + encoding);
+            }
 
             try {
                 _converter = new OutputStreamWriter(_outStreamImpl, javaEncoding);
@@ -2266,13 +2296,14 @@
             _textSaver = new TextSaver(c, options, encoding);
         }
 
-        public void close() throws IOException {
+        public void close() {
             _closed = true;
         }
 
         private void checkClosed() throws IOException {
-            if (_closed)
+            if (_closed) {
                 throw new IOException("Stream closed");
+            }
         }
 
         // Having the gateway here is kinda slow for the single character case.  It may be possible
@@ -2288,12 +2319,14 @@
                 } finally {
                     _locale.exit();
                 }
-            } else synchronized (_locale) {
-                _locale.enter();
-                try {
-                    return _outStreamImpl.read();
-                } finally {
-                    _locale.exit();
+            } else {
+                synchronized (_locale) {
+                    _locale.enter();
+                    try {
+                        return _outStreamImpl.read();
+                    } finally {
+                        _locale.exit();
+                    }
                 }
             }
         }
@@ -2301,11 +2334,13 @@
         public int read(byte[] bbuf, int off, int len) throws IOException {
             checkClosed();
 
-            if (bbuf == null)
+            if (bbuf == null) {
                 throw new NullPointerException("buf to read into is null");
+            }
 
-            if (off < 0 || off > bbuf.length)
+            if (off < 0 || off > bbuf.length) {
                 throw new IndexOutOfBoundsException("Offset is not within buf");
+            }
 
             if (_locale.noSync()) {
                 _locale.enter();
@@ -2314,12 +2349,14 @@
                 } finally {
                     _locale.exit();
                 }
-            } else synchronized (_locale) {
-                _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();
+                    }
                 }
             }
         }
@@ -2329,15 +2366,17 @@
             // atleast one byte so we can determine if we're at the
             // end of the stream.
 
-            if (cbyte <= 0)
+            if (cbyte <= 0) {
                 cbyte = 1;
+            }
 
             int bytesAvailable = _outStreamImpl.getAvailable();
 
             for (; bytesAvailable < cbyte;
                  bytesAvailable = _outStreamImpl.getAvailable()) {
-                if (_textSaver.write(_converter, 2048) < 2048)
+                if (_textSaver.write(_converter, 2048) < 2048) {
                     break;
+                }
             }
 
             bytesAvailable = _outStreamImpl.getAvailable();
@@ -2348,8 +2387,7 @@
             return bytesAvailable;
         }
 
-        public int available()
-                throws IOException {
+        public int available() {
             if (_locale.noSync()) {
                 _locale.enter();
                 try {
@@ -2357,7 +2395,7 @@
                 } finally {
                     _locale.exit();
                 }
-            } else
+            } else {
                 synchronized (_locale) {
                     _locale.enter();
                     try {
@@ -2366,12 +2404,14 @@
                         _locale.exit();
                     }
                 }
+            }
         }
 
         private final class OutputStreamImpl extends OutputStream {
             int read() {
-                if (InputStreamSaver.this.ensure(1) == 0)
+                if (InputStreamSaver.this.ensure(1) == 0) {
                     return -1;
+                }
 
                 assert getAvailable() > 0;
 
@@ -2390,27 +2430,30 @@
 
                 int n;
 
-                if ((n = ensure(len)) == 0)
+                if ((n = ensure(len)) == 0) {
                     return -1;
+                }
 
-                if (bbuf == null || len <= 0)
+                if (bbuf == null || len <= 0) {
                     return 0;
+                }
 
-                if (n < len)
+                if (n < len) {
                     len = n;
+                }
 
                 if (_out < _in) {
                     System.arraycopy(_buf, _out, bbuf, off, len);
                 } else {
                     int chunk = _buf.length - _out;
 
-                    if (chunk >= len)
+                    if (chunk >= len) {
                         System.arraycopy(_buf, _out, bbuf, off, len);
-                    else {
+                    } else {
                         System.arraycopy(_buf, _out, bbuf, off, chunk);
 
                         System.arraycopy(
-                                _buf, 0, bbuf, off + chunk, len - chunk);
+                            _buf, 0, bbuf, off + chunk, len - chunk);
                     }
                 }
                 _out = (_out + len) % _buf.length;
@@ -2425,8 +2468,9 @@
             }
 
             public void write(int bite) {
-                if (_free == 0)
+                if (_free == 0) {
                     resize(1);
+                }
 
                 assert _free > 0;
 
@@ -2438,12 +2482,13 @@
 
             public void write(byte[] buf, int off, int cbyte) {
                 assert cbyte >= 0;
-//System.out.println("---------\nAfter converter, write in queue: OutputStreamImpl.write():Saver:2469  " + cbyte + " bytes \n" + new String(buf, off, cbyte));
-                if (cbyte == 0)
+                if (cbyte == 0) {
                     return;
+                }
 
-                if (_free < cbyte)
+                if (_free < cbyte) {
                     resize(cbyte);
+                }
 
                 if (_in == _out) {
                     assert getAvailable() == 0;
@@ -2460,7 +2505,7 @@
                     System.arraycopy(buf, off, _buf, _in, chunk);
 
                     System.arraycopy(
-                            buf, off + chunk, _buf, 0, cbyte - chunk);
+                        buf, off + chunk, _buf, 0, cbyte - chunk);
 
                     _in = (_in + cbyte) % _buf.length;
                 }
@@ -2474,20 +2519,21 @@
                 int newLen = _buf == null ? _initialBufSize : _buf.length * 2;
                 int used = getAvailable();
 
-                while (newLen - used < cbyte)
+                while (newLen - used < cbyte) {
                     newLen *= 2;
+                }
 
                 byte[] newBuf = new byte[newLen];
 
                 if (used > 0) {
-                    if (_in > _out)
+                    if (_in > _out) {
                         System.arraycopy(_buf, _out, newBuf, 0, used);
-                    else {
+                    } else {
                         System.arraycopy(
-                                _buf, _out, newBuf, 0, used - _in);
+                            _buf, _out, newBuf, 0, used - _in);
 
                         System.arraycopy(
-                                _buf, 0, newBuf, used - _in, _in);
+                            _buf, 0, newBuf, used - _in, _in);
                     }
 
                     _out = 0;
@@ -2509,11 +2555,11 @@
             private byte[] _buf;
         }
 
-        private Locale _locale;
+        private final Locale _locale;
         private boolean _closed;
-        private OutputStreamImpl _outStreamImpl;
-        private TextSaver _textSaver;
-        private OutputStreamWriter _converter;
+        private final OutputStreamImpl _outStreamImpl;
+        private final TextSaver _textSaver;
+        private final OutputStreamWriter _converter;
     }
 
     static final class XmlInputStreamSaver extends Saver {
@@ -2521,7 +2567,8 @@
             super(c, options);
         }
 
-        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+        @Override
+        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
             assert c.isElem();
 
             for (iterateMappings(); hasMapping(); nextMapping()) {
@@ -2533,14 +2580,15 @@
             StartElementImpl.AttributeImpl namespaces = null;
 
             for (int i = 0; i < attrNames.size(); i++) {
-                XMLName attXMLName = computeName((QName) attrNames.get(i), this, true);
+                XMLName attXMLName = computeName(attrNames.get(i), this, true);
                 StartElementImpl.AttributeImpl attr =
-                        new StartElementImpl.NormalAttributeImpl(attXMLName, (String) attrValues.get(i));
+                    new StartElementImpl.NormalAttributeImpl(attXMLName, attrValues.get(i));
 
-                if (attributes == null)
+                if (attributes == null) {
                     attributes = attr;
-                else
+                } else {
                     lastAttr._next = attr;
+                }
 
                 lastAttr = attr;
             }
@@ -2552,12 +2600,13 @@
                 String uri = mappingUri();
 
                 StartElementImpl.AttributeImpl attr =
-                        new StartElementImpl.XmlnsAttributeImpl(prefix, uri);
+                    new StartElementImpl.XmlnsAttributeImpl(prefix, uri);
 
-                if (namespaces == null)
+                if (namespaces == null) {
                     namespaces = attr;
-                else
+                } else {
                     lastAttr._next = attr;
+                }
 
                 lastAttr = attr;
             }
@@ -2570,9 +2619,9 @@
         }
 
         protected void emitFinish(SaveCur c) {
-            if (c.isRoot())
+            if (c.isRoot()) {
                 enqueue(new EndDocumentImpl());
-            else {
+            } else {
                 XMLName xmlName = computeName(c.getName(), this, false);
                 enqueue(new EndElementImpl(xmlName));
             }
@@ -2597,8 +2646,9 @@
             String target = null;
             QName name = c.getName();
 
-            if (name != null)
+            if (name != null) {
                 target = name.getLocalPart();
+            }
 
             enqueue(new ProcessingInstructionImpl(target, c.getChars(), c._cchSrc, c._offSrc));
         }
@@ -2619,20 +2669,23 @@
             if (_out == null) {
                 enterLocale();
                 try {
-                    if (!process())
+                    if (!process()) {
                         return null;
+                    }
                 } finally {
                     exitLocale();
                 }
             }
 
-            if (_out == null)
+            if (_out == null) {
                 return null;
+            }
 
             XmlEventImpl e = _out;
 
-            if ((_out = _out._next) == null)
+            if ((_out = _out._next) == null) {
                 _in = null;
+            }
 
             return e;
         }
@@ -2659,9 +2712,9 @@
                 String prefix = mappingPrefix();
                 String uri = mappingUri();
 
-                if (prevPrefixUri == null)
+                if (prevPrefixUri == null) {
                     enqueue(new EndPrefixMappingImpl(prefix));
-                else {
+                } else {
                     enqueue(new ChangePrefixMappingImpl(prefix, uri, prevPrefixUri));
                 }
             }
@@ -2684,8 +2737,9 @@
                 prefix = name.getPrefix();
                 String mappedUri = saver.getNamespaceForPrefix(prefix);
 
-                if (mappedUri == null || !mappedUri.equals(uri))
+                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.
@@ -2694,8 +2748,9 @@
                 // _urpMap and _prefixMap.  This way, I would not have to look it up manually
                 // here
 
-                if (needsPrefix && prefix.length() == 0)
+                if (needsPrefix && prefix.length() == 0) {
                     prefix = saver.getNonDefaultUriMapping(uri);
+                }
 
             }
 
@@ -2728,7 +2783,7 @@
         }
 
         private static class StartDocumentImpl
-                extends XmlEventImpl implements StartDocument {
+            extends XmlEventImpl implements StartDocument {
             StartDocumentImpl(String systemID, String encoding, boolean isStandAlone, String version) {
                 super(XMLEvent.START_DOCUMENT);
                 _systemID = systemID;
@@ -2760,8 +2815,8 @@
         }
 
         private static class StartElementImpl
-                extends XmlEventImpl implements StartElement {
-            StartElementImpl(XMLName name, AttributeImpl attributes, AttributeImpl namespaces, Map prefixMap) {
+            extends XmlEventImpl implements StartElement {
+            StartElementImpl(XMLName name, AttributeImpl attributes, AttributeImpl namespaces, Map<String,String> prefixMap) {
                 super(XMLEvent.START_ELEMENT);
 
                 _name = name;
@@ -2792,23 +2847,24 @@
 
             public Attribute getAttributeByName(XMLName xmlName) {
                 for (AttributeImpl a = _attributes; a != null; a = a._next) {
-                    if (xmlName.equals(a.getName()))
+                    if (xmlName.equals(a.getName())) {
                         return a;
+                    }
                 }
 
                 return null;
             }
 
             public String getNamespaceUri(String prefix) {
-                return (String) _prefixMap.get(prefix == null ? "" : prefix);
+                return _prefixMap.get(prefix == null ? "" : prefix);
             }
 
-            public Map getNamespaceMap() {
+            public Map<String,String> getNamespaceMap() {
                 return _prefixMap;
             }
 
             private static class AttributeIteratorImpl
-                    implements AttributeIterator {
+                implements AttributeIterator {
                 AttributeIteratorImpl(AttributeImpl attributes, AttributeImpl namespaces) {
                     _attributes = attributes;
                     _namespaces = namespaces;
@@ -2848,10 +2904,11 @@
                     synchronized (monitor()) {
                         checkVersion();
 
-                        if (_attributes != null)
+                        if (_attributes != null) {
                             return _attributes;
-                        else if (_namespaces != null)
+                        } else if (_namespaces != null) {
                             return _namespaces;
+                        }
 
                         return null;
                     }
@@ -2861,14 +2918,15 @@
                     synchronized (monitor()) {
                         checkVersion();
 
-                        if (_attributes != null)
+                        if (_attributes != null) {
                             _attributes = _attributes._next;
-                        else if (_namespaces != null)
+                        } else if (_namespaces != null) {
                             _namespaces = _namespaces._next;
+                        }
                     }
                 }
 
-                private final void checkVersion() {
+                private void checkVersion() {
 //                    if (_version != _root.getVersion())
 //                        throw new IllegalStateException( "Document changed" );
                 }
@@ -2927,7 +2985,7 @@
                     return _uri;
                 }
 
-                private String _uri;
+                private final String _uri;
             }
 
             private static class NormalAttributeImpl extends AttributeImpl {
@@ -2940,18 +2998,18 @@
                     return _value;
                 }
 
-                private String _value; // If invalid in the store
+                private final String _value; // If invalid in the store
             }
 
-            private XMLName _name;
-            private Map _prefixMap;
+            private final XMLName _name;
+            private final Map<String,String> _prefixMap;
 
-            private AttributeImpl _attributes;
-            private AttributeImpl _namespaces;
+            private final AttributeImpl _attributes;
+            private final AttributeImpl _namespaces;
         }
 
         private static class StartPrefixMappingImpl
-                extends XmlEventImpl implements StartPrefixMapping {
+            extends XmlEventImpl implements StartPrefixMapping {
             StartPrefixMappingImpl(String prefix, String uri) {
                 super(XMLEvent.START_PREFIX_MAPPING);
 
@@ -2967,11 +3025,12 @@
                 return _prefix;
             }
 
-            private String _prefix, _uri;
+            private final String _prefix;
+            private final String _uri;
         }
 
         private static class ChangePrefixMappingImpl
-                extends XmlEventImpl implements ChangePrefixMapping {
+            extends XmlEventImpl implements ChangePrefixMapping {
             ChangePrefixMappingImpl(String prefix, String oldUri, String newUri) {
                 super(XMLEvent.CHANGE_PREFIX_MAPPING);
 
@@ -2992,11 +3051,13 @@
                 return _prefix;
             }
 
-            private String _oldUri, _newUri, _prefix;
+            private final String _oldUri;
+            private final String _newUri;
+            private final String _prefix;
         }
 
         private static class EndPrefixMappingImpl
-                extends XmlEventImpl implements EndPrefixMapping {
+            extends XmlEventImpl implements EndPrefixMapping {
             EndPrefixMappingImpl(String prefix) {
                 super(XMLEvent.END_PREFIX_MAPPING);
                 _prefix = prefix;
@@ -3006,11 +3067,11 @@
                 return _prefix;
             }
 
-            private String _prefix;
+            private final String _prefix;
         }
 
         private static class EndElementImpl
-                extends XmlEventImpl implements EndElement {
+            extends XmlEventImpl implements EndElement {
             EndElementImpl(XMLName name) {
                 super(XMLEvent.END_ELEMENT);
 
@@ -3025,18 +3086,18 @@
                 return _name;
             }
 
-            private XMLName _name;
+            private final XMLName _name;
         }
 
         private static class EndDocumentImpl
-                extends XmlEventImpl implements EndDocument {
+            extends XmlEventImpl implements EndDocument {
             EndDocumentImpl() {
                 super(XMLEvent.END_DOCUMENT);
             }
         }
 
         private static class TripletEventImpl
-                extends XmlEventImpl implements CharacterData {
+            extends XmlEventImpl implements CharacterData {
             TripletEventImpl(int eventType, Object obj, int cch, int off) {
                 super(eventType);
                 _obj = obj;
@@ -3052,27 +3113,27 @@
                 return _cch > 0;
             }
 
-            private Object _obj;
-            private int _cch;
-            private int _off;
+            private final Object _obj;
+            private final int _cch;
+            private final int _off;
         }
 
         private static class CharacterDataImpl
-                extends TripletEventImpl implements CharacterData {
+            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 {
+            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 {
+            extends TripletEventImpl implements ProcessingInstruction {
             ProcessingInstructionImpl(String target, Object obj, int cch, int off) {
                 super(XMLEvent.PROCESSING_INSTRUCTION, obj, cch, off);
                 _target = target;
@@ -3086,7 +3147,7 @@
                 return getContent();
             }
 
-            private String _target;
+            private final String _target;
         }
 
         private XmlEventImpl _in, _out;
@@ -3095,7 +3156,7 @@
     static final class XmlInputStreamImpl extends GenericXmlInputStream {
         XmlInputStreamImpl(Cur cur, XmlOptions options) {
             _xmlInputStreamSaver =
-                    new XmlInputStreamSaver(cur, options);
+                new XmlInputStreamSaver(cur, options);
 
             // Make the saver grind away just a bit to throw any exceptions
             // related to the inability to create a stream on this xml
@@ -3103,29 +3164,29 @@
             _xmlInputStreamSaver.process();
         }
 
-        protected XMLEvent nextEvent() throws XMLStreamException {
+        protected XMLEvent nextEvent() {
             return _xmlInputStreamSaver.dequeue();
         }
 
-        private XmlInputStreamSaver _xmlInputStreamSaver;
+        private final XmlInputStreamSaver _xmlInputStreamSaver;
     }
 
     static final class SaxSaver extends Saver {
         SaxSaver(Cur c, XmlOptions options, ContentHandler ch, LexicalHandler lh)
-                throws SAXException {
+            throws SAXException {
             super(c, options);
 
             _contentHandler = ch;
             _lexicalHandler = lh;
 
             _attributes = new AttributesImpl();
-            _nsAsAttrs = !options.hasOption(XmlOptions.SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES);
+            _nsAsAttrs = !options.isSaveSaxNoNSDeclsInAttributes();
 
             _contentHandler.startDocument();
 
             try {
-                while (process())
-                    ;
+                //noinspection StatementWithEmptyBody
+                while (process()) { }
             } catch (SaverSAXException e) {
                 throw e._saxException;
             }
@@ -3133,7 +3194,7 @@
             _contentHandler.endDocument();
         }
 
-        private class SaverSAXException extends RuntimeException {
+        private static class SaverSAXException extends RuntimeException {
             SaverSAXException(SAXException e) {
                 _saxException = e;
             }
@@ -3145,13 +3206,15 @@
             String uri = name.getNamespaceURI();
             String local = name.getLocalPart();
 
-            if (uri.length() == 0)
+            if (uri.length() == 0) {
                 return local;
+            }
 
             String prefix = getUriMapping(uri);
 
-            if (prefix.length() == 0)
+            if (prefix.length() == 0) {
                 return local;
+            }
 
             return prefix + ":" + local;
         }
@@ -3167,37 +3230,42 @@
                     throw new SaverSAXException(e);
                 }
 
-                if (_nsAsAttrs)
-                    if (prefix == null || prefix.length() == 0)
+                if (_nsAsAttrs) {
+                    if (prefix == null || prefix.length() == 0) {
                         _attributes.addAttribute("http://www.w3.org/2000/xmlns/", "xmlns", "xmlns", "CDATA", uri);
-                    else
+                    } else {
                         _attributes.addAttribute("http://www.w3.org/2000/xmlns/", prefix, "xmlns:" + prefix, "CDATA", uri);
+                    }
+                }
             }
         }
 
-        protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
+        @Override
+        protected boolean emitElement(SaveCur c, List<QName> attrNames, List<String> attrValues) {
             _attributes.clear();
 
-            if (saveNamespacesFirst())
+            if (saveNamespacesFirst()) {
                 emitNamespacesHelper();
-
-            for (int i = 0; i < attrNames.size(); i++) {
-                QName name = (QName) attrNames.get(i);
-
-                _attributes.addAttribute(
-                        name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name),
-                        "CDATA", (String) attrValues.get(i));
             }
 
-            if (!saveNamespacesFirst())
+            for (int i = 0; i < attrNames.size(); i++) {
+                QName name = attrNames.get(i);
+
+                _attributes.addAttribute(
+                    name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name),
+                    "CDATA", attrValues.get(i));
+            }
+
+            if (!saveNamespacesFirst()) {
                 emitNamespacesHelper();
+            }
 
             QName elemName = c.getName();
 
             try {
                 _contentHandler.startElement(
-                        elemName.getNamespaceURI(), elemName.getLocalPart(),
-                        getPrefixedName(elemName), _attributes);
+                    elemName.getNamespaceURI(), elemName.getLocalPart(),
+                    getPrefixedName(elemName), _attributes);
             } catch (SAXException e) {
                 throw new SaverSAXException(e);
             }
@@ -3210,10 +3278,11 @@
 
             try {
                 _contentHandler.endElement(
-                        name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name));
+                    name.getNamespaceURI(), name.getLocalPart(), getPrefixedName(name));
 
-                for (iterateMappings(); hasMapping(); nextMapping())
+                for (iterateMappings(); hasMapping(); nextMapping()) {
                     _contentHandler.endPrefixMapping(mappingPrefix());
+                }
             } catch (SAXException e) {
                 throw new SaverSAXException(e);
             }
@@ -3229,8 +3298,9 @@
                     // Pray the user does not modify the buffer ....
                     _contentHandler.characters((char[]) src, c._offSrc, c._cchSrc);
                 } else {
-                    if (_buf == null)
+                    if (_buf == null) {
                         _buf = new char[1024];
+                    }
 
                     while (c._cchSrc > 0) {
                         int cch = java.lang.Math.min(_buf.length, c._cchSrc);
@@ -3255,17 +3325,18 @@
                 c.next();
 
                 try {
-                    if (!c.isText())
+                    if (!c.isText()) {
                         _lexicalHandler.comment(null, 0, 0);
-                    else {
+                    } else {
                         Object src = c.getChars();
 
                         if (src instanceof char[]) {
                             // Pray the user does not modify the buffer ....
                             _lexicalHandler.comment((char[]) src, c._offSrc, c._cchSrc);
                         } else {
-                            if (_buf == null || _buf.length < c._cchSrc)
+                            if (_buf == null || _buf.length < c._cchSrc) {
                                 _buf = new char[java.lang.Math.max(1024, c._cchSrc)];
+                            }
 
                             CharUtil.getChars(_buf, 0, src, c._offSrc, c._cchSrc);
 
@@ -3281,8 +3352,6 @@
         }
 
         protected void emitProcinst(SaveCur c) {
-            String target = c.getName().getLocalPart();
-
             c.push();
 
             c.next();
@@ -3315,13 +3384,13 @@
         protected void emitEndDoc(SaveCur c) {
         }
 
-        private ContentHandler _contentHandler;
-        private LexicalHandler _lexicalHandler;
+        private final ContentHandler _contentHandler;
+        private final LexicalHandler _lexicalHandler;
 
-        private AttributesImpl _attributes;
+        private final AttributesImpl _attributes;
 
         private char[] _buf;
-        private boolean _nsAsAttrs;
+        private final boolean _nsAsAttrs;
     }
 
     //
@@ -3365,6 +3434,7 @@
             return kind() == ATTR && !isXmlns();
         }
 
+        @SuppressWarnings("unused")
         final boolean skip() {
             toEnd();
             return next();
@@ -3404,7 +3474,7 @@
 
         abstract Object getChars();
 
-        abstract List getAncestorNamespaces();
+        abstract List<String> getAncestorNamespaces();
 
         abstract XmlDocumentProperties getDocProps();
 
@@ -3487,7 +3557,7 @@
             _cur.pop();
         }
 
-        List getAncestorNamespaces() {
+        List<String> getAncestorNamespaces() {
             return null;
         }
 
@@ -3570,11 +3640,13 @@
         }
 
         boolean next() {
-            if (!_cur.next())
+            if (!_cur.next()) {
                 return false;
+            }
 
-            if (!filter())
+            if (!filter()) {
                 return true;
+            }
 
             assert !isRoot() && !isText() && !isAttr();
 
@@ -3591,7 +3663,7 @@
             _cur.pop();
         }
 
-        List getAncestorNamespaces() {
+        List<String> getAncestorNamespaces() {
             return _cur.getAncestorNamespaces();
         }
 
@@ -3622,7 +3694,7 @@
             return kind() == PROCINST && getName().getLocalPart().equals(_piTarget);
         }
 
-        private String _piTarget;
+        private final String _piTarget;
     }
 
     private static final class FragSaveCur extends SaveCur {
@@ -3643,12 +3715,12 @@
             start.pop();
         }
 
-        List getAncestorNamespaces() {
+        List<String> getAncestorNamespaces() {
             return _ancestorNamespaces;
         }
 
         private void computeAncestorNamespaces(Cur c) {
-            _ancestorNamespaces = new ArrayList();
+            _ancestorNamespaces = new ArrayList<>();
 
             while (c.toParentRaw()) {
                 if (c.toFirstAttr()) {
@@ -3738,8 +3810,9 @@
                 push();
                 next();
 
-                if (!isText() && !isFinish())
+                if (!isText() && !isFinish()) {
                     hasChildren = true;
+                }
 
                 pop();
             }
@@ -3754,8 +3827,9 @@
                 push();
                 next();
 
-                if (isText())
+                if (isText()) {
                     hasText = true;
+                }
 
                 pop();
             }
@@ -3786,18 +3860,19 @@
                 }
 
                 case ELEM_START: {
-                    if (_saveAttr)
+                    if (_saveAttr) {
                         _state = ELEM_END;
-                    else {
+                    } else {
                         if (_cur.isAttr()) {
                             _cur.toParent();
                             _cur.next();
                         }
 
-                        if (_cur.isSamePos(_end))
+                        if (_cur.isSamePos(_end)) {
                             _state = ELEM_END;
-                        else
+                        } else {
                             _state = CUR;
+                        }
                     }
 
                     break;
@@ -3808,8 +3883,9 @@
 
                     _cur.next();
 
-                    if (_cur.isSamePos(_end))
+                    if (_cur.isSamePos(_end)) {
                         _state = _elem == null ? ROOT_END : ELEM_END;
+                    }
 
                     break;
                 }
@@ -3855,8 +3931,9 @@
 
             assert _state == ELEM_START;
 
-            if (!_cur.isAttr())
+            if (!_cur.isAttr()) {
                 return false;
+            }
 
             _state = CUR;
 
@@ -3900,11 +3977,11 @@
         private Cur _cur;
         private Cur _end;
 
-        private ArrayList _ancestorNamespaces;
+        private ArrayList<String> _ancestorNamespaces;
 
-        private QName _elem;
+        private final QName _elem;
 
-        private boolean _saveAttr;
+        private final boolean _saveAttr;
 
         private static final int ROOT_START = 1;
         private static final int ELEM_START = 2;
@@ -3921,7 +3998,7 @@
     private static final class PrettySaveCur extends SaveCur {
         PrettySaveCur(SaveCur c, XmlOptions options) {
             _sb = new StringBuffer();
-            _stack = new ArrayList();
+            _stack = new ArrayList<>();
 
             _cur = c;
 
@@ -3930,21 +4007,17 @@
             _prettyIndent = 2;
 
             if (options.hasOption(XmlOptions.SAVE_PRETTY_PRINT_INDENT)) {
-                _prettyIndent =
-                        ((Integer) options.get(XmlOptions.SAVE_PRETTY_PRINT_INDENT)).intValue();
+                _prettyIndent = options.getSavePrettyPrintIndent();
             }
 
             if (options.hasOption(XmlOptions.SAVE_PRETTY_PRINT_OFFSET)) {
-                _prettyOffset =
-                        ((Integer) options.get(XmlOptions.SAVE_PRETTY_PRINT_OFFSET)).intValue();
+                _prettyOffset = options.getSavePrettyPrintOffset();
             }
 
-            if (options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS)) {
-                _useCDataBookmarks = true;
-            }
+            _useCDataBookmarks = options.isUseCDataBookmarks();
         }
 
-        List getAncestorNamespaces() {
+        List<String> getAncestorNamespaces() {
             return _cur.getAncestorNamespaces();
         }
 
@@ -3972,21 +4045,21 @@
         }
 
         boolean isXmlns() {
-            return _txt == null ? _cur.isXmlns() : false;
+            return _txt == null && _cur.isXmlns();
         }
 
         boolean hasChildren() {
-            return _txt == null ? _cur.hasChildren() : false;
+            return _txt == null && _cur.hasChildren();
         }
 
         boolean hasText() {
-            return _txt == null ? _cur.hasText() : false;
+            return _txt == null && _cur.hasText();
         }
 
         // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled
         boolean isTextCData() {
             return _txt == null ? (_useCDataBookmarks && _cur.isTextCData())
-                    : _isTextCData;
+                : _isTextCData;
         }
 
         boolean toFirstAttr() {
@@ -4008,8 +4081,9 @@
             assert _txt == null;
             _cur.toEnd();
 
-            if (_cur.kind() == -ELEM)
+            if (_cur.kind() == -ELEM) {
                 _depth--;
+            }
         }
 
         boolean next() {
@@ -4022,10 +4096,11 @@
                 _isTextCData = false;
                 k = _cur.kind();
             } else {
-                int prevKind = k = _cur.kind();
+                int prevKind = _cur.kind();
 
-                if (!_cur.next())
+                if (!_cur.next()) {
                     return false;
+                }
 
                 _sb.delete(0, _sb.length());
 
@@ -4048,15 +4123,16 @@
                 // Check for non leaf, _prettyIndent < 0 means that the save is all on one line
 
                 if (_prettyIndent >= 0 &&
-                        prevKind != COMMENT && prevKind != PROCINST && (prevKind != ELEM || k != -ELEM)) {
+                    prevKind != COMMENT && prevKind != PROCINST && (prevKind != ELEM || k != -ELEM)) {
                     if (_sb.length() > 0) {
                         _sb.insert(0, _newLine);
                         spaces(_sb, _newLine.length(), _prettyOffset + _prettyIndent * _depth);
                     }
 
                     if (k != -ROOT) {
-                        if (prevKind != ROOT)
+                        if (prevKind != ROOT) {
                             _sb.append(_newLine);
+                        }
 
                         int d = k < 0 ? _depth - 1 : _depth;
                         spaces(_sb, _sb.length(), _prettyOffset + _prettyIndent * d);
@@ -4069,10 +4145,11 @@
                 }
             }
 
-            if (k == ELEM)
+            if (k == ELEM) {
                 _depth++;
-            else if (k == -ELEM)
+            } else if (k == -ELEM) {
                 _depth--;
+            }
 
             return true;
         }
@@ -4080,13 +4157,13 @@
         void push() {
             _cur.push();
             _stack.add(_txt);
-            _stack.add(new Integer(_depth));
+            _stack.add(_depth);
             _isTextCData = false;
         }
 
         void pop() {
             _cur.pop();
-            _depth = ((Integer) _stack.remove(_stack.size() - 1)).intValue();
+            _depth = (Integer) _stack.remove(_stack.size() - 1);
             _txt = (String) _stack.remove(_stack.size() - 1);
             _isTextCData = false;
         }
@@ -4111,69 +4188,43 @@
         }
 
         static void spaces(StringBuffer sb, int offset, int count) {
-            while (count-- > 0)
+            while (count-- > 0) {
                 sb.insert(offset, ' ');
+            }
         }
 
         static void trim(StringBuffer sb) {
             int i;
 
-            for (i = 0; i < sb.length(); i++)
-                if (!CharUtil.isWhiteSpace(sb.charAt(i)))
+            for (i = 0; i < sb.length(); i++) {
+                if (!CharUtil.isWhiteSpace(sb.charAt(i))) {
                     break;
+                }
+            }
 
             sb.delete(0, i);
 
-            for (i = sb.length(); i > 0; i--)
-                if (!CharUtil.isWhiteSpace(sb.charAt(i - 1)))
+            for (i = sb.length(); i > 0; i--) {
+                if (!CharUtil.isWhiteSpace(sb.charAt(i - 1))) {
                     break;
+                }
+            }
 
             sb.delete(i, sb.length());
         }
 
-        private SaveCur _cur;
+        private final SaveCur _cur;
 
         private int _prettyIndent;
         private int _prettyOffset;
 
         private String _txt;
-        private StringBuffer _sb;
+        private final StringBuffer _sb;
 
         private int _depth;
 
-        private ArrayList _stack;
+        private final ArrayList<Object> _stack;
         private boolean _isTextCData = false;
-        private boolean _useCDataBookmarks = false;
+        private final boolean _useCDataBookmarks;
     }
-
-
-    //
-    //
-    //
-
-    private final Locale _locale;
-    private final long _version;
-
-    private SaveCur _cur;
-
-    private List _ancestorNamespaces;
-    private Map _suggestedPrefixes;
-    protected XmlOptionCharEscapeMap _replaceChar;
-    private boolean _useDefaultNamespace;
-    private Map _preComputedNamespaces;
-    private boolean _saveNamespacesFirst;
-
-    private ArrayList _attrNames;
-    private ArrayList _attrValues;
-
-    private ArrayList _namespaceStack;
-    private int _currentMapping;
-    private HashMap _uriMap;
-    private HashMap _prefixMap;
-    private String _initialDefaultUri;
-
-    static final String _newLine =
-            SystemProperties.getProperty("line.separator") == null
-                    ? "\n"
-                    : SystemProperties.getProperty("line.separator");
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
index b9bb191..83c03c6 100644
--- a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
+++ b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
@@ -33,69 +33,119 @@
 
 // DOM Level 3
 
-abstract class Xobj implements TypeStore
-{
-    static final int TEXT     = Cur.TEXT;
-    static final int ROOT     = Cur.ROOT;
-    static final int ELEM     = Cur.ELEM;
-    static final int ATTR     = Cur.ATTR;
-    static final int COMMENT  = Cur.COMMENT;
+abstract class Xobj implements TypeStore {
+    static final int TEXT = Cur.TEXT;
+    static final int ROOT = Cur.ROOT;
+    static final int ELEM = Cur.ELEM;
+    static final int ATTR = Cur.ATTR;
+    static final int COMMENT = Cur.COMMENT;
     static final int PROCINST = Cur.PROCINST;
 
     static final int END_POS = Cur.END_POS;
-    static final int NO_POS  = Cur.NO_POS;
+    static final int NO_POS = Cur.NO_POS;
 
-    Xobj ( Locale l, int kind, int domType )
-    {
+    Xobj(Locale l, int kind, int domType) {
         assert kind == ROOT || kind == ELEM || kind == ATTR || kind == COMMENT || kind == PROCINST;
 
         _locale = l;
         _bits = (domType << 4) + kind;
     }
 
-    final boolean entered ( ) { return _locale.entered(); }
+    final boolean entered() {
+        return _locale.entered();
+    }
 
-    final int kind    ( ) { return _bits & 0xF; }
-    final int domType ( ) { return (_bits & 0xF0) >> 4; }
+    final int kind() {
+        return _bits & 0xF;
+    }
 
-    final boolean isRoot      ( ) { return kind() == ROOT; }
-    final boolean isAttr      ( ) { return kind() == ATTR; }
-    final boolean isElem      ( ) { return kind() == ELEM; }
-    final boolean isProcinst  ( ) { return kind() == PROCINST; }
-    final boolean isComment   ( ) { return kind() == COMMENT; }
-    final boolean isContainer ( ) { return Cur.kindIsContainer( kind() ); }
-    final boolean isUserNode  ( ) { int k = kind(); return k == ELEM || k == ROOT || (k == ATTR && !isXmlns()); }
+    final int domType() {
+        return (_bits & 0xF0) >> 4;
+    }
 
-    final boolean isNormalAttr ( ) { return isAttr() && !Locale.isXmlns( _name ); }
-    final boolean isXmlns      ( ) { return isAttr() &&  Locale.isXmlns( _name ); }
+    final boolean isRoot() {
+        return kind() == ROOT;
+    }
 
-    final int cchValue ( ) { return _cchValue; }
-    final int cchAfter ( ) { return _cchAfter; }
+    final boolean isAttr() {
+        return kind() == ATTR;
+    }
 
-    final int posAfter ( ) { return 2 + _cchValue; }
-    final int posMax   ( ) { return 2 + _cchValue + _cchAfter; }
+    final boolean isElem() {
+        return kind() == ELEM;
+    }
 
-    final String getXmlnsPrefix ( ) { return Locale.xmlnsPrefix( _name ); }
-    final String getXmlnsUri    ( ) { return getValueAsString(); }
+    final boolean isProcinst() {
+        return kind() == PROCINST;
+    }
 
-    final boolean hasTextEnsureOccupancy ( )
-    {
+    final boolean isComment() {
+        return kind() == COMMENT;
+    }
+
+    final boolean isContainer() {
+        return Cur.kindIsContainer(kind());
+    }
+
+    final boolean isUserNode() {
+        int k = kind();
+        return k == ELEM || k == ROOT || (k == ATTR && !isXmlns());
+    }
+
+    final boolean isNormalAttr() {
+        return isAttr() && !Locale.isXmlns(_name);
+    }
+
+    final boolean isXmlns() {
+        return isAttr() && Locale.isXmlns(_name);
+    }
+
+    final int cchValue() {
+        return _cchValue;
+    }
+
+    final int cchAfter() {
+        return _cchAfter;
+    }
+
+    final int posAfter() {
+        return 2 + _cchValue;
+    }
+
+    final int posMax() {
+        return 2 + _cchValue + _cchAfter;
+    }
+
+    final String getXmlnsPrefix() {
+        return Locale.xmlnsPrefix(_name);
+    }
+
+    final String getXmlnsUri() {
+        return getValueAsString();
+    }
+
+    final boolean hasTextEnsureOccupancy() {
         ensureOccupancy();
         return hasTextNoEnsureOccupancy();
     }
 
-    final boolean hasTextNoEnsureOccupancy ( )
-    {
-        if (_cchValue > 0)
+    final boolean hasTextNoEnsureOccupancy() {
+        if (_cchValue > 0) {
             return true;
+        }
 
         Xobj lastAttr = lastAttr();
 
         return lastAttr != null && lastAttr._cchAfter > 0;
     }
 
-    final boolean hasAttrs    ( ) { return _firstChild != null &&  _firstChild.isAttr(); }
-    final boolean hasChildren ( ) { return _lastChild  != null && !_lastChild .isAttr(); }
+    final boolean hasAttrs() {
+        return _firstChild != null && _firstChild.isAttr();
+    }
+
+    final boolean hasChildren() {
+        return _lastChild != null && !_lastChild.isAttr();
+    }
 
 
     /**
@@ -103,14 +153,14 @@
      * when underlying obj is an Xobj
      *
      * @return 0 or 1 dom children; val 2 indicates that DomImpl needs to
-     *         compute the result itself
+     * compute the result itself
      */
-    final protected int getDomZeroOneChildren()
-    {
+    final protected int getDomZeroOneChildren() {
         if (_firstChild == null &&
             _srcValue == null &&
-            _charNodesValue == null)
+            _charNodesValue == null) {
             return 0;
+        }
 
         if (_lastChild != null &&
             _lastChild.isAttr() &&
@@ -118,8 +168,9 @@
             _lastChild._srcAfter == null &&
             _srcValue == null &&
             _charNodesValue == null
-        )
+        ) {
             return 0;
+        }
 
         if (_firstChild == _lastChild &&
             _firstChild != null &&
@@ -127,16 +178,18 @@
             _srcValue == null &&
             _charNodesValue == null &&
             _firstChild._srcAfter == null
-        )
+        ) {
             return 1;
+        }
 
         if (_firstChild == null &&
             _srcValue != null &&
-           ( _charNodesValue == null ||
-            (_charNodesValue._next == null &&
-            _charNodesValue._cch == _cchValue))
-        )
+            (_charNodesValue == null ||
+             (_charNodesValue._next == null &&
+              _charNodesValue._cch == _cchValue))
+        ) {
             return 1;
+        }
         //single elem after an attr
         Xobj lastAttr = lastAttr();
         Xobj node = lastAttr == null ?
@@ -145,8 +198,9 @@
             lastAttr._srcAfter == null &&
             node != null &&
             node._srcAfter == null &&
-            node._nextSibling == null)
+            node._nextSibling == null) {
             return 1;
+        }
 
         return 2;
     }
@@ -157,19 +211,18 @@
      *
      * @return
      */
-    final protected boolean isFirstChildPtrDomUsable()
-    {
+    final protected boolean isFirstChildPtrDomUsable() {
         if (_firstChild == null &&
             _srcValue == null &&
-            _charNodesValue == null)
+            _charNodesValue == null) {
             return true;
+        }
 
         if (_firstChild != null &&
             !_firstChild.isAttr() &&
             _srcValue == null &&
-            _charNodesValue == null)
-        {
-            assert (_firstChild instanceof NodeXobj):
+            _charNodesValue == null) {
+            assert (_firstChild instanceof NodeXobj) :
                 "wrong node type";
             return true;
         }
@@ -178,42 +231,44 @@
 
     /**
      * can one use the _nextSibling pointer to retrieve
-     *  the next DOM sibling
+     * the next DOM sibling
+     *
      * @return
      */
-    final protected boolean isNextSiblingPtrDomUsable()
-    {
+    final protected boolean isNextSiblingPtrDomUsable() {
         if (_charNodesAfter == null &&
-            _srcAfter == null)
-        {
+            _srcAfter == null) {
             assert (_nextSibling == null ||
-                _nextSibling instanceof NodeXobj):
+                    _nextSibling instanceof NodeXobj) :
                 "wrong node type";
             return true;
         }
         return false;
     }
+
     /**
      * can one use the _charNodesValue pointer to retrieve
      * the next DOM sibling
      *
      * @return
      */
-    final protected boolean isExistingCharNodesValueUsable()
-    {
-        if (_srcValue == null) return false;
+    final protected boolean isExistingCharNodesValueUsable() {
+        if (_srcValue == null) {
+            return false;
+        }
         if (_charNodesValue != null && _charNodesValue._next == null
-            && _charNodesValue._cch == _cchValue)
+            && _charNodesValue._cch == _cchValue) {
             return true;
-       return false;
+        }
+        return false;
     }
-      final protected boolean isCharNodesValueUsable()
-      {
-          return isExistingCharNodesValueUsable() ||
-              (_charNodesValue =
-              Cur.updateCharNodes(_locale, this,
-                  _charNodesValue, _cchValue)) != null;
-      }
+
+    final protected boolean isCharNodesValueUsable() {
+        return isExistingCharNodesValueUsable() ||
+               (_charNodesValue =
+                   Cur.updateCharNodes(_locale, this,
+                       _charNodesValue, _cchValue)) != null;
+    }
 
     /**
      * can one use the _charNodesAfter pointer to retrieve
@@ -221,41 +276,44 @@
      *
      * @return
      */
-    final protected boolean isCharNodesAfterUsable()
-    {
-        if (_srcAfter == null) return false;
+    final protected boolean isCharNodesAfterUsable() {
+        if (_srcAfter == null) {
+            return false;
+        }
         if (_charNodesAfter != null && _charNodesAfter._next == null
-            && _charNodesAfter._cch == this._cchAfter)
+            && _charNodesAfter._cch == this._cchAfter) {
             return true;
+        }
         return (_charNodesAfter =
             Cur.updateCharNodes(_locale, this,
                 _charNodesAfter, _cchAfter)) != null;
     }
 
 
-    final Xobj lastAttr ( )
-    {
-        if (_firstChild == null || !_firstChild.isAttr())
+    final Xobj lastAttr() {
+        if (_firstChild == null || !_firstChild.isAttr()) {
             return null;
+        }
 
         Xobj lastAttr = _firstChild;
 
-        while ( lastAttr._nextSibling != null && lastAttr._nextSibling.isAttr() )
+        while (lastAttr._nextSibling != null && lastAttr._nextSibling.isAttr()) {
             lastAttr = lastAttr._nextSibling;
+        }
 
         return lastAttr;
     }
 
-    abstract Dom getDom ( );
+    abstract Dom getDom();
 
-    abstract Xobj newNode ( Locale l );
+    abstract Xobj newNode(Locale l);
 
-    final int cchLeft ( int p )
-    {
-        if (isRoot() && p == 0)
+    final int cchLeft(int p) {
+        if (isRoot() && p == 0) {
             return 0;
+        }
 
-        Xobj x = getDenormal( p );
+        Xobj x = getDenormal(p);
 
         p = posTemp();
         int pa = x.posAfter();
@@ -263,12 +321,12 @@
         return p - (p < pa ? 1 : pa);
     }
 
-    final int cchRight ( int p )
-    {
+    final int cchRight(int p) {
         assert p < posMax();
 
-        if (p <= 0)
+        if (p <= 0) {
             return 0;
+        }
 
         int pa = posAfter();
 
@@ -279,22 +337,41 @@
     // Dom interface
     //
 
-    public final Locale locale   ( ) { return _locale;   }
-    public final int    nodeType ( ) { return domType(); }
-    public final QName  getQName ( ) { return _name;     }
+    public final Locale locale() {
+        return _locale;
+    }
 
-    public final Cur tempCur ( ) { Cur c = _locale.tempCur(); c.moveTo( this ); return c; }
+    public final int nodeType() {
+        return domType();
+    }
 
-    public void dump ( PrintStream o, Object ref ) { Cur.dump( o, (Xobj) this, ref ); }
-    public void dump ( PrintStream o ) { Cur.dump( o, this, this ); }
-    public void dump ( ) { dump( System.out ); }
+    public final QName getQName() {
+        return _name;
+    }
+
+    public final Cur tempCur() {
+        Cur c = _locale.tempCur();
+        c.moveTo(this);
+        return c;
+    }
+
+    public void dump(PrintStream o, Object ref) {
+        Cur.dump(o, (Xobj) this, ref);
+    }
+
+    public void dump(PrintStream o) {
+        Cur.dump(o, this, this);
+    }
+
+    public void dump() {
+        dump(System.out);
+    }
 
     //
     //
     //
 
-    final Cur getEmbedded ( )
-    {
+    final Cur getEmbedded() {
         _locale.embedCurs();
 
         return _embedded;
@@ -302,110 +379,107 @@
 
     // Incoming p must be at text (implicitly denormalized)
 
-    final boolean inChars ( int p, Xobj xIn, int pIn, int cch, boolean includeEnd )
-    {
+    final boolean inChars(int p, Xobj xIn, int pIn, int cch, boolean includeEnd) {
         assert p > 0 && p < posMax() && p != posAfter() - 1 && cch > 0;
-        assert xIn.isNormal( pIn );
+        assert xIn.isNormal(pIn);
 
         // No need to denormalize "in" if the right hand side is excluded.  Denormalizing deals
         // with the case where p is END_POS.
 
         int offset;
 
-        if (includeEnd)
-        {
+        if (includeEnd) {
             // Can't denormalize at the beginning of the document
 
-            if (xIn.isRoot() && pIn == 0)
+            if (xIn.isRoot() && pIn == 0) {
                 return false;
+            }
 
-            xIn = xIn.getDenormal( pIn );
+            xIn = xIn.getDenormal(pIn);
             pIn = xIn.posTemp();
 
             offset = 1;
-        }
-        else
+        } else {
             offset = 0;
+        }
 
-        return xIn == this && pIn >= p && pIn < p + (cch < 0 ? cchRight( p ) : cch) + offset;
+        return xIn == this && pIn >= p && pIn < p + (cch < 0 ? cchRight(p) : cch) + offset;
     }
 
     // Is x/p just after the end of this
 
-    final boolean isJustAfterEnd ( Xobj x, int p )
-    {
-        assert x.isNormal( p );
+    final boolean isJustAfterEnd(Xobj x, int p) {
+        assert x.isNormal(p);
 
         // Get denormalize at the beginning of the doc
 
-        if (x.isRoot() && p == 0)
+        if (x.isRoot() && p == 0) {
             return false;
+        }
 
         return
             x == this
                 ? p == posAfter()
-                : x.getDenormal( p ) == this && x.posTemp() == posAfter();
+                : x.getDenormal(p) == this && x.posTemp() == posAfter();
     }
 
-    final boolean isInSameTree ( Xobj x )
-    {
-        if (_locale != x._locale)
+    final boolean isInSameTree(Xobj x) {
+        if (_locale != x._locale) {
             return false;
+        }
 
-        for ( Xobj y = this ; ; y = y._parent )
-        {
-            if (y == x)
+        for (Xobj y = this; ; y = y._parent) {
+            if (y == x) {
                 return true;
+            }
 
-            if (y._parent == null)
-            {
-                for ( ; ; x = x._parent )
-                {
-                    if (x == this)
+            if (y._parent == null) {
+                for (; ; x = x._parent) {
+                    if (x == this) {
                         return true;
+                    }
 
-                    if (x._parent == null)
+                    if (x._parent == null) {
                         return x == y;
+                    }
                 }
             }
         }
     }
 
-    final boolean contains ( Cur c )
-    {
+    final boolean contains(Cur c) {
         assert c.isNormal();
 
-        return contains( c._xobj, c._pos );
+        return contains(c._xobj, c._pos);
     }
 
-    final boolean contains ( Xobj x, int p )
-    {
-        assert x.isNormal( p );
+    final boolean contains(Xobj x, int p) {
+        assert x.isNormal(p);
 
-        if (this == x)
+        if (this == x) {
             return p == END_POS || (p > 0 && p < posAfter());
+        }
 
-        if (_firstChild == null)
+        if (_firstChild == null) {
             return false;
+        }
 
-        for ( ; x != null ; x = x._parent )
-            if (x == this)
+        for (; x != null; x = x._parent) {
+            if (x == this) {
                 return true;
+            }
+        }
 
         return false;
     }
 
-    final Bookmark setBookmark ( int p, Object key, Object value )
-    {
-        assert isNormal( p );
+    final Bookmark setBookmark(int p, Object key, Object value) {
+        assert isNormal(p);
 
-        for ( Bookmark b = _bookmarks ; b != null ; b = b._next )
-        {
-            if (p == b._pos && key == b._key)
-            {
-                if (value == null)
-                {
-                    _bookmarks = b.listRemove( _bookmarks );
+        for (Bookmark b = _bookmarks; b != null; b = b._next) {
+            if (p == b._pos && key == b._key) {
+                if (value == null) {
+                    _bookmarks = b.listRemove(_bookmarks);
                     return null;
                 }
 
@@ -415,66 +489,68 @@
             }
         }
 
-        if (value == null)
+        if (value == null) {
             return null;
+        }
 
         Bookmark b = new Bookmark();
 
-        b._xobj  = this;
-        b._pos   = p;
-        b._key   = key;
+        b._xobj = this;
+        b._pos = p;
+        b._key = key;
         b._value = value;
 
-        _bookmarks = b.listInsert( _bookmarks );
+        _bookmarks = b.listInsert(_bookmarks);
 
         return b;
     }
 
-    final boolean hasBookmark(Object key, int pos)
-    {
-        for ( Bookmark b = _bookmarks ; b != null ; b = b._next )
-            if ( b._pos == pos && key == b._key )
-            {
+    final boolean hasBookmark(Object key, int pos) {
+        for (Bookmark b = _bookmarks; b != null; b = b._next) {
+            if (b._pos == pos && key == b._key) {
                 //System.out.println("hasCDataBookmark  pos: " + pos + " xobj: " + getQName() + " b._pos: " + _bookmarks._pos);
                 return true;
             }
+        }
 
         return false;
     }
 
-    final Xobj findXmlnsForPrefix ( String prefix )
-    {
+    final Xobj findXmlnsForPrefix(String prefix) {
         assert isContainer() && prefix != null;
 
-        for ( Xobj c = this ; c != null ; c = c._parent )
-            for ( Xobj a = c.firstAttr() ; a != null ; a = a.nextAttr() )
-                if (a.isXmlns() && a.getXmlnsPrefix().equals( prefix ))
+        for (Xobj c = this; c != null; c = c._parent) {
+            for (Xobj a = c.firstAttr(); a != null; a = a.nextAttr()) {
+                if (a.isXmlns() && a.getXmlnsPrefix().equals(prefix)) {
                     return a;
+                }
+            }
+        }
 
         return null;
     }
 
-    final boolean removeAttr ( QName name )
-    {
+    final boolean removeAttr(QName name) {
         assert isContainer();
 
-        Xobj a = getAttr( name );
+        Xobj a = getAttr(name);
 
-        if (a == null)
+        if (a == null) {
             return false;
+        }
 
         Cur c = a.tempCur();
 
-        for ( ; ; )
-        {
-            c.moveNode( null );
+        for (; ; ) {
+            c.moveNode(null);
 
-            a = getAttr( name );
+            a = getAttr(name);
 
-            if (a == null)
+            if (a == null) {
                 break;
+            }
 
-            c.moveTo( a );
+            c.moveTo(a);
         }
 
         c.release();
@@ -482,21 +558,19 @@
         return true;
     }
 
-    final Xobj setAttr ( QName name, String value )
-    {
+    final Xobj setAttr(QName name, String value) {
         assert isContainer();
 
         Cur c = tempCur();
 
-        if (c.toAttr( name ))
+        if (c.toAttr(name)) {
             c.removeFollowingAttrs();
-        else
-        {
+        } else {
             c.next();
-            c.createAttr( name );
+            c.createAttr(name);
         }
 
-        c.setValue( value );
+        c.setValue(value);
 
         Xobj a = c._xobj;
 
@@ -505,36 +579,33 @@
         return a;
     }
 
-    final void setName ( QName newName )
-    {
+    final void setName(QName newName) {
         assert isAttr() || isElem() || isProcinst();
         assert newName != null;
 
-        if (!_name.equals( newName ) || !_name.getPrefix().equals( newName.getPrefix() ))
-        {
+        if (!_name.equals(newName) || !_name.getPrefix().equals(newName.getPrefix())) {
 // TODO - this is not a structural change .... perhaps should not issue a change here?
             _locale.notifyChange();
 
             QName oldName = _name;
 
             _name = newName;
-            if (this instanceof NamedNodeXobj)
-            {
-                NamedNodeXobj me = (NamedNodeXobj)this;
+            if (this instanceof NamedNodeXobj) {
+                NamedNodeXobj me = (NamedNodeXobj) this;
                 me._canHavePrefixUri = true;
             }
 
-            if (!isProcinst())
-            {
+            if (!isProcinst()) {
                 Xobj disconnectFromHere = this;
 
-                if (isAttr() && _parent != null)
-                {
-                    if (oldName.equals( Locale._xsiType ) || newName.equals( Locale._xsiType ))
+                if (isAttr() && _parent != null) {
+                    if (oldName.equals(Locale._xsiType) || newName.equals(Locale._xsiType)) {
                         disconnectFromHere = _parent;
+                    }
 
-                    if (oldName.equals( Locale._xsiNil ) || newName.equals( Locale._xsiNil ))
+                    if (oldName.equals(Locale._xsiNil) || newName.equals(Locale._xsiNil)) {
                         _parent.invalidateNil();
+                    }
                 }
 
                 disconnectFromHere.disconnectNonRootUsers();
@@ -545,62 +616,55 @@
         }
     }
 
-    final Xobj ensureParent ( )
-    {
+    final Xobj ensureParent() {
         assert _parent != null || (!isRoot() && cchAfter() == 0);
-        return _parent == null ? new DocumentFragXobj( _locale ).appendXobj( this ) : _parent;
+        return _parent == null ? new DocumentFragXobj(_locale).appendXobj(this) : _parent;
     }
 
-    final Xobj firstAttr ( )
-    {
+    final Xobj firstAttr() {
         return _firstChild == null || !_firstChild.isAttr() ? null : _firstChild;
     }
 
-    final Xobj nextAttr ( )
-    {
-        if (_firstChild != null && _firstChild.isAttr())
+    final Xobj nextAttr() {
+        if (_firstChild != null && _firstChild.isAttr()) {
             return _firstChild;
+        }
 
-        if (_nextSibling != null && _nextSibling.isAttr())
+        if (_nextSibling != null && _nextSibling.isAttr()) {
             return _nextSibling;
+        }
 
         return null;
     }
 
-    final boolean isValid ( )
-    {
-        if (isVacant() && (_cchValue != 0 || _user == null))
+    final boolean isValid() {
+        if (isVacant() && (_cchValue != 0 || _user == null)) {
             return false;
+        }
 
         return true;
     }
 
-    final int posTemp ( )
-    {
+    final int posTemp() {
         return _locale._posTemp;
     }
 
-    final Xobj getNormal ( int p )
-    {
+    final Xobj getNormal(int p) {
         assert p == END_POS || (p >= 0 && p <= posMax());
 
         Xobj x = this;
 
-        if (p == x.posMax())
-        {
-            if (x._nextSibling != null)
-            {
+        if (p == x.posMax()) {
+            if (x._nextSibling != null) {
                 x = x._nextSibling;
                 p = 0;
-            }
-            else
-            {
+            } else {
                 x = x.ensureParent();
                 p = END_POS;
             }
-        }
-        else if (p == x.posAfter() - 1)
+        } else if (p == x.posAfter() - 1) {
             p = END_POS;
+        }
 
         _locale._posTemp = p;
 
@@ -610,32 +674,24 @@
     // Can't denormalize a position at the very beginning of the document.  No where to go to the
     // left!
 
-    final Xobj getDenormal ( int p )
-    {
+    final Xobj getDenormal(int p) {
         assert END_POS == -1;
         assert !isRoot() || p == END_POS || p > 0;
 
         Xobj x = this;
 
-        if (p == 0)
-        {
-            if (x._prevSibling == null)
-            {
+        if (p == 0) {
+            if (x._prevSibling == null) {
                 x = x.ensureParent();
                 p = x.posAfter() - 1;
-            }
-            else
-            {
+            } else {
                 x = x._prevSibling;
                 p = x.posMax();
             }
-        }
-        else if (p == END_POS)
-        {
-            if (x._lastChild == null)
+        } else if (p == END_POS) {
+            if (x._lastChild == null) {
                 p = x.posAfter() - 1;
-            else
-            {
+            } else {
                 x = x._lastChild;
                 p = x.posMax();
             }
@@ -646,62 +702,71 @@
         return x;
     }
 
-    final boolean isNormal ( int p )
-    {
-        if (!isValid())
+    final boolean isNormal(int p) {
+        if (!isValid()) {
             return false;
-
-        if (p == END_POS || p == 0)
-            return true;
-
-        if (p < 0 || p >= posMax())
-            return false;
-
-        if (p >= posAfter())
-        {
-            if (isRoot())
-                return false;
-
-            if (_nextSibling != null && _nextSibling.isAttr())
-                return false;
-
-            if (_parent == null || !_parent.isContainer())
-                return false;
         }
 
-        if (p == posAfter() - 1)
+        if (p == END_POS || p == 0) {
+            return true;
+        }
+
+        if (p < 0 || p >= posMax()) {
             return false;
+        }
+
+        if (p >= posAfter()) {
+            if (isRoot()) {
+                return false;
+            }
+
+            if (_nextSibling != null && _nextSibling.isAttr()) {
+                return false;
+            }
+
+            if (_parent == null || !_parent.isContainer()) {
+                return false;
+            }
+        }
+
+        if (p == posAfter() - 1) {
+            return false;
+        }
 
         return true;
     }
 
-    final Xobj walk ( Xobj root, boolean walkChildren )
-    {
-        if (_firstChild != null && walkChildren)
+    final Xobj walk(Xobj root, boolean walkChildren) {
+        if (_firstChild != null && walkChildren) {
             return _firstChild;
+        }
 
-        for ( Xobj x = this ; x != root ; x = x._parent )
-            if (x._nextSibling != null)
+        for (Xobj x = this; x != root; x = x._parent) {
+            if (x._nextSibling != null) {
                 return x._nextSibling;
+            }
+        }
 
         return null;
     }
 
-    final Xobj removeXobj ( )
-    {
-        if (_parent != null)
-        {
-            if (_parent._firstChild == this)
+    final Xobj removeXobj() {
+        if (_parent != null) {
+            if (_parent._firstChild == this) {
                 _parent._firstChild = _nextSibling;
+            }
 
-            if (_parent._lastChild == this)
+            if (_parent._lastChild == this) {
                 _parent._lastChild = _prevSibling;
+            }
 
-            if (_prevSibling != null)
+            if (_prevSibling != null) {
                 _prevSibling._nextSibling = _nextSibling;
+            }
 
-            if (_nextSibling != null)
+            if (_nextSibling != null) {
                 _nextSibling._prevSibling = _prevSibling;
+            }
 
             _parent = null;
             _prevSibling = null;
@@ -711,8 +776,7 @@
         return this;
     }
 
-    final Xobj insertXobj ( Xobj s )
-    {
+    final Xobj insertXobj(Xobj s) {
         assert _locale == s._locale;
         assert !s.isRoot() && !isRoot();
         assert s._parent == null;
@@ -725,18 +789,18 @@
         s._prevSibling = _prevSibling;
         s._nextSibling = this;
 
-        if (_prevSibling != null)
+        if (_prevSibling != null) {
             _prevSibling._nextSibling = s;
-        else
+        } else {
             _parent._firstChild = s;
+        }
 
         _prevSibling = s;
 
         return this;
     }
 
-    final Xobj appendXobj ( Xobj c )
-    {
+    final Xobj appendXobj(Xobj c) {
         assert _locale == c._locale;
         assert !c.isRoot();
         assert c._parent == null;
@@ -747,45 +811,49 @@
         c._parent = this;
         c._prevSibling = _lastChild;
 
-        if (_lastChild == null)
+        if (_lastChild == null) {
             _firstChild = c;
-        else
+        } else {
             _lastChild._nextSibling = c;
+        }
 
         _lastChild = c;
 
         return this;
     }
 
-    final void removeXobjs ( Xobj first, Xobj last )
-    {
+    final void removeXobjs(Xobj first, Xobj last) {
         assert last._locale == first._locale;
         assert first._parent == this;
         assert last._parent == this;
 
-        if (_firstChild == first)
+        if (_firstChild == first) {
             _firstChild = last._nextSibling;
+        }
 
-        if (_lastChild == last)
+        if (_lastChild == last) {
             _lastChild = first._prevSibling;
+        }
 
-        if (first._prevSibling != null)
+        if (first._prevSibling != null) {
             first._prevSibling._nextSibling = last._nextSibling;
+        }
 
-        if (last._nextSibling != null)
+        if (last._nextSibling != null) {
             last._nextSibling._prevSibling = first._prevSibling;
+        }
 
         // Leave the children linked together
 
         first._prevSibling = null;
         last._nextSibling = null;
 
-        for ( ; first != null ; first = first._nextSibling )
+        for (; first != null; first = first._nextSibling) {
             first._parent = null;
+        }
     }
 
-    final void insertXobjs ( Xobj first, Xobj last )
-    {
+    final void insertXobjs(Xobj first, Xobj last) {
         assert _locale == first._locale;
         assert last._locale == first._locale;
         assert first._parent == null && last._parent == null;
@@ -795,19 +863,20 @@
         first._prevSibling = _prevSibling;
         last._nextSibling = this;
 
-        if (_prevSibling != null)
+        if (_prevSibling != null) {
             _prevSibling._nextSibling = first;
-        else
+        } else {
             _parent._firstChild = first;
+        }
 
         _prevSibling = last;
 
-        for ( ; first != this ; first = first._nextSibling )
+        for (; first != this; first = first._nextSibling) {
             first._parent = _parent;
+        }
     }
 
-    final void appendXobjs ( Xobj first, Xobj last )
-    {
+    final void appendXobjs(Xobj first, Xobj last) {
         assert _locale == first._locale;
         assert last._locale == first._locale;
         assert first._parent == null && last._parent == null;
@@ -817,27 +886,27 @@
 
         first._prevSibling = _lastChild;
 
-        if (_lastChild == null)
+        if (_lastChild == null) {
             _firstChild = first;
-        else
+        } else {
             _lastChild._nextSibling = first;
+        }
 
         _lastChild = last;
 
-        for ( ; first != null ; first = first._nextSibling )
+        for (; first != null; first = first._nextSibling) {
             first._parent = this;
+        }
     }
 
-    static final void disbandXobjs ( Xobj first, Xobj last )
-    {
+    static final void disbandXobjs(Xobj first, Xobj last) {
         assert last._locale == first._locale;
         assert first._parent == null && last._parent == null;
         assert first._prevSibling == null;
         assert last._nextSibling == null;
         assert !first.isRoot();
 
-        while ( first != null )
-        {
+        while (first != null) {
             Xobj next = first._nextSibling;
             first._nextSibling = first._prevSibling = null;
             first = next;
@@ -846,26 +915,26 @@
 
     // Potential attr is going to be moved/removed, invalidate parent if it is a special attr
 
-    final void invalidateSpecialAttr ( Xobj newParent )
-    {
-        if (isAttr())
-        {
-            if (_name.equals( Locale._xsiType ))
-            {
-                if (_parent != null)
+    final void invalidateSpecialAttr(Xobj newParent) {
+        if (isAttr()) {
+            if (_name.equals(Locale._xsiType)) {
+                if (_parent != null) {
                     _parent.disconnectNonRootUsers();
+                }
 
-                if (newParent != null)
+                if (newParent != null) {
                     newParent.disconnectNonRootUsers();
+                }
             }
 
-            if (_name.equals( Locale._xsiNil ))
-            {
-                if (_parent != null)
+            if (_name.equals(Locale._xsiNil)) {
+                if (_parent != null) {
                     _parent.invalidateNil();
+                }
 
-                if (newParent != null)
+                if (newParent != null) {
                     newParent.invalidateNil();
+                }
             }
         }
     }
@@ -879,12 +948,11 @@
     // the fcns it calls must also deal with these invalid conditions.  Try not to call so many
     // fcns from here.
 
-    final void removeCharsHelper (
-        int p, int cchRemove, Xobj xTo, int pTo, boolean moveCurs, boolean invalidate )
-    {
+    final void removeCharsHelper(
+        int p, int cchRemove, Xobj xTo, int pTo, boolean moveCurs, boolean invalidate) {
         assert p > 0 && p < posMax() && p != posAfter() - 1;
         assert cchRemove > 0;
-        assert cchRight( p ) >= cchRemove;
+        assert cchRight(p) >= cchRemove;
         assert !moveCurs || xTo != null;
 
         // Here I check the span of text to be removed for cursors.  If xTo/pTo is not specified,
@@ -896,8 +964,7 @@
         // cursor just before an end tag, instead of placing it just before the first child.  Also,
         // I adjust all positions of curs after the text to be removed to account for the removal.
 
-        for ( Cur c = getEmbedded() ; c != null ; )
-        {
+        for (Cur c = getEmbedded(); c != null; ) {
             Cur next = c._next;
 
             // Here I test to see if the Cur c is in the range of chars to be removed.  Normally
@@ -909,20 +976,21 @@
 
             assert c._xobj == this;
 
-            if (c._pos >= p && c._pos < p + cchRemove)
-            {
-                if (moveCurs)
-                    c.moveToNoCheck( xTo, pTo + c._pos - p );
-                else
-                    c.nextChars( cchRemove - c._pos + p );
+            if (c._pos >= p && c._pos < p + cchRemove) {
+                if (moveCurs) {
+                    c.moveToNoCheck(xTo, pTo + c._pos - p);
+                } else {
+                    c.nextChars(cchRemove - c._pos + p);
+                }
             }
 
             // If c is still on this Xobj and it's to the right of the chars to remove, adjust
             // it to adapt to the removal of the cars.  I don't have to worry about END_POS
             // here, just curs in text.
 
-            if (c._xobj == this && c._pos >= p + cchRemove)
+            if (c._xobj == this && c._pos >= p + cchRemove) {
                 c._pos -= cchRemove;
+            }
 
             c = next;
         }
@@ -932,22 +1000,21 @@
         // xTo/pTo.  The caller has to make sure that if xTo/pTo is not specified, then there are
         // no bookmarks in the span of text to be removed.
 
-        for ( Bookmark b = _bookmarks ; b != null ; )
-        {
+        for (Bookmark b = _bookmarks; b != null; ) {
             Bookmark next = b._next;
 
             // Similarly, as above, I can't call inChars here
 
             assert b._xobj == this;
 
-            if (b._pos >= p && b._pos < p + cchRemove)
-            {
+            if (b._pos >= p && b._pos < p + cchRemove) {
                 assert xTo != null;
-                b.moveTo( xTo, pTo + b._pos - p );
+                b.moveTo(xTo, pTo + b._pos - p);
             }
 
-            if (b._xobj == this && b._pos >= p + cchRemove)
+            if (b._xobj == this && b._pos >= p + cchRemove) {
                 b._pos -= cchRemove;
+            }
 
             b = b._next;
         }
@@ -957,26 +1024,23 @@
         int pa = posAfter();
         CharUtil cu = _locale.getCharUtil();
 
-        if (p < pa)
-        {
-            _srcValue = cu.removeChars( p - 1, cchRemove, _srcValue, _offValue, _cchValue );
+        if (p < pa) {
+            _srcValue = cu.removeChars(p - 1, cchRemove, _srcValue, _offValue, _cchValue);
             _offValue = cu._offSrc;
             _cchValue = cu._cchSrc;
 
-            if (invalidate)
-            {
+            if (invalidate) {
                 invalidateUser();
-                invalidateSpecialAttr( null );
+                invalidateSpecialAttr(null);
             }
-        }
-        else
-        {
-            _srcAfter = cu.removeChars( p - pa, cchRemove, _srcAfter, _offAfter, _cchAfter );
+        } else {
+            _srcAfter = cu.removeChars(p - pa, cchRemove, _srcAfter, _offAfter, _cchAfter);
             _offAfter = cu._offSrc;
             _cchAfter = cu._cchSrc;
 
-            if (invalidate && _parent != null)
+            if (invalidate && _parent != null) {
                 _parent.invalidateUser();
+            }
         }
     }
 
@@ -984,8 +1048,7 @@
     // This fcn does not deal with occupation of the value, this needs to be handled by the
     // caller.
 
-    final void insertCharsHelper ( int p, Object src, int off, int cch, boolean invalidate )
-    {
+    final void insertCharsHelper(int p, Object src, int off, int cch, boolean invalidate) {
         assert p > 0;
         assert p >= posAfter() || isOccupied();
 
@@ -996,15 +1059,18 @@
         // Basically, I need to know if p is before any text in the node as a whole.  If it is,
         // then there may be cursors/marks I need to shift right.
 
-        if (p - (p < pa ? 1 : 2) < _cchValue + _cchAfter)
-        {
-            for ( Cur c = getEmbedded() ; c != null ; c = c._next )
-                if (c._pos >= p)
+        if (p - (p < pa ? 1 : 2) < _cchValue + _cchAfter) {
+            for (Cur c = getEmbedded(); c != null; c = c._next) {
+                if (c._pos >= p) {
                     c._pos += cch;
+                }
+            }
 
-            for ( Bookmark b = _bookmarks ; b != null ; b = b._next )
-                if (b._pos >= p)
+            for (Bookmark b = _bookmarks; b != null; b = b._next) {
+                if (b._pos >= p) {
                     b._pos += cch;
+                }
+            }
         }
 
         // Now, stuff the new characters in!  Also invalidate the proper container and if the
@@ -1014,39 +1080,34 @@
 
         CharUtil cu = _locale.getCharUtil();
 
-        if (p < pa)
-        {
-            _srcValue = cu.insertChars( p - 1, _srcValue, _offValue, _cchValue, src, off, cch );
+        if (p < pa) {
+            _srcValue = cu.insertChars(p - 1, _srcValue, _offValue, _cchValue, src, off, cch);
             _offValue = cu._offSrc;
             _cchValue = cu._cchSrc;
 
-            if (invalidate)
-            {
+            if (invalidate) {
                 invalidateUser();
-                invalidateSpecialAttr( null );
+                invalidateSpecialAttr(null);
             }
-        }
-        else
-        {
-            _srcAfter = cu.insertChars( p - pa, _srcAfter, _offAfter, _cchAfter, src, off, cch );
+        } else {
+            _srcAfter = cu.insertChars(p - pa, _srcAfter, _offAfter, _cchAfter, src, off, cch);
             _offAfter = cu._offSrc;
             _cchAfter = cu._cchSrc;
 
-            if (invalidate && _parent != null)
+            if (invalidate && _parent != null) {
                 _parent.invalidateUser();
+            }
         }
     }
 
-    Xobj copyNode ( Locale toLocale )
-    {
+    Xobj copyNode(Locale toLocale) {
         Xobj newParent = null;
         Xobj copy = null;
 
-        for ( Xobj x = this ; ; )
-        {
+        for (Xobj x = this; ; ) {
             x.ensureOccupancy();
 
-            Xobj newX = x.newNode( toLocale );
+            Xobj newX = x.newNode(toLocale);
 
             newX._srcValue = x._srcValue;
             newX._offValue = x._offValue;
@@ -1056,32 +1117,36 @@
             newX._offAfter = x._offAfter;
             newX._cchAfter = x._cchAfter;
 
-            for ( Bookmark b = x._bookmarks; b != null ; b = b._next )
-            {
-               if ( x.hasBookmark( CDataBookmark.CDATA_BOOKMARK.getKey(), b._pos) )
-                   newX.setBookmark(b._pos, CDataBookmark.CDATA_BOOKMARK.getKey(), CDataBookmark.CDATA_BOOKMARK);
+            for (Bookmark b = x._bookmarks; b != null; b = b._next) {
+                if (x.hasBookmark(CDataBookmark.CDATA_BOOKMARK.getKey(), b._pos)) {
+                    newX.setBookmark(b._pos, CDataBookmark.CDATA_BOOKMARK.getKey(), CDataBookmark.CDATA_BOOKMARK);
+                }
             }
             // TODO - strange to have charNode stuff inside here .....
-           // newX._charNodesValue = CharNode.copyNodes( x._charNodesValue, newX._srcValue );
-           // newX._charNodesAfter = CharNode.copyNodes( x._charNodesAfter, newX._srcAfter );
+            // newX._charNodesValue = CharNode.copyNodes( x._charNodesValue, newX._srcValue );
+            // newX._charNodesAfter = CharNode.copyNodes( x._charNodesAfter, newX._srcAfter );
 
-            if (newParent == null)
+            if (newParent == null) {
                 copy = newX;
-            else
-                newParent.appendXobj( newX );
+            } else {
+                newParent.appendXobj(newX);
+            }
 
             // Walk to the next in-order xobj.  Record the current (y) to compute newParent
 
             Xobj y = x;
 
-            if ((x = x.walk( this, true )) == null)
+            if ((x = x.walk(this, true)) == null) {
                 break;
+            }
 
-            if (y == x._parent)
+            if (y == x._parent) {
                 newParent = newX;
-            else
-                for ( ; y._parent != x._parent ; y = y._parent )
+            } else {
+                for (; y._parent != x._parent; y = y._parent) {
                     newParent = newParent._parent;
+                }
+            }
         }
 
         copy._srcAfter = null;
@@ -1093,62 +1158,58 @@
 
     // Rturns all the chars, even if there is text intermixed with children
 
-    String getCharsAsString ( int p, int cch, int wsr )
-    {
-        if (cchRight( p ) == 0)
+    String getCharsAsString(int p, int cch, int wsr) {
+        if (cchRight(p) == 0) {
             return "";
+        }
 
-        Object src = getChars( p, cch );
+        Object src = getChars(p, cch);
 
-        if (wsr == Locale.WS_PRESERVE)
-            return CharUtil.getString( src, _locale._offSrc, _locale._cchSrc );
+        if (wsr == Locale.WS_PRESERVE) {
+            return CharUtil.getString(src, _locale._offSrc, _locale._cchSrc);
+        }
 
-        Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr );
+        Locale.ScrubBuffer scrub = Locale.getScrubBuffer(wsr);
 
-        scrub.scrub( src, _locale._offSrc, _locale._cchSrc );
+        scrub.scrub(src, _locale._offSrc, _locale._cchSrc);
 
         return scrub.getResultAsString();
     }
-    String getCharsAfterAsString ( int off, int cch )
-    {
-       int offset = off + _cchValue + 2;
-        if (offset == posMax())
+
+    String getCharsAfterAsString(int off, int cch) {
+        int offset = off + _cchValue + 2;
+        if (offset == posMax()) {
             offset = -1;
+        }
         return getCharsAsString(offset, cch,
             Locale.WS_PRESERVE);
     }
-    String getCharsValueAsString ( int off, int cch )
-    {
-       return getCharsAsString(off + 1, cch,
-                        Locale.WS_PRESERVE);
+
+    String getCharsValueAsString(int off, int cch) {
+        return getCharsAsString(off + 1, cch,
+            Locale.WS_PRESERVE);
     }
-    String getValueAsString ( int wsr )
-    {
-        if (!hasChildren())
-        {
+
+    String getValueAsString(int wsr) {
+        if (!hasChildren()) {
             Object src = getFirstChars();
 
-            if (wsr == Locale.WS_PRESERVE)
-            {
-                String s = CharUtil.getString( src, _locale._offSrc, _locale._cchSrc );
+            if (wsr == Locale.WS_PRESERVE) {
+                String s = CharUtil.getString(src, _locale._offSrc, _locale._cchSrc);
 
                 // Cache string to be able to use it later again
 
                 int cch = s.length();
 
-                if (cch > 0)
-                {
+                if (cch > 0) {
                     Xobj lastAttr = lastAttr();
 
                     assert (lastAttr == null ? _cchValue : lastAttr._cchAfter) == cch;
 
-                    if (lastAttr != null)
-                    {
+                    if (lastAttr != null) {
                         lastAttr._srcAfter = s;
                         lastAttr._offAfter = 0;
-                    }
-                    else
-                    {
+                    } else {
                         _srcValue = s;
                         _offValue = 0;
                     }
@@ -1157,28 +1218,29 @@
                 return s;
             }
 
-            Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr );
+            Locale.ScrubBuffer scrub = Locale.getScrubBuffer(wsr);
 
-            scrub.scrub( src, _locale._offSrc, _locale._cchSrc );
+            scrub.scrub(src, _locale._offSrc, _locale._cchSrc);
 
             return scrub.getResultAsString();
         }
 
-        Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr );
+        Locale.ScrubBuffer scrub = Locale.getScrubBuffer(wsr);
 
         Cur c = tempCur();
 
         c.push();
 
-        for ( c.next() ; !c.isAtEndOfLastPush() ; )
-        {
-            if (c.isText())
-                scrub.scrub( c.getChars( -1 ), c._offSrc, c._cchSrc );
+        for (c.next(); !c.isAtEndOfLastPush(); ) {
+            if (c.isText()) {
+                scrub.scrub(c.getChars(-1), c._offSrc, c._cchSrc);
+            }
 
-            if (c.isComment() || c.isProcinst())
+            if (c.isComment() || c.isProcinst()) {
                 c.skip();
-            else
+            } else {
                 c.next();
+            }
         }
 
         String s = scrub.getResultAsString();
@@ -1188,20 +1250,20 @@
         return s;
     }
 
-    String getValueAsString ( )
-    {
-        return getValueAsString( Locale.WS_PRESERVE );
+    String getValueAsString() {
+        return getValueAsString(Locale.WS_PRESERVE);
     }
 
-    String getString ( int p, int cch )
-    {
-        int cchRight = cchRight( p );
+    String getString(int p, int cch) {
+        int cchRight = cchRight(p);
 
-        if (cchRight == 0)
+        if (cchRight == 0) {
             return "";
+        }
 
-        if (cch < 0 || cch > cchRight)
+        if (cch < 0 || cch > cchRight) {
             cch = cchRight;
+        }
 
         int pa = posAfter();
 
@@ -1209,22 +1271,17 @@
 
         String s;
 
-        if (p >= pa)
-        {
-            s = CharUtil.getString( _srcAfter, _offAfter + p - pa, cch );
+        if (p >= pa) {
+            s = CharUtil.getString(_srcAfter, _offAfter + p - pa, cch);
 
-            if (p == pa && cch == _cchAfter)
-            {
+            if (p == pa && cch == _cchAfter) {
                 _srcAfter = s;
                 _offAfter = 0;
             }
-        }
-        else
-        {
-            s = CharUtil.getString( _srcValue, _offValue + p - 1, cch );
+        } else {
+            s = CharUtil.getString(_srcValue, _offValue + p - 1, cch);
 
-            if (p == 1 && cch == _cchValue)
-            {
+            if (p == 1 && cch == _cchValue) {
                 _srcValue = s;
                 _offValue = 0;
             }
@@ -1236,29 +1293,27 @@
     // Returns just chars just after the begin tag ... does not get all the text if there are
     // children
 
-    Object getFirstChars ( )
-    {
+    Object getFirstChars() {
         ensureOccupancy();
 
-        if (_cchValue > 0)
-            return getChars( 1, -1 );
+        if (_cchValue > 0) {
+            return getChars(1, -1);
+        }
 
         Xobj lastAttr = lastAttr();
 
-        if (lastAttr == null || lastAttr._cchAfter <= 0)
-        {
+        if (lastAttr == null || lastAttr._cchAfter <= 0) {
             _locale._offSrc = 0;
             _locale._cchSrc = 0;
 
             return null;
         }
 
-        return lastAttr.getChars( lastAttr.posAfter(), -1 );
+        return lastAttr.getChars(lastAttr.posAfter(), -1);
     }
 
-    Object getChars ( int pos, int cch, Cur c )
-    {
-        Object src = getChars( pos, cch );
+    Object getChars(int pos, int cch, Cur c) {
+        Object src = getChars(pos, cch);
 
         c._offSrc = _locale._offSrc;
         c._cchSrc = _locale._cchSrc;
@@ -1268,43 +1323,38 @@
 
     // These return the remainder of the char triple that getChars starts
 
-    Object getChars ( int pos, int cch )
-    {
-        assert isNormal( pos );
+    Object getChars(int pos, int cch) {
+        assert isNormal(pos);
 
-        int cchRight = cchRight( pos );
+        int cchRight = cchRight(pos);
 
-        if (cch < 0 || cch > cchRight)
+        if (cch < 0 || cch > cchRight) {
             cch = cchRight;
+        }
 
-        if (cch == 0)
-        {
+        if (cch == 0) {
             _locale._offSrc = 0;
             _locale._cchSrc = 0;
 
             return null;
         }
 
-        return getCharsHelper( pos, cch );
+        return getCharsHelper(pos, cch);
     }
 
     // Assumes that there are chars to return, does not assume normal x/p
 
-    Object getCharsHelper ( int pos, int cch )
-    {
-        assert cch > 0 && cchRight( pos ) >= cch;
+    Object getCharsHelper(int pos, int cch) {
+        assert cch > 0 && cchRight(pos) >= cch;
 
         int pa = posAfter();
 
         Object src;
 
-        if (pos >= pa)
-        {
+        if (pos >= pa) {
             src = _srcAfter;
             _locale._offSrc = _offAfter + pos - pa;
-        }
-        else
-        {
+        } else {
             src = _srcValue;
             _locale._offSrc = _offValue + pos - 1;
         }
@@ -1318,35 +1368,53 @@
     //
     //
 
-    final void setBit     ( int mask ) { _bits |=  mask; }
-    final void clearBit   ( int mask ) { _bits &= ~mask; }
+    final void setBit(int mask) {
+        _bits |= mask;
+    }
 
-    final boolean bitIsSet   ( int mask ) { return (_bits & mask) != 0; }
-    final boolean bitIsClear ( int mask ) { return (_bits & mask) == 0; }
+    final void clearBit(int mask) {
+        _bits &= ~mask;
+    }
 
-    static final int VACANT             = 0x100;
-    static final int STABLE_USER        = 0x200;
+    final boolean bitIsSet(int mask) {
+        return (_bits & mask) != 0;
+    }
+
+    final boolean bitIsClear(int mask) {
+        return (_bits & mask) == 0;
+    }
+
+    static final int VACANT = 0x100;
+    static final int STABLE_USER = 0x200;
     static final int INHIBIT_DISCONNECT = 0x400;
 
-    final boolean isVacant          ( ) { return bitIsSet   ( VACANT ); }
-    final boolean isOccupied        ( ) { return bitIsClear ( VACANT ); }
-    final boolean inhibitDisconnect ( ) { return bitIsSet   ( INHIBIT_DISCONNECT ); }
+    final boolean isVacant() {
+        return bitIsSet(VACANT);
+    }
 
-    final boolean isStableUser    ( ) { return bitIsSet( STABLE_USER ); }
+    final boolean isOccupied() {
+        return bitIsClear(VACANT);
+    }
 
-    void invalidateNil ( )
-    {
-        if (_user != null)
+    final boolean inhibitDisconnect() {
+        return bitIsSet(INHIBIT_DISCONNECT);
+    }
+
+    final boolean isStableUser() {
+        return bitIsSet(STABLE_USER);
+    }
+
+    void invalidateNil() {
+        if (_user != null) {
             _user.invalidate_nilvalue();
+        }
     }
 
-    void setStableType ( SchemaType type )
-    {
-        setStableUser( ((TypeStoreUserFactory) type).createTypeStoreUser() );
+    void setStableType(SchemaType type) {
+        setStableUser(((TypeStoreUserFactory) type).createTypeStoreUser());
     }
 
-    void setStableUser ( TypeStoreUser user )
-    {
+    void setStableUser(TypeStoreUser user) {
         disconnectNonRootUsers();
         disconnectUser();
 
@@ -1354,15 +1422,13 @@
 
         _user = user;
 
-        _user.attach_store( this );
+        _user.attach_store(this);
 
-        setBit( STABLE_USER );
+        setBit(STABLE_USER);
     }
 
-    void disconnectUser ( )
-    {
-        if (_user != null && !inhibitDisconnect())
-        {
+    void disconnectUser() {
+        if (_user != null && !inhibitDisconnect()) {
             ensureOccupancy();
             _user.disconnect_store();
             _user = null;
@@ -1373,26 +1439,23 @@
     // the doconnect happens in document order.  This may be a problem ... not sure ... May want
     // to disconnect in a bottom up manner.
 
-    void disconnectNonRootUsers ( )
-    {
+    void disconnectNonRootUsers() {
         Xobj next;
 
-        for ( Xobj x = this ; x != null ; x = next )
-        {
-            next = x.walk( this, x._user != null );
+        for (Xobj x = this; x != null; x = next) {
+            next = x.walk(this, x._user != null);
 
-            if (!x.isRoot())
+            if (!x.isRoot()) {
                 x.disconnectUser();
+            }
         }
     }
 
-    void disconnectChildrenUsers ( )
-    {
+    void disconnectChildrenUsers() {
         Xobj next;
 
-        for ( Xobj x = walk( this, _user == null ) ; x != null ; x = next )
-        {
-            next = x.walk( this, x._user != null );
+        for (Xobj x = walk(this, _user == null); x != null; x = next) {
+            next = x.walk(this, x._user != null);
 
             x.disconnectUser();
         }
@@ -1417,128 +1480,142 @@
      * This function intercepts the built-in prefixes "xml" and
      * "xmlns" and returns their well-known namespace URIs.
      *
-     * @param prefix The prefix to look up.
+     * @param prefix              The prefix to look up.
      * @param defaultAlwaysMapped If true, return the no-namespace for the default namespace if not set.
      * @return The mapped namespace URI ("" if no-namespace), or null if no mapping.
      */
 
-    final String namespaceForPrefix ( String prefix, boolean defaultAlwaysMapped )
-    {
-        if (prefix == null)
+    final String namespaceForPrefix(String prefix, boolean defaultAlwaysMapped) {
+        if (prefix == null) {
             prefix = "";
+        }
 
         // handle built-in prefixes
 
-        if (prefix.equals( "xml" ))
+        if (prefix.equals("xml")) {
             return Locale._xml1998Uri;
+        }
 
-        if (prefix.equals( "xmlns" ))
+        if (prefix.equals("xmlns")) {
             return Locale._xmlnsUri;
+        }
 
-        for ( Xobj x = this ; x != null ; x = x._parent )
-            for ( Xobj a = x._firstChild ; a != null && a.isAttr() ; a = a._nextSibling )
-                if (a.isXmlns() && a.getXmlnsPrefix().equals( prefix ))
+        for (Xobj x = this; x != null; x = x._parent) {
+            for (Xobj a = x._firstChild; a != null && a.isAttr(); a = a._nextSibling) {
+                if (a.isXmlns() && a.getXmlnsPrefix().equals(prefix)) {
                     return a.getXmlnsUri();
+                }
+            }
+        }
 
         return defaultAlwaysMapped && prefix.length() == 0 ? "" : null;
     }
 
-    final String prefixForNamespace ( String ns, String suggestion, boolean createIfMissing )
-    {
-        if (ns == null)
+    final String prefixForNamespace(String ns, String suggestion, boolean createIfMissing) {
+        if (ns == null) {
             ns = "";
+        }
 
         // special cases
 
-        if (ns.equals( Locale._xml1998Uri ))
+        if (ns.equals(Locale._xml1998Uri)) {
             return "xml";
+        }
 
-        if (ns.equals( Locale._xmlnsUri ))
+        if (ns.equals(Locale._xmlnsUri)) {
             return "xmlns";
+        }
 
         // Get the closest container for the spot we're on
 
         Xobj base = this;
 
-        while ( !base.isContainer() )
+        while (!base.isContainer()) {
             base = base.ensureParent();
+        }
 
         // Special handling for the no-namespace case
 
-        if (ns.length() == 0)
-        {
+        if (ns.length() == 0) {
             // Search for a namespace decl which defines the default namespace
 
-            Xobj a = base.findXmlnsForPrefix( "" );
+            Xobj a = base.findXmlnsForPrefix("");
 
             // If I did not find a default decl or the decl maps to the no namespace, then
             // the default namespace is mapped to ""
 
-            if (a == null || a.getXmlnsUri().length() == 0)
+            if (a == null || a.getXmlnsUri().length() == 0) {
                 return "";
+            }
 
             // At this point, I've found a default namespace which is *not* the no-namespace.
             // If I can't modify the document to mape the desired no-namespace, I must fail.
 
-            if (!createIfMissing)
+            if (!createIfMissing) {
                 return null;
+            }
 
             // Ok, I need to make the default namespace on the nearest container map to ""
 
-            base.setAttr( _locale.createXmlns( null ), "" );
+            base.setAttr(_locale.createXmlns(null), "");
 
             return "";
         }
 
         // Look for an exisiting mapping for the desired uri which has a visible prefix
 
-        for ( Xobj c = base ; c != null ; c = c._parent )
-            for ( Xobj a = c.firstAttr() ; a != null ; a = a.nextAttr() )
-                if (a.isXmlns() && a.getXmlnsUri().equals( ns ))
-                    if (base.findXmlnsForPrefix( a.getXmlnsPrefix() ) == a)
+        for (Xobj c = base; c != null; c = c._parent) {
+            for (Xobj a = c.firstAttr(); a != null; a = a.nextAttr()) {
+                if (a.isXmlns() && a.getXmlnsUri().equals(ns)) {
+                    if (base.findXmlnsForPrefix(a.getXmlnsPrefix()) == a) {
                         return a.getXmlnsPrefix();
+                    }
+                }
+            }
+        }
 
         // No exisiting xmlns I can use, need to create one.  See if I can first
 
-        if (!createIfMissing)
+        if (!createIfMissing) {
             return null;
+        }
 
         // Sanitize the suggestion.
 
         if (suggestion != null &&
-              (suggestion.length() == 0 || suggestion.toLowerCase().startsWith( "xml" ) ||
-                    base.findXmlnsForPrefix( suggestion ) != null))
-        {
+            (suggestion.length() == 0 || suggestion.toLowerCase().startsWith("xml") ||
+             base.findXmlnsForPrefix(suggestion) != null)) {
             suggestion = null;
         }
 
         // If no suggestion, make one up
 
-        if (suggestion == null)
-        {
-            String prefixBase = QNameHelper.suggestPrefix( ns );
+        if (suggestion == null) {
+            String prefixBase = QNameHelper.suggestPrefix(ns);
 
             suggestion = prefixBase;
 
-            for ( int i = 1 ; ; suggestion = prefixBase + i++ )
-                if (base.findXmlnsForPrefix( suggestion ) == null)
+            for (int i = 1; ; suggestion = prefixBase + i++) {
+                if (base.findXmlnsForPrefix(suggestion) == null) {
                     break;
+                }
+            }
         }
 
         // Add a new namespace decl at the top elem if one exists, otherwise at root
 
         Xobj c = base;
 
-        while ( !c.isRoot() && !c.ensureParent().isRoot() )
+        while (!c.isRoot() && !c.ensureParent().isRoot()) {
             c = c._parent;
+        }
 
-        base.setAttr( _locale.createXmlns( suggestion ), ns );
+        base.setAttr(_locale.createXmlns(suggestion), ns);
 
         return suggestion;
     }
 
-    final QName getValueAsQName ( )
-    {
+    final QName getValueAsQName() {
         assert !hasChildren();
 
         // TODO -
@@ -1547,61 +1624,56 @@
         // when I make the store capable of handling strong simple types this
         // can be done ...
 
-        String value = getValueAsString( Locale.WS_COLLAPSE );
+        String value = getValueAsString(Locale.WS_COLLAPSE);
 
         String prefix, localname;
 
-        int firstcolon = value.indexOf( ':' );
+        int firstcolon = value.indexOf(':');
 
-        if (firstcolon >= 0)
-        {
-            prefix = value.substring( 0, firstcolon );
-            localname = value.substring( firstcolon + 1 );
-        }
-        else
-        {
+        if (firstcolon >= 0) {
+            prefix = value.substring(0, firstcolon);
+            localname = value.substring(firstcolon + 1);
+        } else {
             prefix = "";
             localname = value;
         }
 
-        String uri = namespaceForPrefix( prefix, true );
+        String uri = namespaceForPrefix(prefix, true);
 
-        if (uri == null)
+        if (uri == null) {
             return null; // no prefix definition found - that's illegal
+        }
 
-        return new QName( uri, localname );
+        return new QName(uri, localname);
     }
 
-    final Xobj getAttr ( QName name )
-    {
-        for ( Xobj x = _firstChild ; x != null && x.isAttr() ; x = x._nextSibling )
-            if (x._name.equals( name ))
+    final Xobj getAttr(QName name) {
+        for (Xobj x = _firstChild; x != null && x.isAttr(); x = x._nextSibling) {
+            if (x._name.equals(name)) {
                 return x;
+            }
+        }
 
         return null;
     }
 
-    final QName getXsiTypeName ( )
-    {
+    final QName getXsiTypeName() {
         assert isContainer();
 
-        Xobj a = getAttr( Locale._xsiType );
+        Xobj a = getAttr(Locale._xsiType);
 
         return a == null ? null : a.getValueAsQName();
     }
 
-    final XmlObject getObject ( )
-    {
-        return isUserNode() ?  (XmlObject) getUser() : null;
+    final XmlObject getObject() {
+        return isUserNode() ? (XmlObject) getUser() : null;
     }
 
-    final TypeStoreUser getUser ( )
-    {
+    final TypeStoreUser getUser() {
         assert isUserNode();
         assert _user != null || (!isRoot() && !isStableUser());
 
-        if (_user == null)
-        {
+        if (_user == null) {
             // BUGBUG - this is recursive
 
             TypeStoreUser parentUser =
@@ -1611,49 +1683,47 @@
 
             _user =
                 isElem()
-                    ? parentUser.create_element_user( _name, getXsiTypeName() )
-                    : parentUser.create_attribute_user( _name );
+                    ? parentUser.create_element_user(_name, getXsiTypeName())
+                    : parentUser.create_attribute_user(_name);
 
-            _user.attach_store( this );
+            _user.attach_store(this);
         }
 
         return _user;
     }
 
-    final void invalidateUser ( )
-    {
+    final void invalidateUser() {
         assert isValid();
         assert _user == null || isUserNode();
 
-        if (_user != null)
+        if (_user != null) {
             _user.invalidate_value();
+        }
     }
 
-    final void ensureOccupancy ( )
-    {
+    final void ensureOccupancy() {
         assert isValid();
 
-        if (isVacant())
-        {
+        if (isVacant()) {
             assert isUserNode();
 
             // In order to use Cur to set the value, I mark the
             // value as occupied and remove the user to prohibit
             // further user invalidations
 
-            clearBit( VACANT );
+            clearBit(VACANT);
 
             TypeStoreUser user = _user;
             _user = null;
 
-            String value = user.build_text( this );
+            String value = user.build_text(this);
 
 
             long saveVersion = _locale._versionAll;
             long saveVersionSansText = _locale._versionSansText;
 
 
-            setValue( value );
+            setValue(value);
             assert saveVersionSansText == _locale._versionSansText;
 
             _locale._versionAll = saveVersion;
@@ -1663,21 +1733,21 @@
             _user = user;
         }
     }
-    private void setValue(String val)
-    {
+
+    private void setValue(String val) {
         assert CharUtil.isValid(val, 0, val.length());
 
         // Check for nothing to insert
 
-        if (val.length() <= 0)
+        if (val.length() <= 0) {
             return;
+        }
 
         _locale.notifyChange();
         Xobj lastAttr = lastAttr();
         int startPos = 1;
         Xobj charOwner = this;
-        if (lastAttr != null)
-        {
+        if (lastAttr != null) {
             charOwner = lastAttr;
             startPos = charOwner.posAfter();
         }
@@ -1687,204 +1757,177 @@
     // TypeStore
     //
 
-    public SchemaTypeLoader get_schematypeloader ( )
-    {
+    public SchemaTypeLoader get_schematypeloader() {
         return _locale._schemaTypeLoader;
     }
 
-    public XmlLocale get_locale ( )
-    {
+    public XmlLocale get_locale() {
         return _locale;
     }
 
     // TODO - remove this when I've replaced the old store
-    public Object get_root_object ( )
-    {
+    public Object get_root_object() {
         return _locale;
     }
 
-    public boolean is_attribute    ( ) { assert isValid(); return isAttr();               }
-    public boolean validate_on_set ( ) { assert isValid(); return _locale._validateOnSet; }
+    public boolean is_attribute() {
+        assert isValid();
+        return isAttr();
+    }
 
-    public void invalidate_text ( )
-    {
+    public boolean validate_on_set() {
+        assert isValid();
+        return _locale._validateOnSet;
+    }
+
+    public void invalidate_text() {
         _locale.enter();
 
-        try
-        {
+        try {
             assert isValid();
 
-            if (isOccupied())
-            {
-                if (hasTextNoEnsureOccupancy() || hasChildren())
-                {
+            if (isOccupied()) {
+                if (hasTextNoEnsureOccupancy() || hasChildren()) {
                     TypeStoreUser user = _user;
                     _user = null;
 
                     Cur c = tempCur();
-                    c.moveNodeContents( null, false );
+                    c.moveNodeContents(null, false);
                     c.release();
 
                     assert _user == null;
                     _user = user;
                 }
 
-                setBit( VACANT );
+                setBit(VACANT);
             }
 
             assert isValid();
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
     }
 
-    public String fetch_text ( int wsr )
-    {
+    public String fetch_text(int wsr) {
         _locale.enter();
 
-        try
-        {
+        try {
             assert isValid() && isOccupied();
 
-            return getValueAsString( wsr );
-        }
-        finally
-        {
+            return getValueAsString(wsr);
+        } finally {
             _locale.exit();
         }
     }
 
-    public XmlCursor new_cursor ( )
-    {
+    public XmlCursor new_cursor() {
         _locale.enter();
 
-        try
-        {
+        try {
             Cur c = tempCur();
-            XmlCursor xc = new Cursor( c );
+            XmlCursor xc = new Cursor(c);
             c.release();
             return xc;
 
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
     }
 
-    public SchemaField get_schema_field ( )
-    {
+    public SchemaField get_schema_field() {
         assert isValid();
 
-        if (isRoot())
+        if (isRoot()) {
             return null;
+        }
 
         TypeStoreUser parentUser = ensureParent().getUser();
 
-        if (isAttr())
-            return parentUser.get_attribute_field( _name );
+        if (isAttr()) {
+            return parentUser.get_attribute_field(_name);
+        }
 
         assert isElem();
 
         TypeStoreVisitor visitor = parentUser.new_visitor();
 
-        if (visitor == null)
+        if (visitor == null) {
             return null;
+        }
 
-        for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling )
-        {
-            if (x.isElem())
-            {
-                visitor.visit( x._name );
+        for (Xobj x = _parent._firstChild; ; x = x._nextSibling) {
+            if (x.isElem()) {
+                visitor.visit(x._name);
 
-                if (x == this)
+                if (x == this) {
                     return visitor.get_schema_field();
+                }
             }
         }
     }
 
-    public void validate ( ValidatorListener eventSink )
-    {
+    public void validate(ValidatorListener eventSink) {
         _locale.enter();
 
-        try
-        {
+        try {
             Cur c = tempCur();
-            Validate validate = new Validate( c, eventSink );
+            Validate validate = new Validate(c, eventSink);
             c.release();
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
     }
 
-    public TypeStoreUser change_type ( SchemaType type )
-    {
+    public TypeStoreUser change_type(SchemaType type) {
         _locale.enter();
 
-        try
-        {
+        try {
             Cur c = tempCur();
-            c.setType( type, false );
+            c.setType(type, false);
             c.release();
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
 
         return getUser();
     }
 
-    public TypeStoreUser substitute ( QName name, SchemaType type )
-    {
+    public TypeStoreUser substitute(QName name, SchemaType type) {
         _locale.enter();
 
-        try
-        {
+        try {
             Cur c = tempCur();
-            c.setSubstitution( name, type );
+            c.setSubstitution(name, type);
             c.release();
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
 
         return getUser();
     }
 
-    public QName get_xsi_type ( )
-    {
+    public QName get_xsi_type() {
         return getXsiTypeName();
     }
 
-    public void store_text ( String text )
-    {
+    public void store_text(String text) {
         _locale.enter();
 
         TypeStoreUser user = _user;
         _user = null;
 
-        try
-        {
+        try {
             Cur c = tempCur();
 
-            c.moveNodeContents( null, false );
+            c.moveNodeContents(null, false);
 
-            if (text != null && text.length() > 0)
-            {
+            if (text != null && text.length() > 0) {
                 c.next();
-                c.insertString( text );
+                c.insertString(text);
             }
 
             c.release();
-        }
-        finally
-        {
+        } finally {
             assert _user == null;
             _user = user;
 
@@ -1892,374 +1935,364 @@
         }
     }
 
-    public int compute_flags ( )
-    {
-        if (isRoot())
+    public int compute_flags() {
+        if (isRoot()) {
             return 0;
+        }
 
         TypeStoreUser parentUser = ensureParent().getUser();
 
-        if (isAttr())
-            return parentUser.get_attributeflags( _name );
+        if (isAttr()) {
+            return parentUser.get_attributeflags(_name);
+        }
 
-        int f = parentUser.get_elementflags( _name );
+        int f = parentUser.get_elementflags(_name);
 
-        if (f != -1)
+        if (f != -1) {
             return f;
+        }
 
         TypeStoreVisitor visitor = parentUser.new_visitor();
 
-        if (visitor == null)
+        if (visitor == null) {
             return 0;
+        }
 
-        for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling )
-        {
-            if (x.isElem())
-            {
-                visitor.visit( x._name );
+        for (Xobj x = _parent._firstChild; ; x = x._nextSibling) {
+            if (x.isElem()) {
+                visitor.visit(x._name);
 
-                if (x == this)
+                if (x == this) {
                     return visitor.get_elementflags();
+                }
             }
         }
     }
 
-    public String compute_default_text ( )
-    {
-        if (isRoot())
+    public String compute_default_text() {
+        if (isRoot()) {
             return null;
+        }
 
         TypeStoreUser parentUser = ensureParent().getUser();
 
-        if (isAttr())
-            return parentUser.get_default_attribute_text( _name );
+        if (isAttr()) {
+            return parentUser.get_default_attribute_text(_name);
+        }
 
-        String result = parentUser.get_default_element_text( _name );
+        String result = parentUser.get_default_element_text(_name);
 
-        if (result != null)
+        if (result != null) {
             return result;
+        }
 
         TypeStoreVisitor visitor = parentUser.new_visitor();
 
-        if (visitor == null)
+        if (visitor == null) {
             return null;
+        }
 
-        for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling )
-        {
-            if (x.isElem())
-            {
-                visitor.visit( x._name );
+        for (Xobj x = _parent._firstChild; ; x = x._nextSibling) {
+            if (x.isElem()) {
+                visitor.visit(x._name);
 
-                if (x == this)
+                if (x == this) {
                     return visitor.get_default_text();
+                }
             }
         }
     }
 
-    public boolean find_nil ( )
-    {
-        if (isAttr())
+    public boolean find_nil() {
+        if (isAttr()) {
             return false;
+        }
 
         _locale.enter();
 
-        try
-        {
-            Xobj a = getAttr( Locale._xsiNil );
+        try {
+            Xobj a = getAttr(Locale._xsiNil);
 
-            if (a == null)
+            if (a == null) {
                 return false;
+            }
 
-            String value = a.getValueAsString( Locale.WS_COLLAPSE );
+            String value = a.getValueAsString(Locale.WS_COLLAPSE);
 
-            return value.equals( "true" ) || value.equals( "1" );
-        }
-        finally
-        {
+            return value.equals("true") || value.equals("1");
+        } finally {
             _locale.exit();
         }
     }
 
-    public void invalidate_nil ( )
-    {
-        if (isAttr())
+    public void invalidate_nil() {
+        if (isAttr()) {
             return;
+        }
 
         _locale.enter();
 
-        try
-        {
-            if (!_user.build_nil())
-                removeAttr( Locale._xsiNil );
-            else
-                setAttr( Locale._xsiNil, "true" );
-        }
-        finally
-        {
+        try {
+            if (!_user.build_nil()) {
+                removeAttr(Locale._xsiNil);
+            } else {
+                setAttr(Locale._xsiNil, "true");
+            }
+        } finally {
             _locale.exit();
         }
     }
 
-    public int count_elements ( QName name )
-    {
-        return _locale.count( this, name, null );
+    public int count_elements(QName name) {
+        return _locale.count(this, name, null);
     }
 
-    public int count_elements ( QNameSet names )
-    {
-        return _locale.count( this, null, names );
+    public int count_elements(QNameSet names) {
+        return _locale.count(this, null, names);
     }
 
-    public TypeStoreUser find_element_user ( QName name, int i )
-    {
-        for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && x._name.equals( name ) && --i < 0)
+    public TypeStoreUser find_element_user(QName name, int i) {
+        for (Xobj x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && x._name.equals(name) && --i < 0) {
                 return x.getUser();
+            }
+        }
 
         return null;
     }
 
-    public TypeStoreUser find_element_user ( QNameSet names, int i )
-    {
-        for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && names.contains( x._name ) && --i < 0)
+    public TypeStoreUser find_element_user(QNameSet names, int i) {
+        for (Xobj x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && names.contains(x._name) && --i < 0) {
                 return x.getUser();
+            }
+        }
 
         return null;
     }
 
-    public void find_all_element_users ( QName name, List fillMeUp )
-    {
-        for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && x._name.equals( name ))
-                fillMeUp.add( x.getUser() );
+    public void find_all_element_users(QName name, List fillMeUp) {
+        for (Xobj x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && x._name.equals(name)) {
+                fillMeUp.add(x.getUser());
+            }
+        }
     }
 
-    public void find_all_element_users ( QNameSet names, List fillMeUp )
-    {
-        for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && names.contains( x._name ))
-                fillMeUp.add( x.getUser() );
+    public void find_all_element_users(QNameSet names, List fillMeUp) {
+        for (Xobj x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && names.contains(x._name)) {
+                fillMeUp.add(x.getUser());
+            }
+        }
     }
 
-    private static TypeStoreUser insertElement ( QName name, Xobj x, int pos )
-    {
+    private static TypeStoreUser insertElement(QName name, Xobj x, int pos) {
         x._locale.enter();
 
-        try
-        {
+        try {
             Cur c = x._locale.tempCur();
-            c.moveTo( x, pos );
-            c.createElement( name );
+            c.moveTo(x, pos);
+            c.createElement(name);
             TypeStoreUser user = c.getUser();
             c.release();
             return user;
-        }
-        finally
-        {
+        } finally {
             x._locale.exit();
         }
     }
 
-    public TypeStoreUser insert_element_user ( QName name, int i )
-    {
-        if (i < 0)
+    public TypeStoreUser insert_element_user(QName name, int i) {
+        if (i < 0) {
             throw new IndexOutOfBoundsException();
-
-        if (!isContainer())
-            throw new IllegalStateException();
-
-        Xobj x = _locale.findNthChildElem( this, name, null, i );
-
-        if (x == null)
-        {
-            if (i > _locale.count( this, name, null ) + 1)
-                throw new IndexOutOfBoundsException();
-
-            return add_element_user( name );
         }
 
-        return insertElement( name, x, 0 );
-    }
-
-    public TypeStoreUser insert_element_user ( QNameSet names, QName name, int i )
-    {
-        if (i < 0)
-            throw new IndexOutOfBoundsException();
-
-        if (!isContainer())
+        if (!isContainer()) {
             throw new IllegalStateException();
-
-        Xobj x = _locale.findNthChildElem( this, null, names, i );
-
-        if (x == null)
-        {
-            if (i > _locale.count( this, null, names ) + 1)
-                throw new IndexOutOfBoundsException();
-
-            return add_element_user( name );
         }
 
-        return insertElement( name, x, 0 );
+        Xobj x = _locale.findNthChildElem(this, name, null, i);
+
+        if (x == null) {
+            if (i > _locale.count(this, name, null) + 1) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            return add_element_user(name);
+        }
+
+        return insertElement(name, x, 0);
     }
 
-    public TypeStoreUser add_element_user ( QName name )
-    {
-        if (!isContainer())
+    public TypeStoreUser insert_element_user(QNameSet names, QName name, int i) {
+        if (i < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (!isContainer()) {
             throw new IllegalStateException();
+        }
+
+        Xobj x = _locale.findNthChildElem(this, null, names, i);
+
+        if (x == null) {
+            if (i > _locale.count(this, null, names) + 1) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            return add_element_user(name);
+        }
+
+        return insertElement(name, x, 0);
+    }
+
+    public TypeStoreUser add_element_user(QName name) {
+        if (!isContainer()) {
+            throw new IllegalStateException();
+        }
 
         QNameSet endSet = null;
-        boolean  gotEndSet = false;
+        boolean gotEndSet = false;
 
         Xobj candidate = null;
 
-        for ( Xobj x = _lastChild ; x != null ; x = x._prevSibling )
-        {
-            if (x.isContainer())
-            {
-                if (x._name.equals( name ))
+        for (Xobj x = _lastChild; x != null; x = x._prevSibling) {
+            if (x.isContainer()) {
+                if (x._name.equals(name)) {
                     break;
+                }
 
-                if (!gotEndSet)
-                {
-                    endSet = _user.get_element_ending_delimiters( name );
+                if (!gotEndSet) {
+                    endSet = _user.get_element_ending_delimiters(name);
                     gotEndSet = true;
                 }
 
-                if (endSet == null || endSet.contains( x._name ))
+                if (endSet == null || endSet.contains(x._name)) {
                     candidate = x;
+                }
             }
         }
 
         return
             candidate == null
-                ? insertElement( name, this, END_POS )
-                : insertElement( name, candidate, 0 );
+                ? insertElement(name, this, END_POS)
+                : insertElement(name, candidate, 0);
     }
 
-    private static void removeElement ( Xobj x )
-    {
-        if (x == null)
+    private static void removeElement(Xobj x) {
+        if (x == null) {
             throw new IndexOutOfBoundsException();
+        }
 
         x._locale.enter();
 
-        try
-        {
+        try {
             Cur c = x.tempCur();
-            c.moveNode( null );
+            c.moveNode(null);
             c.release();
-        }
-        finally
-        {
+        } finally {
             x._locale.exit();
         }
     }
 
-    public void remove_element ( QName name, int i )
-    {
-        if (i < 0)
+    public void remove_element(QName name, int i) {
+        if (i < 0) {
             throw new IndexOutOfBoundsException();
+        }
 
-        if (!isContainer())
+        if (!isContainer()) {
             throw new IllegalStateException();
+        }
 
         Xobj x;
 
-        for ( x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && x._name.equals( name ) && --i < 0)
+        for (x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && x._name.equals(name) && --i < 0) {
                 break;
+            }
+        }
 
-        removeElement( x );
+        removeElement(x);
     }
 
-    public void remove_element ( QNameSet names, int i )
-    {
-        if (i < 0)
+    public void remove_element(QNameSet names, int i) {
+        if (i < 0) {
             throw new IndexOutOfBoundsException();
+        }
 
-        if (!isContainer())
+        if (!isContainer()) {
             throw new IllegalStateException();
+        }
 
         Xobj x;
 
-        for ( x = _firstChild ; x != null ; x = x._nextSibling )
-            if (x.isElem() && names.contains( x._name ) && --i < 0)
+        for (x = _firstChild; x != null; x = x._nextSibling) {
+            if (x.isElem() && names.contains(x._name) && --i < 0) {
                 break;
+            }
+        }
 
-        removeElement( x );
+        removeElement(x);
     }
 
-    public TypeStoreUser find_attribute_user ( QName name )
-    {
-        Xobj a = getAttr( name );
+    public TypeStoreUser find_attribute_user(QName name) {
+        Xobj a = getAttr(name);
 
         return a == null ? null : a.getUser();
     }
 
-    public TypeStoreUser add_attribute_user ( QName name )
-    {
-        if (getAttr( name ) != null)
+    public TypeStoreUser add_attribute_user(QName name) {
+        if (getAttr(name) != null) {
             throw new IndexOutOfBoundsException();
+        }
 
         _locale.enter();
 
-        try
-        {
-            return setAttr( name, "" ).getUser();
-        }
-        finally
-        {
+        try {
+            return setAttr(name, "").getUser();
+        } finally {
             _locale.exit();
         }
     }
 
-    public void remove_attribute ( QName name )
-    {
+    public void remove_attribute(QName name) {
         _locale.enter();
 
-        try
-        {
-            if (!removeAttr( name ))
+        try {
+            if (!removeAttr(name)) {
                 throw new IndexOutOfBoundsException();
-        }
-        finally
-        {
+            }
+        } finally {
             _locale.exit();
         }
     }
 
-    public TypeStoreUser copy_contents_from ( TypeStore source )
-    {
+    public TypeStoreUser copy_contents_from(TypeStore source) {
         Xobj xSrc = (Xobj) source;
 
-        if (xSrc == this)
+        if (xSrc == this) {
             return getUser();
+        }
 
         _locale.enter();
 
-        try
-        {
+        try {
             xSrc._locale.enter();
 
             Cur c = tempCur();
 
-            try
-            {
+            try {
                 Cur cSrc1 = xSrc.tempCur();
-                Map sourceNamespaces = Locale.getAllNamespaces( cSrc1, null );
+                Map<String, String> sourceNamespaces = Locale.getAllNamespaces(cSrc1, null);
                 cSrc1.release();
 
-                if (isAttr())
-                {
+                if (isAttr()) {
                     Cur cSrc = xSrc.tempCur();
-                    String value = Locale.getTextValue( cSrc );
+                    String value = Locale.getTextValue(cSrc);
                     cSrc.release();
 
-                    c.setValue( value );
-                }
-                else
-                {
+                    c.setValue(value);
+                } else {
                     // Here I save away the user of this node so that it does not get whacked
                     // in the following operations.
 
@@ -2267,81 +2300,77 @@
 
                     assert !inhibitDisconnect();
 
-                    setBit( INHIBIT_DISCONNECT );
+                    setBit(INHIBIT_DISCONNECT);
 
                     QName xsiType = isContainer() ? getXsiTypeName() : null;
 
-                    Xobj copy = xSrc.copyNode( _locale );
+                    Xobj copy = xSrc.copyNode(_locale);
 
-                    Cur.moveNodeContents( this, null, true );
+                    Cur.moveNodeContents(this, null, true);
 
                     c.next();
 
-                    Cur.moveNodeContents( copy, c, true );
+                    Cur.moveNodeContents(copy, c, true);
 
-                    c.moveTo( this );
+                    c.moveTo(this);
 
-                    if (xsiType != null)
-                        c.setXsiType( xsiType );
+                    if (xsiType != null) {
+                        c.setXsiType(xsiType);
+                    }
 
                     assert inhibitDisconnect();
-                    clearBit( INHIBIT_DISCONNECT );
+                    clearBit(INHIBIT_DISCONNECT);
                 }
 
-                if (sourceNamespaces != null)
-                {
-                    if (!c.isContainer())
+                if (sourceNamespaces != null) {
+                    if (!c.isContainer()) {
                         c.toParent();
+                    }
 
-                    Locale.applyNamespaces( c, sourceNamespaces );
+                    Locale.applyNamespaces(c, sourceNamespaces);
                 }
 
-            }
-            finally
-            {
+            } finally {
                 c.release();
 
                 xSrc._locale.exit();
             }
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
 
         return getUser();
     }
 
-    public TypeStoreUser copy(SchemaTypeLoader stl, SchemaType type, XmlOptions options)
-    {
+    public TypeStoreUser copy(SchemaTypeLoader stl, SchemaType type, XmlOptions options) {
         //do not use a user's Factory method for copying.
         //XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
         Xobj destination = null;
         options = XmlOptions.maskNull(options);
-        SchemaType sType = (SchemaType) options.get(XmlOptions.DOCUMENT_TYPE);
+        SchemaType sType = options.getDocumentType();
 
-        if (sType == null)
+        if (sType == null) {
             sType = type == null ? XmlObject.type : type;
+        }
 
         Locale locale = this.locale();
-        if ( Boolean.TRUE.equals(options.get(XmlOptions.COPY_USE_NEW_SYNC_DOMAIN)) )
+        if (options.isCopyUseNewSynchronizationDomain()) {
             locale = Locale.getLocale(stl, options);
+        }
 
-        if (sType.isDocumentType() || (sType.isNoType() && (this instanceof DocumentXobj)))
+        if (sType.isDocumentType() || (sType.isNoType() && (this instanceof DocumentXobj))) {
             destination = Cur.createDomDocumentRootXobj(locale, false);
-        else
+        } else {
             destination = Cur.createDomDocumentRootXobj(locale, true);
+        }
 
 
         locale.enter();
-        try
-        {
+        try {
             Cur c = destination.tempCur();
             c.setType(type);
             c.release();
-        }
-        finally
-        {
+        } finally {
             locale.exit();
         }
 
@@ -2349,12 +2378,10 @@
         return tsu;
     }
 
-    public void array_setter ( XmlObject[] sources, QName elementName )
-    {
+    public void array_setter(XmlObject[] sources, QName elementName) {
         _locale.enter();
 
-        try
-        {
+        try {
             // TODO - this is the quick and dirty implementation, make this faster
 
             int m = sources.length;
@@ -2362,132 +2389,112 @@
             ArrayList copies = new ArrayList();
             ArrayList types = new ArrayList();
 
-            for ( int i = 0 ; i < m ; i++ )
-            {
-    // TODO - deal with null sources[ i ] here -- what to do?
+            for (int i = 0; i < m; i++) {
+                // TODO - deal with null sources[ i ] here -- what to do?
 
-                if (sources[ i ] == null)
-                    throw new IllegalArgumentException( "Array element null" );
+                if (sources[i] == null) {
+                    throw new IllegalArgumentException("Array element null");
+                } else if (sources[i].isImmutable()) {
+                    copies.add(null);
+                    types.add(null);
+                } else {
+                    Xobj x = ((Xobj) ((TypeStoreUser) sources[i]).get_store());
 
-                else if (sources[ i ].isImmutable())
-                {
-                    copies.add( null );
-                    types.add( null );
-                }
-                else
-                {
-                    Xobj x = ((Xobj) ((TypeStoreUser) sources[ i ]).get_store());
-
-                    if (x._locale == _locale)
-                        copies.add( x.copyNode( _locale ) );
-                    else
-                    {
+                    if (x._locale == _locale) {
+                        copies.add(x.copyNode(_locale));
+                    } else {
                         x._locale.enter();
 
-                        try
-                        {
-                            copies.add( x.copyNode( _locale ) );
-                        }
-                        finally
-                        {
+                        try {
+                            copies.add(x.copyNode(_locale));
+                        } finally {
                             x._locale.exit();
                         }
                     }
 
-                    types.add( sources[ i ].schemaType() );
+                    types.add(sources[i].schemaType());
                 }
             }
 
-            int n = count_elements( elementName );
+            int n = count_elements(elementName);
 
-            for ( ; n > m ; n-- )
-                remove_element( elementName, m );
+            for (; n > m; n--) {
+                remove_element(elementName, m);
+            }
 
-            for ( ; m > n ; n++ )
-                add_element_user( elementName );
+            for (; m > n; n++) {
+                add_element_user(elementName);
+            }
 
             assert m == n;
 
             ArrayList elements = new ArrayList();
 
-            find_all_element_users( elementName, elements );
+            find_all_element_users(elementName, elements);
 
-            for ( int i = 0 ; i < elements.size() ; i++ )
-                elements.set( i, (Xobj) ((TypeStoreUser) elements.get( i )).get_store() );
+            for (int i = 0; i < elements.size(); i++) {
+                elements.set(i, (Xobj) ((TypeStoreUser) elements.get(i)).get_store());
+            }
 
             assert elements.size() == n;
 
             Cur c = tempCur();
 
-            for ( int i = 0 ; i < n ; i++ )
-            {
-                Xobj x = (Xobj) elements.get( i );
+            for (int i = 0; i < n; i++) {
+                Xobj x = (Xobj) elements.get(i);
 
-                if (sources[ i ].isImmutable())
-                    x.getObject().set( sources[ i ] );
-                else
-                {
-                    Cur.moveNodeContents( x, null, true );
+                if (sources[i].isImmutable()) {
+                    x.getObject().set(sources[i]);
+                } else {
+                    Cur.moveNodeContents(x, null, true);
 
-                    c.moveTo( x );
+                    c.moveTo(x);
                     c.next();
 
-                    Cur.moveNodeContents( (Xobj) copies.get( i ), c, true );
+                    Cur.moveNodeContents((Xobj) copies.get(i), c, true);
 
-                    x.change_type( (SchemaType) types.get( i ) );
+                    x.change_type((SchemaType) types.get(i));
                 }
             }
 
             c.release();
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
     }
 
-    public void visit_elements ( TypeStoreVisitor visitor )
-    {
-        throw new RuntimeException( "Not implemeneted" );
+    public void visit_elements(TypeStoreVisitor visitor) {
+        throw new RuntimeException("Not implemeneted");
     }
 
-    public XmlObject[] exec_query ( String queryExpr, XmlOptions options ) throws XmlException
-    {
+    public XmlObject[] exec_query(String queryExpr, XmlOptions options) throws XmlException {
         _locale.enter();
 
-        try
-        {
+        try {
             Cur c = tempCur();
 
-            XmlObject[] result = Query.objectExecQuery( c, queryExpr, options );
+            XmlObject[] result = Query.objectExecQuery(c, queryExpr, options);
 
             c.release();
 
             return result;
-        }
-        finally
-        {
+        } finally {
             _locale.exit();
         }
     }
 
-    public String find_prefix_for_nsuri ( String nsuri, String suggested_prefix )
-    {
+    public String find_prefix_for_nsuri(String nsuri, String suggested_prefix) {
         _locale.enter();
 
-        try
-        {
-            return prefixForNamespace( nsuri, suggested_prefix, true );
-        }
-        finally
-        {
+        try {
+            return prefixForNamespace(nsuri, suggested_prefix, true);
+        } finally {
             _locale.exit();
         }
     }
 
-    public String getNamespaceForPrefix ( String prefix )
-    {
-        return namespaceForPrefix( prefix, true );
+    public String getNamespaceForPrefix(String prefix) {
+        return namespaceForPrefix(prefix, true);
     }
 
     Locale _locale;
@@ -2506,8 +2513,8 @@
     Xobj _lastChild;
 
     Object _srcValue, _srcAfter;
-    int    _offValue, _offAfter;
-    int    _cchValue, _cchAfter;
+    int _offValue, _offAfter;
+    int _cchValue, _cchAfter;
 
     // TODO - put this in a ptr off this node
     CharNode _charNodesValue;
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/FactorImports.java b/src/main/java/org/apache/xmlbeans/impl/tool/FactorImports.java
index bf1dd21..3938684 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/FactorImports.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/FactorImports.java
@@ -15,31 +15,16 @@
 
 package org.apache.xmlbeans.impl.tool;
 
-import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelSimpleType;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement;
-import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute;
-import org.apache.xmlbeans.impl.xb.xsdschema.NamedGroup;
-import org.apache.xmlbeans.impl.xb.xsdschema.NamedAttributeGroup;
-import org.apache.xmlbeans.impl.xb.xsdschema.FormChoice;
-import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.impl.xb.xsdschema.*;
 
-import java.util.Arrays;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
+import javax.xml.namespace.QName;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
-
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-
-import javax.xml.namespace.QName;
+import java.util.*;
 
 /**
  * This program takes a collection of .xsd files as input, finds all duplicate
@@ -47,10 +32,8 @@
  * a common.xsd file, adding an appropriate <import> statement in the original
  * xsd file.
  */
-public class FactorImports
-{
-    public static void printUsage()
-    {
+public class FactorImports {
+    public static void printUsage() {
         System.out.println("Refactors a directory of XSD files to remove name conflicts.");
         System.out.println("Usage: sfactor [-import common.xsd] [-out outputdir] inputdir");
         System.out.println("    -import common.xsd - The XSD file to contain redundant ");
@@ -65,61 +48,56 @@
 
     }
 
-    public static void main(String[] args) throws Exception
-    {
-        Set flags = new HashSet();
+    public static void main(String[] args) throws Exception {
+        Set<String> flags = new HashSet<>();
         flags.add("h");
         flags.add("help");
         flags.add("usage");
         flags.add("license");
         flags.add("version");
 
-        CommandLine cl = new CommandLine(args, flags, Arrays.asList(new String[] {"import", "out"}));
-        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1)
-        {
+        CommandLine cl = new CommandLine(args, flags, Arrays.asList("import", "out"));
+        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1) {
             printUsage();
             System.exit(0);
             return;
         }
 
         String[] badopts = cl.getBadOpts();
-        if (badopts.length > 0)
-        {
-            for (int i = 0; i < badopts.length; i++)
-                System.out.println("Unrecognized option: " + badopts[i]);
+        if (badopts.length > 0) {
+            for (String badopt : badopts) {
+                System.out.println("Unrecognized option: " + badopt);
+            }
             printUsage();
             System.exit(0);
             return;
         }
 
-        if (cl.getOpt("license") != null)
-        {
+        if (cl.getOpt("license") != null) {
             CommandLine.printLicense();
             System.exit(0);
             return;
         }
 
-        if (cl.getOpt("version") != null)
-        {
+        if (cl.getOpt("version") != null) {
             CommandLine.printVersion();
             System.exit(0);
             return;
         }
 
         args = cl.args();
-        if (args.length != 1)
-        {
+        if (args.length != 1) {
             System.exit(0);
             return;
         }
 
         String commonName = cl.getOpt("import");
-        if (commonName == null)
+        if (commonName == null) {
             commonName = "common.xsd";
+        }
 
         String out = cl.getOpt("out");
-        if (out == null)
-        {
+        if (out == null) {
             System.out.println("Using output directory 'out'");
             out = "out";
         }
@@ -128,101 +106,100 @@
 
         // first, parse all the schema files
         File[] files = cl.getFiles();
-        Map schemaDocs = new HashMap();
-        Set elementNames = new HashSet();
-        Set attributeNames = new HashSet();
-        Set typeNames = new HashSet();
-        Set modelGroupNames = new HashSet();
-        Set attrGroupNames = new HashSet();
+        Map<SchemaDocument,File> schemaDocs = new HashMap<>();
+        Set<QName> elementNames = new HashSet<>();
+        Set<QName> attributeNames = new HashSet<>();
+        Set<QName> typeNames = new HashSet<>();
+        Set<QName> modelGroupNames = new HashSet<>();
+        Set<QName> attrGroupNames = new HashSet<>();
 
-        Set dupeElementNames = new HashSet();
-        Set dupeAttributeNames = new HashSet();
-        Set dupeTypeNames = new HashSet();
-        Set dupeModelGroupNames = new HashSet();
-        Set dupeAttrGroupNames = new HashSet();
-        Set dupeNamespaces = new HashSet();
+        Set<QName> dupeElementNames = new HashSet<>();
+        Set<QName> dupeAttributeNames = new HashSet<>();
+        Set<QName> dupeTypeNames = new HashSet<>();
+        Set<QName> dupeModelGroupNames = new HashSet<>();
+        Set<QName> dupeAttrGroupNames = new HashSet<>();
+        Set<String> dupeNamespaces = new HashSet<>();
 
-        for (int i = 0; i < files.length; i++)
-        {
-            try
-            {
+        for (File file : files) {
+            try {
                 // load schema
-                SchemaDocument doc = SchemaDocument.Factory.parse(files[i]);
-                schemaDocs.put(doc, files[i]);
+                SchemaDocument doc = SchemaDocument.Factory.parse(file);
+                schemaDocs.put(doc, file);
 
                 // warn about for imports, includes
-                if (doc.getSchema().sizeOfImportArray() > 0 || doc.getSchema().sizeOfIncludeArray() > 0)
-                    System.out.println("warning: " + files[i] + " contains imports or includes that are being ignored.");
+                if (doc.getSchema().sizeOfImportArray() > 0 || doc.getSchema().sizeOfIncludeArray() > 0) {
+                    System.out.println("warning: " + file + " contains imports or includes that are being ignored.");
+                }
 
                 // collect together names
                 String targetNamespace = doc.getSchema().getTargetNamespace();
-                if (targetNamespace == null)
+                if (targetNamespace == null) {
                     targetNamespace = "";
+                }
 
-                TopLevelComplexType ct[] = doc.getSchema().getComplexTypeArray();
-                for (int j = 0; j < ct.length; j++)
-                    noteName(ct[j].getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces);
+                TopLevelComplexType[] ct = doc.getSchema().getComplexTypeArray();
+                for (TopLevelComplexType topLevelComplexType : ct) {
+                    noteName(topLevelComplexType.getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces);
+                }
 
-                TopLevelSimpleType st[] = doc.getSchema().getSimpleTypeArray();
-                for (int j = 0; j < st.length; j++)
-                    noteName(st[j].getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces);
+                TopLevelSimpleType[] st = doc.getSchema().getSimpleTypeArray();
+                for (TopLevelSimpleType topLevelSimpleType : st) {
+                    noteName(topLevelSimpleType.getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces);
+                }
 
-                TopLevelElement el[] = doc.getSchema().getElementArray();
-                for (int j = 0; j < el.length; j++)
-                    noteName(el[j].getName(), targetNamespace, elementNames, dupeElementNames, dupeNamespaces);
+                TopLevelElement[] el = doc.getSchema().getElementArray();
+                for (TopLevelElement topLevelElement : el) {
+                    noteName(topLevelElement.getName(), targetNamespace, elementNames, dupeElementNames, dupeNamespaces);
+                }
 
-                TopLevelAttribute at[] = doc.getSchema().getAttributeArray();
-                for (int j = 0; j < at.length; j++)
-                    noteName(at[j].getName(), targetNamespace, attributeNames, dupeAttributeNames, dupeNamespaces);
+                TopLevelAttribute[] at = doc.getSchema().getAttributeArray();
+                for (TopLevelAttribute topLevelAttribute : at) {
+                    noteName(topLevelAttribute.getName(), targetNamespace, attributeNames, dupeAttributeNames, dupeNamespaces);
+                }
 
-                NamedGroup gr[] = doc.getSchema().getGroupArray();
-                for (int j = 0; j < gr.length; j++)
-                    noteName(gr[j].getName(), targetNamespace, modelGroupNames, dupeModelGroupNames, dupeNamespaces);
+                NamedGroup[] gr = doc.getSchema().getGroupArray();
+                for (NamedGroup namedGroup : gr) {
+                    noteName(namedGroup.getName(), targetNamespace, modelGroupNames, dupeModelGroupNames, dupeNamespaces);
+                }
 
-                NamedAttributeGroup ag[] = doc.getSchema().getAttributeGroupArray();
-                for (int j = 0; j < ag.length; j++)
-                    noteName(ag[j].getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames, dupeNamespaces);
+                NamedAttributeGroup[] ag = doc.getSchema().getAttributeGroupArray();
+                for (NamedAttributeGroup namedAttributeGroup : ag) {
+                    noteName(namedAttributeGroup.getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames, dupeNamespaces);
+                }
 
-            }
-            catch (XmlException e)
-            {
-                System.out.println("warning: " + files[i] + " is not a schema file - " + e.getError().toString());
-            }
-            catch (IOException e)
-            {
-                System.err.println("Unable to load " + files[i] + " - " + e.getMessage());
+            } catch (XmlException e) {
+                System.out.println("warning: " + file + " is not a schema file - " + e.getError().toString());
+            } catch (IOException e) {
+                System.err.println("Unable to load " + file + " - " + e.getMessage());
                 System.exit(1);
                 return;
             }
         }
 
-        if (schemaDocs.size() == 0)
-        {
+        if (schemaDocs.size() == 0) {
             System.out.println("No schema files found.");
             System.exit(0);
             return;
         }
 
         if (dupeTypeNames.size() + dupeElementNames.size() + dupeAttributeNames.size() +
-                dupeModelGroupNames.size() + dupeAttrGroupNames.size() == 0)
-        {
+            dupeModelGroupNames.size() + dupeAttrGroupNames.size() == 0) {
             System.out.println("No duplicate names found.");
             System.exit(0);
             return;
         }
 
         // create a schema doc for each namespace to be imported
-        Map commonDocs = new HashMap();
-        Map commonFiles = new HashMap();
+        Map<String,SchemaDocument> commonDocs = new HashMap<>();
+        Map<SchemaDocument,File> commonFiles = new HashMap<>();
         int count = dupeNamespaces.size() == 1 ? 0 : 1;
-        for (Iterator i = dupeNamespaces.iterator(); i.hasNext(); )
-        {
-            String namespace = (String)i.next();
+        for (String namespace : dupeNamespaces) {
             SchemaDocument commonDoc = SchemaDocument.Factory.parse(
-                    "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'/>"
+                "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'/>"
             );
-            if (namespace.length() > 0)
+            if (namespace.length() > 0) {
                 commonDoc.getSchema().setTargetNamespace(namespace);
+            }
             commonDoc.getSchema().setElementFormDefault(FormChoice.QUALIFIED);
             commonDocs.put(namespace, commonDoc);
             commonFiles.put(commonDoc, commonFileFor(commonName, namespace, count++, outdir));
@@ -231,132 +208,130 @@
         // pull out all the duplicate definitions and drop them into the file
         // we reuse the elementNames (etc) sets to keep track of which definitions
         // we have already inserted.
-        for (Iterator i = schemaDocs.keySet().iterator(); i.hasNext(); )
-        {
-            SchemaDocument doc = (SchemaDocument)i.next();
-
+        for (SchemaDocument doc : schemaDocs.keySet()) {
             // collect together names
             String targetNamespace = doc.getSchema().getTargetNamespace();
-            if (targetNamespace == null)
+            if (targetNamespace == null) {
                 targetNamespace = "";
+            }
 
-            SchemaDocument commonDoc = (SchemaDocument)commonDocs.get(targetNamespace);
+            SchemaDocument commonDoc = commonDocs.get(targetNamespace);
 
             boolean needImport = false;
 
-            TopLevelComplexType ct[] = doc.getSchema().getComplexTypeArray();
-            for (int j = ct.length - 1; j >= 0; j--)
-            {
-                if (!isDuplicate(ct[j].getName(), targetNamespace, dupeTypeNames))
+            TopLevelComplexType[] ct = doc.getSchema().getComplexTypeArray();
+            for (int j = ct.length - 1; j >= 0; j--) {
+                if (!isDuplicate(ct[j].getName(), targetNamespace, dupeTypeNames)) {
                     continue;
-                if (isFirstDuplicate(ct[j].getName(), targetNamespace, typeNames, dupeTypeNames))
+                }
+                if (isFirstDuplicate(ct[j].getName(), targetNamespace, typeNames, dupeTypeNames)) {
                     commonDoc.getSchema().addNewComplexType().set(ct[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeComplexType(j);
             }
 
-            TopLevelSimpleType st[] = doc.getSchema().getSimpleTypeArray();
-            for (int j = 0; j < st.length; j++)
-            {
-                if (!isDuplicate(st[j].getName(), targetNamespace, dupeTypeNames))
+            TopLevelSimpleType[] st = doc.getSchema().getSimpleTypeArray();
+            for (int j = 0; j < st.length; j++) {
+                if (!isDuplicate(st[j].getName(), targetNamespace, dupeTypeNames)) {
                     continue;
-                if (isFirstDuplicate(st[j].getName(), targetNamespace, typeNames, dupeTypeNames))
+                }
+                if (isFirstDuplicate(st[j].getName(), targetNamespace, typeNames, dupeTypeNames)) {
                     commonDoc.getSchema().addNewSimpleType().set(st[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeSimpleType(j);
             }
 
-            TopLevelElement el[] = doc.getSchema().getElementArray();
-            for (int j = 0; j < el.length; j++)
-            {
-                if (!isDuplicate(el[j].getName(), targetNamespace, dupeElementNames))
+            TopLevelElement[] el = doc.getSchema().getElementArray();
+            for (int j = 0; j < el.length; j++) {
+                if (!isDuplicate(el[j].getName(), targetNamespace, dupeElementNames)) {
                     continue;
-                if (isFirstDuplicate(el[j].getName(), targetNamespace, elementNames, dupeElementNames))
+                }
+                if (isFirstDuplicate(el[j].getName(), targetNamespace, elementNames, dupeElementNames)) {
                     commonDoc.getSchema().addNewElement().set(el[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeElement(j);
             }
 
-            TopLevelAttribute at[] = doc.getSchema().getAttributeArray();
-            for (int j = 0; j < at.length; j++)
-            {
-                if (!isDuplicate(at[j].getName(), targetNamespace, dupeAttributeNames))
+            TopLevelAttribute[] at = doc.getSchema().getAttributeArray();
+            for (int j = 0; j < at.length; j++) {
+                if (!isDuplicate(at[j].getName(), targetNamespace, dupeAttributeNames)) {
                     continue;
-                if (isFirstDuplicate(at[j].getName(), targetNamespace, attributeNames, dupeAttributeNames))
+                }
+                if (isFirstDuplicate(at[j].getName(), targetNamespace, attributeNames, dupeAttributeNames)) {
                     commonDoc.getSchema().addNewElement().set(at[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeElement(j);
             }
 
-            NamedGroup gr[] = doc.getSchema().getGroupArray();
-            for (int j = 0; j < gr.length; j++)
-            {
-                if (!isDuplicate(gr[j].getName(), targetNamespace, dupeModelGroupNames))
+            NamedGroup[] gr = doc.getSchema().getGroupArray();
+            for (int j = 0; j < gr.length; j++) {
+                if (!isDuplicate(gr[j].getName(), targetNamespace, dupeModelGroupNames)) {
                     continue;
-                if (isFirstDuplicate(gr[j].getName(), targetNamespace, modelGroupNames, dupeModelGroupNames))
+                }
+                if (isFirstDuplicate(gr[j].getName(), targetNamespace, modelGroupNames, dupeModelGroupNames)) {
                     commonDoc.getSchema().addNewElement().set(gr[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeElement(j);
             }
 
-            NamedAttributeGroup ag[] = doc.getSchema().getAttributeGroupArray();
-            for (int j = 0; j < ag.length; j++)
-            {
-                if (!isDuplicate(ag[j].getName(), targetNamespace, dupeAttrGroupNames))
+            NamedAttributeGroup[] ag = doc.getSchema().getAttributeGroupArray();
+            for (int j = 0; j < ag.length; j++) {
+                if (!isDuplicate(ag[j].getName(), targetNamespace, dupeAttrGroupNames)) {
                     continue;
-                if (isFirstDuplicate(ag[j].getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames))
+                }
+                if (isFirstDuplicate(ag[j].getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames)) {
                     commonDoc.getSchema().addNewElement().set(ag[j]);
+                }
                 needImport = true;
                 doc.getSchema().removeElement(j);
             }
 
-            if (needImport)
-            {
+            if (needImport) {
                 IncludeDocument.Include newInclude = doc.getSchema().addNewInclude();
-                File inputFile = (File)schemaDocs.get(doc);
+                File inputFile = (File) schemaDocs.get(doc);
                 File outputFile = outputFileFor(inputFile, basedir, outdir);
-                File commonFile = (File)commonFiles.get(commonDoc);
-                if (targetNamespace != null)
+                File commonFile = (File) commonFiles.get(commonDoc);
+                if (targetNamespace != null) {
                     newInclude.setSchemaLocation(relativeURIFor(outputFile, commonFile));
+                }
             }
         }
 
         // make the directory for output
-        if (!outdir.isDirectory() && !outdir.mkdirs())
-        {
+        if (!outdir.isDirectory() && !outdir.mkdirs()) {
             System.err.println("Unable to makedir " + outdir);
             System.exit(1);
             return;
         }
 
         // now write all those docs back out.
-        for (Iterator i = schemaDocs.keySet().iterator(); i.hasNext(); )
-        {
-            SchemaDocument doc = (SchemaDocument)i.next();
-            File inputFile = (File)schemaDocs.get(doc);
+        for (SchemaDocument doc : schemaDocs.keySet()) {
+            File inputFile = schemaDocs.get(doc);
             File outputFile = outputFileFor(inputFile, basedir, outdir);
-            if (outputFile == null)
+            if (outputFile == null) {
                 System.out.println("Cannot copy " + inputFile);
-            else
-                doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggresiveNamespaces());
+            } else {
+                doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggressiveNamespaces());
+            }
         }
 
-        for (Iterator i = commonFiles.keySet().iterator(); i.hasNext(); )
-        {
-            SchemaDocument doc = (SchemaDocument)i.next();
-            File outputFile = (File)commonFiles.get(doc);
-            doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggresiveNamespaces());
+        for (SchemaDocument doc : commonFiles.keySet()) {
+            File outputFile = commonFiles.get(doc);
+            doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggressiveNamespaces());
         }
 
     }
 
-    private static File outputFileFor(File file, File baseDir, File outdir)
-    {
+    private static File outputFileFor(File file, File baseDir, File outdir) {
         URI base = baseDir.getAbsoluteFile().toURI();
         URI abs = file.getAbsoluteFile().toURI();
         URI rel = base.relativize(abs);
-        if (rel.isAbsolute())
-        {
+        if (rel.isAbsolute()) {
             System.out.println("Cannot relativize " + file);
             return null;
         }
@@ -366,107 +341,104 @@
         return new File(out);
     }
 
-    private static URI commonAncestor(URI first, URI second)
-    {
+    private static URI commonAncestor(URI first, URI second) {
         String firstStr = first.toString();
         String secondStr = second.toString();
         int len = firstStr.length();
-        if (secondStr.length() < len)
+        if (secondStr.length() < len) {
             len = secondStr.length();
+        }
         int i;
-        for (i = 0; i < len; i++)
-        {
-            if (firstStr.charAt(i) != secondStr.charAt(i))
+        for (i = 0; i < len; i++) {
+            if (firstStr.charAt(i) != secondStr.charAt(i)) {
                 break;
+            }
         }
         i -= 1;
-        if (i >= 0)
+        if (i >= 0) {
             i = firstStr.lastIndexOf('/', i);
-        if (i < 0)
-            return null;
-        try
-        {
-            return new URI(firstStr.substring(0, i));
         }
-        catch (URISyntaxException e)
-        {
+        if (i < 0) {
+            return null;
+        }
+        try {
+            return new URI(firstStr.substring(0, i));
+        } catch (URISyntaxException e) {
             return null;
         }
     }
 
 
-    private static String relativeURIFor(File source, File target)
-    {
+    private static String relativeURIFor(File source, File target) {
         URI base = source.getAbsoluteFile().toURI();
         URI abs = target.getAbsoluteFile().toURI();
         // find common substring...
         URI commonBase = commonAncestor(base, abs);
-        if (commonBase == null)
+        if (commonBase == null) {
             return abs.toString();
+        }
 
         URI baserel = commonBase.relativize(base);
         URI targetrel = commonBase.relativize(abs);
-        if (baserel.isAbsolute() || targetrel.isAbsolute())
+        if (baserel.isAbsolute() || targetrel.isAbsolute()) {
             return abs.toString();
+        }
         String prefix = "";
         String sourceRel = baserel.toString();
-        for (int i = 0; i < sourceRel.length();)
-        {
+        for (int i = 0; i < sourceRel.length(); ) {
             i = sourceRel.indexOf('/', i);
-            if (i < 0)
+            if (i < 0) {
                 break;
+            }
             prefix += "../";
             i += 1;
         }
         return prefix + targetrel.toString();
     }
 
-    private static File commonFileFor(String commonName, String namespace, int i, File outdir)
-    {
+    private static File commonFileFor(String commonName, String namespace, int i, File outdir) {
         String name = commonName;
-        if (i > 0)
-        {
+        if (i > 0) {
             int index = commonName.lastIndexOf('.');
-            if (index < 0)
+            if (index < 0) {
                 index = commonName.length();
+            }
             name = commonName.substring(0, index) + i + commonName.substring(index);
         }
         return new File(outdir, name);
     }
 
 
-    private static void noteName(String name, String targetNamespace, Set seen, Set dupes, Set dupeNamespaces)
-    {
-        if (name == null)
+    private static void noteName(String name, String targetNamespace, Set<QName> seen, Set<QName> dupes, Set<String> dupeNamespaces) {
+        if (name == null) {
             return;
+        }
         QName qName = new QName(targetNamespace, name);
-        if (seen.contains(qName))
-        {
+        if (seen.contains(qName)) {
             dupes.add(qName);
             dupeNamespaces.add(targetNamespace);
-        }
-        else
+        } else {
             seen.add(qName);
+        }
 
     }
 
-    private static boolean isFirstDuplicate(String name, String targetNamespace, Set notseen, Set dupes)
-    {
-        if (name == null)
+    private static boolean isFirstDuplicate(String name, String targetNamespace, Set<QName> notseen, Set<QName> dupes) {
+        if (name == null) {
             return false;
+        }
         QName qName = new QName(targetNamespace, name);
-        if (dupes.contains(qName) && notseen.contains(qName))
-        {
+        if (dupes.contains(qName) && notseen.contains(qName)) {
             notseen.remove(qName);
             return true;
         }
         return false;
     }
 
-    private static boolean isDuplicate(String name, String targetNamespace, Set dupes)
-    {
-        if (name == null)
+    private static boolean isDuplicate(String name, String targetNamespace, Set<QName> dupes) {
+        if (name == null) {
             return false;
+        }
         QName qName = new QName(targetNamespace, name);
         return (dupes.contains(qName));
     }
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/InstanceValidator.java b/src/main/java/org/apache/xmlbeans/impl/tool/InstanceValidator.java
index f0e9dac..affe499 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/InstanceValidator.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/InstanceValidator.java
@@ -15,25 +15,13 @@
 
 package org.apache.xmlbeans.impl.tool;
 
-import org.apache.xmlbeans.XmlBeans;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.*;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collection;
-import java.util.Iterator;
 import java.io.File;
+import java.util.*;
 
-public class InstanceValidator
-{
-    public static void printUsage()
-    {
+public class InstanceValidator {
+    public static void printUsage() {
         System.out.println("Validates the specified instance against the specified schema.");
         System.out.println("Contrast with the svalidate tool, which validates using a stream.");
         System.out.println("Usage: validate [-dl] [-nopvr] [-noupa] [-license] schema.xsd instance.xml");
@@ -46,18 +34,17 @@
         System.out.println("    -license - prints license information");
     }
 
-    public static void main(String[] args)
-    {
+    public static void main(String[] args) {
         System.exit(extraMain(args));
     }
 
     /**
      * Use this method to avoid calling {@link java.lang.System#exit(int)}
+     *
      * @param args are command line options
      * @return exitCode
      */
-    public static int extraMain(String[] args)
-    {
+    public static int extraMain(String[] args) {
         Set flags = new HashSet();
         flags.add("h");
         flags.add("help");
@@ -72,35 +59,31 @@
 
         CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET);
 
-        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1)
-        {
+        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1) {
             printUsage();
             return 0;
         }
 
         String[] badopts = cl.getBadOpts();
-        if (badopts.length > 0)
-        {
-            for (int i = 0; i < badopts.length; i++)
+        if (badopts.length > 0) {
+            for (int i = 0; i < badopts.length; i++) {
                 System.out.println("Unrecognized option: " + badopts[i]);
+            }
             printUsage();
             return 0;
         }
 
-        if (cl.getOpt("license") != null)
-        {
+        if (cl.getOpt("license") != null) {
             CommandLine.printLicense();
             return 0;
         }
 
-        if (cl.getOpt("version") != null)
-        {
+        if (cl.getOpt("version") != null) {
             CommandLine.printVersion();
             return 0;
         }
 
-        if (cl.args().length == 0)
-        {
+        if (cl.args().length == 0) {
             return 0;
         }
 
@@ -114,108 +97,99 @@
         File[] instanceFiles = cl.filesEndingWith(".xml");
         File[] jarFiles = cl.filesEndingWith(".jar");
 
-        List sdocs = new ArrayList();
+        List<XmlObject> sdocs = new ArrayList<>();
 
 
-        for (int i = 0; i < schemaFiles.length; i++)
-        {
-            try
-            {
-                sdocs.add(
-                    XmlObject.Factory.parse(
-                        schemaFiles[i], (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest()));
-            }
-            catch (Exception e)
-            {
-                System.err.println( schemaFiles[i] + " not loadable: " + e );
+        for (File schemaFile : schemaFiles) {
+            try {
+                sdocs.add(XmlObject.Factory.parse(schemaFile, (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest()));
+            } catch (Exception e) {
+                System.err.println(schemaFile + " not loadable: " + e);
             }
         }
 
-        XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]);
+        XmlObject[] schemas = (XmlObject[]) sdocs.toArray(new XmlObject[0]);
 
         SchemaTypeLoader sLoader = null;
-        Collection compErrors = new ArrayList();
+        Collection<XmlError> compErrors = new ArrayList<>();
         XmlOptions schemaOptions = new XmlOptions();
         schemaOptions.setErrorListener(compErrors);
-        if (dl)
+        if (dl) {
             schemaOptions.setCompileDownloadUrls();
-        if (nopvr)
+        }
+        if (nopvr) {
             schemaOptions.setCompileNoPvrRule();
-        if (noupa)
+        }
+        if (noupa) {
             schemaOptions.setCompileNoUpaRule();
-        if (partial)
+        }
+        if (partial) {
             schemaOptions.put("COMPILE_PARTIAL_TYPESYSTEM");
+        }
 
-        if (jarFiles != null && jarFiles.length > 0)
+        if (jarFiles != null && jarFiles.length > 0) {
             sLoader = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(jarFiles));
+        }
 
         int returnCode = 0;
 
-        try
-        {
-            if (schemas != null && schemas.length > 0)
+        try {
+            if (schemas != null && schemas.length > 0) {
                 sLoader = XmlBeans.compileXsd(schemas, sLoader, schemaOptions);
-        }
-        catch (Exception e)
-        {
-            if (compErrors.isEmpty() || !(e instanceof XmlException))
-            {
+            }
+        } catch (Exception e) {
+            if (compErrors.isEmpty() || !(e instanceof XmlException)) {
                 e.printStackTrace(System.err);
             }
             System.out.println("Schema invalid:" + (partial ? " couldn't recover from errors" : ""));
-            for (Iterator i = compErrors.iterator(); i.hasNext(); )
-                System.out.println(i.next());
+            for (XmlError compError : compErrors) {
+                System.out.println(compError);
+            }
 
             returnCode = 10;
             return returnCode;
         }
 
         // recovered from errors, print out errors
-        if (partial && !compErrors.isEmpty())
-        {
+        if (partial && !compErrors.isEmpty()) {
             returnCode = 11;
             System.out.println("Schema invalid: partial schema type system recovered");
-            for (Iterator i = compErrors.iterator(); i.hasNext(); )
-                System.out.println(i.next());
+            for (XmlError compError : compErrors) {
+                System.out.println(compError);
+            }
         }
 
-        if (sLoader == null)
+        if (sLoader == null) {
             sLoader = XmlBeans.getContextTypeLoader();
+        }
 
-        for (int i = 0; i < instanceFiles.length; i++)
-        {
+        for (File instanceFile : instanceFiles) {
             XmlObject xobj;
 
-            try
-            {
-                xobj =
-                    sLoader.parse( instanceFiles[i], null, (new XmlOptions()).setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT) );
-            }
-            catch (Exception e)
-            {
-                System.err.println(instanceFiles[i] + " not loadable: " + e);
+            try {
+                XmlOptions xo = new XmlOptions();
+                xo.setLoadLineNumbersEndElement();
+                xobj = sLoader.parse(instanceFile, null, xo);
+            } catch (Exception e) {
+                System.err.println(instanceFile + " not loadable: " + e);
                 e.printStackTrace(System.err);
                 continue;
             }
 
-            Collection errors = new ArrayList();
+            Collection<XmlError> errors = new ArrayList<>();
 
-            if (xobj.schemaType() == XmlObject.type)
-            {
-                System.out.println(instanceFiles[i] + " NOT valid.  ");
-                System.out.println("  Document type not found." );
-            }
-            else if (xobj.validate(strict ?
+            if (xobj.schemaType() == XmlObject.type) {
+                System.out.println(instanceFile + " NOT valid.  ");
+                System.out.println("  Document type not found.");
+            } else if (xobj.validate(strict ?
                 new XmlOptions().setErrorListener(errors).setValidateStrict() :
-                new XmlOptions().setErrorListener(errors)))
-                System.out.println(instanceFiles[i] + " valid.");
-            else
-            {
+                new XmlOptions().setErrorListener(errors))) {
+                System.out.println(instanceFile + " valid.");
+            } else {
                 returnCode = 1;
-                System.out.println(instanceFiles[i] + " NOT valid.");
-                for (Iterator it = errors.iterator(); it.hasNext(); )
-                {
-                    System.out.println(it.next());
+                System.out.println(instanceFile + " NOT valid.");
+                for (XmlError error : errors) {
+                    System.out.println(error);
                 }
             }
         }
diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java b/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
index 4e10920..04d4259 100644
--- a/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
+++ b/src/main/java/org/apache/xmlbeans/impl/tool/SchemaCompiler.java
@@ -15,56 +15,26 @@
 
 package org.apache.xmlbeans.impl.tool;
 
-import org.apache.xmlbeans.SchemaCodePrinter;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.SchemaTypeSystem;
-import org.apache.xmlbeans.SystemProperties;
-import org.apache.xmlbeans.SimpleValue;
-import org.apache.xmlbeans.XmlBeans;
-import org.apache.xmlbeans.XmlErrorCodes;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.ResourceLoader;
-import org.apache.xmlbeans.impl.common.IOUtil;
-import org.apache.xmlbeans.impl.common.ResolverUtil;
-import org.apache.xmlbeans.impl.common.XmlErrorPrinter;
-import org.apache.xmlbeans.impl.common.XmlErrorWatcher;
-import org.apache.xmlbeans.impl.schema.PathResourceLoader;
-import org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl;
-import org.apache.xmlbeans.impl.schema.SchemaTypeSystemCompiler;
-import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl;
-import org.apache.xmlbeans.impl.schema.StscState;
-import org.apache.xmlbeans.impl.common.JarHelper;
+import org.apache.xmlbeans.*;
+import org.apache.xmlbeans.impl.common.*;
+import org.apache.xmlbeans.impl.config.BindingConfigImpl;
+import org.apache.xmlbeans.impl.repackage.Repackager;
+import org.apache.xmlbeans.impl.schema.*;
 import org.apache.xmlbeans.impl.util.FilerImpl;
 import org.apache.xmlbeans.impl.values.XmlListImpl;
 import org.apache.xmlbeans.impl.xb.xmlconfig.ConfigDocument;
 import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig;
 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
 import org.xml.sax.EntityResolver;
-import org.apache.xmlbeans.impl.config.BindingConfigImpl;
 
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import org.apache.xmlbeans.impl.repackage.Repackager;
+import java.util.*;
 
-public class SchemaCompiler
-{
-    public static void printUsage()
-    {
+public class SchemaCompiler {
+    public static void printUsage() {
         System.out.println("Compiles a schema into XML Bean classes and metadata.");
         System.out.println("Usage: scomp [opts] [dirs]* [schema.xsd]* [service.wsdl]* [config.xsdconfig]*");
         System.out.println("Options include:");
@@ -100,16 +70,14 @@
         System.out.println();
     }
 
-    public static void main(String[] args)
-    {
-        if (args.length == 0)
-        {
+    public static void main(String[] args) {
+        if (args.length == 0) {
             printUsage();
             System.exit(0);
             return;
         }
 
-        Set flags = new HashSet();
+        Set<String> flags = new HashSet<>();
         flags.add("h");
         flags.add("help");
         flags.add("usage");
@@ -126,7 +94,7 @@
         flags.add("srconly");
         flags.add("debug");
 
-        Set opts = new HashSet();
+        Set<String> opts = new HashSet<>();
         opts.add("out");
         opts.add("name");
         opts.add("src");
@@ -145,32 +113,29 @@
         opts.add("catalog");
         CommandLine cl = new CommandLine(args, flags, opts);
 
-        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null)
-        {
+        if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) {
             printUsage();
             System.exit(0);
             return;
         }
 
         String[] badopts = cl.getBadOpts();
-        if (badopts.length > 0)
-        {
-            for (int i = 0; i < badopts.length; i++)
-                System.out.println("Unrecognized option: " + badopts[i]);
+        if (badopts.length > 0) {
+            for (String badopt : badopts) {
+                System.out.println("Unrecognized option: " + badopt);
+            }
             printUsage();
             System.exit(0);
             return;
         }
 
-        if (cl.getOpt("license") != null)
-        {
+        if (cl.getOpt("license") != null) {
             CommandLine.printLicense();
             System.exit(0);
             return;
         }
 
-        if (cl.getOpt("version") != null)
-        {
+        if (cl.getOpt("version") != null) {
             CommandLine.printVersion();
             System.exit(0);
             return;
@@ -179,11 +144,13 @@
         args = cl.args();
         boolean verbose = (cl.getOpt("verbose") != null);
         boolean quiet = (cl.getOpt("quiet") != null);
-        if (verbose)
+        if (verbose) {
             quiet = false;
+        }
 
-        if (verbose)
+        if (verbose) {
             CommandLine.printVersion();
+        }
 
         String outputfilename = cl.getOpt("out");
 
@@ -191,15 +158,11 @@
 
         String codePrinterClass = cl.getOpt("schemaCodePrinter");
         SchemaCodePrinter codePrinter = null;
-        if (codePrinterClass != null)
-        {
-            try
-            {
+        if (codePrinterClass != null) {
+            try {
                 codePrinter = (SchemaCodePrinter)
                     Class.forName(codePrinterClass).newInstance();
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
                 System.err.println
                     ("Failed to load SchemaCodePrinter class " +
                      codePrinterClass + "; proceeding with default printer");
@@ -212,16 +175,16 @@
         boolean noUpa = (cl.getOpt("noupa") != null);
         boolean noPvr = (cl.getOpt("nopvr") != null);
         boolean noAnn = (cl.getOpt("noann") != null);
-        boolean noVDoc= (cl.getOpt("novdoc") != null);
-        boolean noExt= (cl.getOpt("noext") != null);
+        boolean noVDoc = (cl.getOpt("novdoc") != null);
+        boolean noExt = (cl.getOpt("noext") != null);
         boolean nojavac = (cl.getOpt("srconly") != null);
         boolean debug = (cl.getOpt("debug") != null);
 
         String allowmdef = cl.getOpt("allowmdef");
-        Set mdefNamespaces = (allowmdef == null ? Collections.EMPTY_SET :
-                new HashSet(Arrays.asList(XmlListImpl.split_list(allowmdef))));
+        Set<String> mdefNamespaces = (allowmdef == null ? Collections.emptySet() :
+            new HashSet<>(Arrays.asList(XmlListImpl.split_list(allowmdef))));
 
-        List extensions = new ArrayList();
+        List<Extension> extensions = new ArrayList<>();
         if (cl.getOpt("extension") != null) {
             try {
                 Extension e = new Extension();
@@ -233,19 +196,17 @@
             }
         }
 
-        if (extensions.size() > 0)
-        {
+        if (extensions.size() > 0) {
             // example: -extensionParms typeMappingFileLocation=d:\types
             if (cl.getOpt("extensionParms") != null) {
-                Extension e = (Extension) extensions.get(0);
+                Extension e = extensions.get(0);
                 // extensionParms are delimited by ';'
                 StringTokenizer parmTokens = new StringTokenizer(cl.getOpt("extensionParms"), ";");
                 while (parmTokens.hasMoreTokens()) {
                     // get name value pair for each extension parms and stick into extension parms
                     String nvPair = parmTokens.nextToken();
                     int index = nvPair.indexOf('=');
-                    if (index < 0)
-                    {
+                    if (index < 0) {
                         System.err.println("extensionParms should be name=value;name=value");
                         System.exit(1);
                     }
@@ -260,62 +221,64 @@
 
         String classesdir = cl.getOpt("d");
         File classes = null;
-        if (classesdir != null)
+        if (classesdir != null) {
             classes = new File(classesdir);
+        }
 
         String srcdir = cl.getOpt("src");
         File src = null;
-        if (srcdir != null)
+        if (srcdir != null) {
             src = new File(srcdir);
-        if (nojavac && srcdir == null && classes != null)
+        }
+        if (nojavac && srcdir == null && classes != null) {
             src = classes;
+        }
 
         // create temp directory
         File tempdir = null;
-        if (src == null || classes == null)
-        {
-            try
-            {
+        if (src == null || classes == null) {
+            try {
                 tempdir = SchemaCodeGenerator.createTempDir();
-            }
-            catch (java.io.IOException e)
-            {
+            } catch (java.io.IOException e) {
                 System.err.println("Error creating temp dir " + e);
                 System.exit(1);
             }
         }
 
         File jarfile = null;
-        if (outputfilename == null && classes == null && !nojavac)
+        if (outputfilename == null && classes == null && !nojavac) {
             outputfilename = "xmltypes.jar";
-        if (outputfilename != null)
-            jarfile = new File(outputfilename);
-
-        if (src == null)
-            src = IOUtil.createDir(tempdir, "src");
-        if (classes == null)
-            classes = IOUtil.createDir(tempdir, "classes");
-
-        File[] classpath = null;
-        String cpString = cl.getOpt("cp");
-        if (cpString != null)
-        {
-            String[] cpparts = cpString.split(File.pathSeparator);
-            List cpList = new ArrayList();
-            for (int i = 0; i < cpparts.length; i++)
-                cpList.add(new File(cpparts[i]));
-            classpath = (File[])cpList.toArray(new File[cpList.size()]);
         }
-        else
-        {
+        if (outputfilename != null) {
+            jarfile = new File(outputfilename);
+        }
+
+        if (src == null) {
+            src = IOUtil.createDir(tempdir, "src");
+        }
+        if (classes == null) {
+            classes = IOUtil.createDir(tempdir, "classes");
+        }
+
+        File[] classpath;
+        String cpString = cl.getOpt("cp");
+        if (cpString != null) {
+            String[] cpparts = cpString.split(File.pathSeparator);
+            List<File> cpList = new ArrayList<>();
+            for (String cppart : cpparts) {
+                cpList.add(new File(cppart));
+            }
+            classpath = cpList.toArray(new File[0]);
+        } else {
             classpath = CodeGenUtil.systemClasspath();
         }
 
         String javasource = cl.getOpt("javasource");
         String compiler = cl.getOpt("compiler");
         String jar = cl.getOpt("jar");
-        if (verbose && jar != null)
+        if (verbose && jar != null) {
             System.out.println("The 'jar' option is no longer supported.");
+        }
 
         String memoryInitialSize = cl.getOpt("ms");
         String memoryMaximumSize = cl.getOpt("mx");
@@ -326,8 +289,7 @@
         File[] configFiles = cl.filesEndingWith(".xsdconfig");
         URL[] urlFiles = cl.getURLs();
 
-        if (xsdFiles.length + wsdlFiles.length + urlFiles.length == 0)
-        {
+        if (xsdFiles.length + wsdlFiles.length + urlFiles.length == 0) {
             System.out.println("Could not find any xsd or wsdl files to process.");
             System.exit(0);
         }
@@ -373,17 +335,18 @@
 
         boolean result = compile(params);
 
-        if (tempdir != null)
+        if (tempdir != null) {
             SchemaCodeGenerator.tryHardToDelete(tempdir);
+        }
 
-        if (!result)
+        if (!result) {
             System.exit(1);
+        }
 
         System.exit(0);
     }
 
-    public static class Parameters
-    {
+    public static class Parameters {
         private File baseDir;
         private File[] xsdFiles;
         private File[] wsdlFiles;
@@ -403,7 +366,7 @@
         private boolean quiet;
         private boolean verbose;
         private boolean download;
-        private Collection errorListener;
+        private Collection<XmlError> errorListener;
         private boolean noUpa;
         private boolean noPvr;
         private boolean noAnn;
@@ -412,339 +375,279 @@
         private boolean debug;
         private boolean incrementalSrcGen;
         private String repackage;
-        private List extensions = Collections.EMPTY_LIST;
-        private Set mdefNamespaces = Collections.EMPTY_SET;
+        private List<Extension> extensions = Collections.emptyList();
+        private Set<String> mdefNamespaces = Collections.emptySet();
         private String catalogFile;
         private SchemaCodePrinter schemaCodePrinter;
         private EntityResolver entityResolver;
 
-        public File getBaseDir()
-        {
+        public File getBaseDir() {
             return baseDir;
         }
 
-        public void setBaseDir(File baseDir)
-        {
+        public void setBaseDir(File baseDir) {
             this.baseDir = baseDir;
         }
 
-        public File[] getXsdFiles()
-        {
+        public File[] getXsdFiles() {
             return xsdFiles;
         }
 
-        public void setXsdFiles(File[] xsdFiles)
-        {
+        public void setXsdFiles(File[] xsdFiles) {
             this.xsdFiles = xsdFiles;
         }
 
-        public File[] getWsdlFiles()
-        {
+        public File[] getWsdlFiles() {
             return wsdlFiles;
         }
 
-        public void setWsdlFiles(File[] wsdlFiles)
-        {
+        public void setWsdlFiles(File[] wsdlFiles) {
             this.wsdlFiles = wsdlFiles;
         }
 
-        public File[] getJavaFiles()
-        {
+        public File[] getJavaFiles() {
             return javaFiles;
         }
 
-        public void setJavaFiles(File[] javaFiles)
-        {
+        public void setJavaFiles(File[] javaFiles) {
             this.javaFiles = javaFiles;
         }
 
-        public File[] getConfigFiles()
-        {
+        public File[] getConfigFiles() {
             return configFiles;
         }
 
-        public void setConfigFiles(File[] configFiles)
-        {
+        public void setConfigFiles(File[] configFiles) {
             this.configFiles = configFiles;
         }
 
-        public URL[] getUrlFiles()
-        {
+        public URL[] getUrlFiles() {
             return urlFiles;
         }
 
-        public void setUrlFiles(URL[] urlFiles)
-        {
+        public void setUrlFiles(URL[] urlFiles) {
             this.urlFiles = urlFiles;
         }
 
-        public File[] getClasspath()
-        {
+        public File[] getClasspath() {
             return classpath;
         }
 
-        public void setClasspath(File[] classpath)
-        {
+        public void setClasspath(File[] classpath) {
             this.classpath = classpath;
         }
 
-        public File getOutputJar()
-        {
+        public File getOutputJar() {
             return outputJar;
         }
 
-        public void setOutputJar(File outputJar)
-        {
+        public void setOutputJar(File outputJar) {
             this.outputJar = outputJar;
         }
 
-        public String getName()
-        {
+        public String getName() {
             return name;
         }
 
-        public void setName(String name)
-        {
+        public void setName(String name) {
             this.name = name;
         }
 
-        public File getSrcDir()
-        {
+        public File getSrcDir() {
             return srcDir;
         }
 
-        public void setSrcDir(File srcDir)
-        {
+        public void setSrcDir(File srcDir) {
             this.srcDir = srcDir;
         }
 
-        public File getClassesDir()
-        {
+        public File getClassesDir() {
             return classesDir;
         }
 
-        public void setClassesDir(File classesDir)
-        {
+        public void setClassesDir(File classesDir) {
             this.classesDir = classesDir;
         }
 
-        public boolean isNojavac()
-        {
+        public boolean isNojavac() {
             return nojavac;
         }
 
-        public void setNojavac(boolean nojavac)
-        {
+        public void setNojavac(boolean nojavac) {
             this.nojavac = nojavac;
         }
 
-        public boolean isQuiet()
-        {
+        public boolean isQuiet() {
             return quiet;
         }
 
-        public void setQuiet(boolean quiet)
-        {
+        public void setQuiet(boolean quiet) {
             this.quiet = quiet;
         }
 
-        public boolean isVerbose()
-        {
+        public boolean isVerbose() {
             return verbose;
         }
 
-        public void setVerbose(boolean verbose)
-        {
+        public void setVerbose(boolean verbose) {
             this.verbose = verbose;
         }
 
-        public boolean isDownload()
-        {
+        public boolean isDownload() {
             return download;
         }
 
-        public void setDownload(boolean download)
-        {
+        public void setDownload(boolean download) {
             this.download = download;
         }
 
-        public boolean isNoUpa()
-        {
+        public boolean isNoUpa() {
             return noUpa;
         }
 
-        public void setNoUpa(boolean noUpa)
-        {
+        public void setNoUpa(boolean noUpa) {
             this.noUpa = noUpa;
         }
 
-        public boolean isNoPvr()
-        {
+        public boolean isNoPvr() {
             return noPvr;
         }
 
-        public void setNoPvr(boolean noPvr)
-        {
+        public void setNoPvr(boolean noPvr) {
             this.noPvr = noPvr;
         }
 
-        public boolean isNoAnn()
-        {
+        public boolean isNoAnn() {
             return noAnn;
         }
 
-        public void setNoAnn(boolean noAnn)
-        {
+        public void setNoAnn(boolean noAnn) {
             this.noAnn = noAnn;
         }
 
-        public boolean isNoVDoc()
-        {
+        public boolean isNoVDoc() {
             return noVDoc;
         }
 
-        public void setNoVDoc(boolean newNoVDoc)
-        {
+        public void setNoVDoc(boolean newNoVDoc) {
             this.noVDoc = newNoVDoc;
         }
 
-        public boolean isNoExt()
-        {
+        public boolean isNoExt() {
             return noExt;
         }
 
-        public void setNoExt(boolean newNoExt)
-        {
+        public void setNoExt(boolean newNoExt) {
             this.noExt = newNoExt;
         }
 
-        public boolean isIncrementalSrcGen()
-        {
+        public boolean isIncrementalSrcGen() {
             return incrementalSrcGen;
         }
 
-        public void setIncrementalSrcGen(boolean incrSrcGen)
-        {
+        public void setIncrementalSrcGen(boolean incrSrcGen) {
             this.incrementalSrcGen = incrSrcGen;
         }
 
-        public boolean isDebug()
-        {
+        public boolean isDebug() {
             return debug;
         }
 
-        public void setDebug(boolean debug)
-        {
+        public void setDebug(boolean debug) {
             this.debug = debug;
         }
 
-        public String getMemoryInitialSize()
-        {
+        public String getMemoryInitialSize() {
             return memoryInitialSize;
         }
 
-        public void setMemoryInitialSize(String memoryInitialSize)
-        {
+        public void setMemoryInitialSize(String memoryInitialSize) {
             this.memoryInitialSize = memoryInitialSize;
         }
 
-        public String getMemoryMaximumSize()
-        {
+        public String getMemoryMaximumSize() {
             return memoryMaximumSize;
         }
 
-        public void setMemoryMaximumSize(String memoryMaximumSize)
-        {
+        public void setMemoryMaximumSize(String memoryMaximumSize) {
             this.memoryMaximumSize = memoryMaximumSize;
         }
 
-        public String getCompiler()
-        {
+        public String getCompiler() {
             return compiler;
         }
 
-        public void setCompiler(String compiler)
-        {
+        public void setCompiler(String compiler) {
             this.compiler = compiler;
         }
 
-        public String getJavaSource()
-        {
+        public String getJavaSource() {
             return javasource;
         }
 
-        public void setJavaSource(String javasource)
-        {
+        public void setJavaSource(String javasource) {
             this.javasource = javasource;
         }
 
-        /** @deprecated */
-        public String getJar()
-        {
+        /**
+         * @deprecated
+         */
+        public String getJar() {
             return null;
         }
 
-        /** @deprecated */
-        public void setJar(String jar)
-        {
+        /**
+         * @deprecated
+         */
+        public void setJar(String jar) {
             // no op
         }
 
-        public Collection getErrorListener()
-        {
+        public Collection<XmlError> getErrorListener() {
             return errorListener;
         }
 
-        public void setErrorListener(Collection errorListener)
-        {
+        public void setErrorListener(Collection<XmlError> errorListener) {
             this.errorListener = errorListener;
         }
 
-        public String getRepackage()
-        {
+        public String getRepackage() {
             return repackage;
         }
 
-        public void setRepackage(String newRepackage)
-        {
+        public void setRepackage(String newRepackage) {
             repackage = newRepackage;
         }
 
-        public List getExtensions() {
+        public List<Extension> getExtensions() {
             return extensions;
         }
 
-        public void setExtensions(List extensions) {
+        public void setExtensions(List<Extension> extensions) {
             this.extensions = extensions;
         }
 
-        public Set getMdefNamespaces()
-        {
+        public Set<String> getMdefNamespaces() {
             return mdefNamespaces;
         }
 
-        public void setMdefNamespaces(Set mdefNamespaces)
-        {
+        public void setMdefNamespaces(Set<String> mdefNamespaces) {
             this.mdefNamespaces = mdefNamespaces;
         }
 
-        public String getCatalogFile()
-        {
+        public String getCatalogFile() {
             return catalogFile;
         }
 
-        public void setCatalogFile(String catalogPropFile)
-        {
+        public void setCatalogFile(String catalogPropFile) {
             this.catalogFile = catalogPropFile;
         }
 
-        public SchemaCodePrinter getSchemaCodePrinter()
-        {
+        public SchemaCodePrinter getSchemaCodePrinter() {
             return schemaCodePrinter;
         }
 
-        public void setSchemaCodePrinter(SchemaCodePrinter schemaCodePrinter)
-        {
+        public void setSchemaCodePrinter(SchemaCodePrinter schemaCodePrinter) {
             this.schemaCodePrinter = schemaCodePrinter;
         }
 
@@ -758,11 +661,10 @@
     }
 
     private static SchemaTypeSystem loadTypeSystem(String name, File[] xsdFiles, File[] wsdlFiles, URL[] urlFiles, File[] configFiles,
-        File[] javaFiles, ResourceLoader cpResourceLoader,
-        boolean download, boolean noUpa, boolean noPvr, boolean noAnn, boolean noVDoc, boolean noExt,
-        Set mdefNamespaces, File baseDir, Map sourcesToCopyMap,
-        Collection outerErrorListener, File schemasDir, EntityResolver entResolver, File[] classpath, String javasource)
-    {
+                                                   File[] javaFiles, ResourceLoader cpResourceLoader,
+                                                   boolean download, boolean noUpa, boolean noPvr, boolean noAnn, boolean noVDoc, boolean noExt,
+                                                   Set<String> mdefNamespaces, File baseDir, Map sourcesToCopyMap,
+                                                   Collection<XmlError> outerErrorListener, File schemasDir, EntityResolver entResolver, File[] classpath, String javasource) {
         XmlErrorWatcher errorListener = new XmlErrorWatcher(outerErrorListener);
 
         // construct the state (have to initialize early in case of errors)
@@ -779,56 +681,56 @@
             SchemaTypeLoader loader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader());
 
             // step 1, parse all the XSD files.
-            ArrayList scontentlist = new ArrayList();
+            ArrayList<SchemaDocument.Schema> scontentlist = new ArrayList<>();
             if (xsdFiles != null) {
-                for (int i = 0; i < xsdFiles.length; i++) {
+                for (File xsdFile : xsdFiles) {
                     try {
                         XmlOptions options = new XmlOptions();
                         options.setLoadLineNumbers();
                         options.setLoadMessageDigest();
                         options.setEntityResolver(entResolver);
 
-                        XmlObject schemadoc = loader.parse(xsdFiles[i], null, options);
+                        XmlObject schemadoc = loader.parse(xsdFile, null, options);
                         if (!(schemadoc instanceof SchemaDocument)) {
                             StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE,
-                                    new Object[]{xsdFiles[i], "schema"}, schemadoc);
+                                new Object[]{xsdFile, "schema"}, schemadoc);
                         } else {
-                            addSchema(xsdFiles[i].toString(), (SchemaDocument) schemadoc,
-                                    errorListener, noVDoc, scontentlist);
+                            addSchema(xsdFile.toString(), (SchemaDocument) schemadoc,
+                                errorListener, noVDoc, scontentlist);
                         }
                     } catch (XmlException e) {
                         errorListener.add(e.getError());
                     } catch (Exception e) {
                         StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE,
-                                new Object[]{"xsd", xsdFiles[i], e.getMessage()}, xsdFiles[i]);
+                            new Object[]{"xsd", xsdFile, e.getMessage()}, xsdFile);
                     }
                 }
             }
 
             // step 2, parse all WSDL files
             if (wsdlFiles != null) {
-                for (int i = 0; i < wsdlFiles.length; i++) {
+                for (File wsdlFile : wsdlFiles) {
                     try {
                         XmlOptions options = new XmlOptions();
                         options.setLoadLineNumbers();
                         options.setLoadSubstituteNamespaces(Collections.singletonMap(
-                                "http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst"
+                            "http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst"
                         ));
                         options.setEntityResolver(entResolver);
 
-                        XmlObject wsdldoc = loader.parse(wsdlFiles[i], null, options);
+                        XmlObject wsdldoc = loader.parse(wsdlFile, null, options);
 
-                        if (!(wsdldoc instanceof org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument))
+                        if (!(wsdldoc instanceof org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)) {
                             StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE,
-                                    new Object[]{wsdlFiles[i], "wsdl"}, wsdldoc);
-                        else {
-                            addWsdlSchemas(wsdlFiles[i].toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument) wsdldoc, errorListener, noVDoc, scontentlist);
+                                new Object[]{wsdlFile, "wsdl"}, wsdldoc);
+                        } else {
+                            addWsdlSchemas(wsdlFile.toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument) wsdldoc, errorListener, noVDoc, scontentlist);
                         }
                     } catch (XmlException e) {
                         errorListener.add(e.getError());
                     } catch (Exception e) {
                         StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE,
-                                new Object[]{"wsdl", wsdlFiles[i], e.getMessage()}, wsdlFiles[i]);
+                            new Object[]{"wsdl", wsdlFile, e.getMessage()}, wsdlFile);
                     }
                 }
             }
@@ -836,55 +738,56 @@
             // step 3, parse all URL files
             // XMLBEANS-58 - Ability to pass URLs instead of Files for Wsdl/Schemas
             if (urlFiles != null) {
-                for (int i = 0; i < urlFiles.length; i++) {
+                for (URL urlFile : urlFiles) {
                     try {
                         XmlOptions options = new XmlOptions();
                         options.setLoadLineNumbers();
                         options.setLoadSubstituteNamespaces(Collections.singletonMap("http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst"));
                         options.setEntityResolver(entResolver);
 
-                        XmlObject urldoc = loader.parse(urlFiles[i], null, options);
+                        XmlObject urldoc = loader.parse(urlFile, null, options);
 
                         if ((urldoc instanceof org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)) {
-                            addWsdlSchemas(urlFiles[i].toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument) urldoc, errorListener, noVDoc, scontentlist);
+                            addWsdlSchemas(urlFile.toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument) urldoc, errorListener, noVDoc, scontentlist);
                         } else if ((urldoc instanceof SchemaDocument)) {
-                            addSchema(urlFiles[i].toString(), (SchemaDocument) urldoc,
-                                    errorListener, noVDoc, scontentlist);
+                            addSchema(urlFile.toString(), (SchemaDocument) urldoc,
+                                errorListener, noVDoc, scontentlist);
                         } else {
                             StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE,
-                                    new Object[]{urlFiles[i], "wsdl or schema"}, urldoc);
+                                new Object[]{urlFile, "wsdl or schema"}, urldoc);
                         }
 
                     } catch (XmlException e) {
                         errorListener.add(e.getError());
                     } catch (Exception e) {
                         StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE,
-                                new Object[]{"url", urlFiles[i], e.getMessage()}, urlFiles[i]);
+                            new Object[]{"url", urlFile, e.getMessage()}, urlFile);
                     }
                 }
             }
 
-            SchemaDocument.Schema[] sdocs = (SchemaDocument.Schema[]) scontentlist.toArray(new SchemaDocument.Schema[scontentlist.size()]);
+            SchemaDocument.Schema[] sdocs = (SchemaDocument.Schema[]) scontentlist.toArray(new SchemaDocument.Schema[0]);
 
             // now the config files.
-            ArrayList cdoclist = new ArrayList();
+            ArrayList<ConfigDocument.Config> cdoclist = new ArrayList<>();
             if (configFiles != null) {
-                if (noExt)
+                if (noExt) {
                     System.out.println("Pre/Post and Interface extensions will be ignored.");
+                }
 
-                for (int i = 0; i < configFiles.length; i++) {
+                for (File configFile : configFiles) {
                     try {
                         XmlOptions options = new XmlOptions();
-                        options.put(XmlOptions.LOAD_LINE_NUMBERS);
+                        options.setLoadLineNumbers();
                         options.setEntityResolver(entResolver);
                         options.setLoadSubstituteNamespaces(MAP_COMPATIBILITY_CONFIG_URIS);
 
-                        XmlObject configdoc = loader.parse(configFiles[i], null, options);
-                        if (!(configdoc instanceof ConfigDocument))
+                        XmlObject configdoc = loader.parse(configFile, null, options);
+                        if (!(configdoc instanceof ConfigDocument)) {
                             StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE,
-                                    new Object[]{configFiles[i], "xsd config"}, configdoc);
-                        else {
-                            StscState.addInfo(errorListener, "Loading config file " + configFiles[i]);
+                                new Object[]{configFile, "xsd config"}, configdoc);
+                        } else {
+                            StscState.addInfo(errorListener, "Loading config file " + configFile);
                             if (configdoc.validate(new XmlOptions().setErrorListener(errorListener))) {
                                 ConfigDocument.Config config = ((ConfigDocument) configdoc).getConfig();
                                 cdoclist.add(config);
@@ -898,33 +801,40 @@
                         errorListener.add(e.getError());
                     } catch (Exception e) {
                         StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE,
-                                new Object[]{"xsd config", configFiles[i], e.getMessage()}, configFiles[i]);
+                            new Object[]{"xsd config", configFile, e.getMessage()}, configFile);
                     }
                 }
             }
-            ConfigDocument.Config[] cdocs = (ConfigDocument.Config[]) cdoclist.toArray(new ConfigDocument.Config[cdoclist.size()]);
+            ConfigDocument.Config[] cdocs = cdoclist.toArray(new ConfigDocument.Config[0]);
 
             SchemaTypeLoader linkTo = SchemaTypeLoaderImpl.build(null, cpResourceLoader, null);
 
             URI baseURI = null;
-            if (baseDir != null)
+            if (baseDir != null) {
                 baseURI = baseDir.toURI();
+            }
 
             XmlOptions opts = new XmlOptions();
-            if (download)
+            if (download) {
                 opts.setCompileDownloadUrls();
-            if (noUpa)
+            }
+            if (noUpa) {
                 opts.setCompileNoUpaRule();
-            if (noPvr)
+            }
+            if (noPvr) {
                 opts.setCompileNoPvrRule();
-            if (noAnn)
+            }
+            if (noAnn) {
                 opts.setCompileNoAnnotations();
-            if (mdefNamespaces != null)
+            }
+            if (mdefNamespaces != null) {
                 opts.setCompileMdefNamespaces(mdefNamespaces);
+            }
             opts.setCompileNoValidation(); // already validated here
             opts.setEntityResolver(entResolver);
-            if (javasource != null)
+            if (javasource != null) {
                 opts.setGenerateJavaVersion(javasource);
+            }
 
             // now pass it to the main compile function
             SchemaTypeSystemCompiler.Parameters params = new SchemaTypeSystemCompiler.Parameters();
@@ -945,42 +855,40 @@
     }
 
     private static void addSchema(String name, SchemaDocument schemadoc,
-        XmlErrorWatcher errorListener, boolean noVDoc, List scontentlist)
-    {
+                                  XmlErrorWatcher errorListener, boolean noVDoc, List<SchemaDocument.Schema> scontentlist) {
         StscState.addInfo(errorListener, "Loading schema file " + name);
         XmlOptions opts = new XmlOptions().setErrorListener(errorListener);
-        if (noVDoc)
+        if (noVDoc) {
             opts.setValidateTreatLaxAsSkip();
-        if (schemadoc.validate(opts))
+        }
+        if (schemadoc.validate(opts)) {
             scontentlist.add((schemadoc).getSchema());
+        }
     }
 
     private static void addWsdlSchemas(String name,
-        org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument wsdldoc,
-        XmlErrorWatcher errorListener, boolean noVDoc, List scontentlist)
-    {
-        if (wsdlContainsEncoded(wsdldoc))
+                                       org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument wsdldoc,
+                                       XmlErrorWatcher errorListener, boolean noVDoc, List scontentlist) {
+        if (wsdlContainsEncoded(wsdldoc)) {
             StscState.addWarning(errorListener, "The WSDL " + name + " uses SOAP encoding. SOAP encoding is not compatible with literal XML Schema.", XmlErrorCodes.GENERIC_ERROR, wsdldoc);
+        }
         StscState.addInfo(errorListener, "Loading wsdl file " + name);
         XmlOptions opts = new XmlOptions().setErrorListener(errorListener);
-        if (noVDoc)
-        opts.setValidateTreatLaxAsSkip();
+        if (noVDoc) {
+            opts.setValidateTreatLaxAsSkip();
+        }
         XmlObject[] types = wsdldoc.getDefinitions().getTypesArray();
         int count = 0;
-        for (int j = 0; j < types.length; j++)
-        {
+        for (int j = 0; j < types.length; j++) {
             XmlObject[] schemas = types[j].selectPath("declare namespace xs=\"http://www.w3.org/2001/XMLSchema\" xs:schema");
-            if (schemas.length == 0)
-            {
+            if (schemas.length == 0) {
                 StscState.addWarning(errorListener, "The WSDL " + name + " did not have any schema documents in namespace 'http://www.w3.org/2001/XMLSchema'", XmlErrorCodes.GENERIC_ERROR, wsdldoc);
                 continue;
             }
 
-            for (int k = 0; k < schemas.length; k++)
-            {
+            for (int k = 0; k < schemas.length; k++) {
                 if (schemas[k] instanceof SchemaDocument.Schema &&
-                    schemas[k].validate(opts))
-                {
+                    schemas[k].validate(opts)) {
                     count++;
                     scontentlist.add(schemas[k]);
                 }
@@ -989,8 +897,7 @@
         StscState.addInfo(errorListener, "Processing " + count + " schema(s) in " + name);
     }
 
-    public static boolean compile(Parameters params)
-    {
+    public static boolean compile(Parameters params) {
         File baseDir = params.getBaseDir();
         File[] xsdFiles = params.getXsdFiles();
         File[] wsdlFiles = params.getWsdlFiles();
@@ -1021,11 +928,10 @@
 
         String repackage = params.getRepackage();
 
-        if (repackage!=null)
-        {
+        if (repackage != null) {
             SchemaTypeLoaderImpl.METADATA_PACKAGE_LOAD = SchemaTypeSystemImpl.METADATA_PACKAGE_GEN;
 
-            Repackager repackager = new Repackager( repackage );
+            Repackager repackager = new Repackager(repackage);
 
             StringBuffer sb = new StringBuffer(SchemaTypeLoaderImpl.METADATA_PACKAGE_LOAD);
             sb = repackager.repackage(sb);
@@ -1041,21 +947,24 @@
         EntityResolver cmdLineEntRes = params.getEntityResolver() == null ?
             ResolverUtil.resolverForCatalog(params.getCatalogFile()) : params.getEntityResolver();
 
-        if (srcDir == null || classesDir == null)
+        if (srcDir == null || classesDir == null) {
             throw new IllegalArgumentException("src and class gen directories may not be null.");
+        }
 
         long start = System.currentTimeMillis();
 
         // Calculate the usenames based on the relativized filenames on the filesystem
-        if (baseDir == null)
+        if (baseDir == null) {
             baseDir = new File(SystemProperties.getProperty("user.dir"));
+        }
 
         ResourceLoader cpResourceLoader = null;
 
         Map sourcesToCopyMap = new HashMap();
 
-        if (classpath != null)
+        if (classpath != null) {
             cpResourceLoader = new PathResourceLoader(classpath);
+        }
 
         boolean result = true;
 
@@ -1066,11 +975,13 @@
         SchemaTypeSystem system = loadTypeSystem(name, xsdFiles, wsdlFiles, urlFiles, configFiles,
             javaFiles, cpResourceLoader, download, noUpa, noPvr, noAnn, noVDoc, noExt, mdefNamespaces,
             baseDir, sourcesToCopyMap, errorListener, schemasDir, cmdLineEntRes, classpath, javasource);
-        if (errorListener.hasError())
+        if (errorListener.hasError()) {
             result = false;
+        }
         long finish = System.currentTimeMillis();
-        if (!quiet)
-            System.out.println("Time to build schema type system: " + ((double)(finish - start) / 1000.0) + " seconds" );
+        if (!quiet) {
+            System.out.println("Time to build schema type system: " + ((double) (finish - start) / 1000.0) + " seconds");
+        }
 
         // now code generate and compile the JAR
         if (result && system != null) // todo: don't check "result" here if we want to compile anyway, ignoring invalid schemas
@@ -1083,10 +994,12 @@
 
             // currently just for schemaCodePrinter
             XmlOptions options = new XmlOptions();
-            if (codePrinter != null)
+            if (codePrinter != null) {
                 options.setSchemaCodePrinter(codePrinter);
-            if (javasource != null)
+            }
+            if (javasource != null) {
                 options.setGenerateJavaVersion(javasource);
+            }
 
             // save .xsb files
             system.save(filer);
@@ -1094,102 +1007,88 @@
             // gen source files
             result &= SchemaTypeSystemCompiler.generateTypes(system, filer, options);
 
-            if (incrSrcGen)
-            {
+            if (incrSrcGen) {
                 // We have to delete extra source files that may be out of date
                 SchemaCodeGenerator.deleteObsoleteFiles(srcDir, srcDir,
                     new HashSet(filer.getSourceFiles()));
             }
 
-            if (result)
-            {
+            if (result) {
                 finish = System.currentTimeMillis();
-                if (!quiet)
-                    System.out.println("Time to generate code: " + ((double)(finish - start) / 1000.0) + " seconds" );
+                if (!quiet) {
+                    System.out.println("Time to generate code: " + ((double) (finish - start) / 1000.0) + " seconds");
+                }
             }
 
             // compile source
-            if (result && !nojavac)
-            {
+            if (result && !nojavac) {
                 start = System.currentTimeMillis();
 
                 List sourcefiles = filer.getSourceFiles();
 
-                if (javaFiles != null)
+                if (javaFiles != null) {
                     sourcefiles.addAll(java.util.Arrays.asList(javaFiles));
-                if (!CodeGenUtil.externalCompile(sourcefiles, classesDir, classpath, debug, compiler, javasource, memoryInitialSize, memoryMaximumSize, quiet, verbose))
+                }
+                if (!CodeGenUtil.externalCompile(sourcefiles, classesDir, classpath, debug, compiler, javasource, memoryInitialSize, memoryMaximumSize, quiet, verbose)) {
                     result = false;
+                }
 
                 finish = System.currentTimeMillis();
-                if (result && !params.isQuiet())
-                    System.out.println("Time to compile code: " + ((double)(finish - start) / 1000.0) + " seconds" );
+                if (result && !params.isQuiet()) {
+                    System.out.println("Time to compile code: " + ((double) (finish - start) / 1000.0) + " seconds");
+                }
 
                 // jar classes and .xsb
-                if (result && outputJar != null)
-                {
-                    try
-                    {
+                if (result && outputJar != null) {
+                    try {
                         new JarHelper().jarDir(classesDir, outputJar);
-                    }
-                    catch (IOException e)
-                    {
+                    } catch (IOException e) {
                         System.err.println("IO Error " + e);
                         result = false;
                     }
 
-                    if (result && !params.isQuiet())
+                    if (result && !params.isQuiet()) {
                         System.out.println("Compiled types to: " + outputJar);
+                    }
                 }
             }
         }
 
-        if (!result && !quiet)
-        {
+        if (!result && !quiet) {
             System.out.println("BUILD FAILED");
-        }
-        else {
+        } else {
             // call schema compiler extension if registered
             runExtensions(extensions, system, classesDir);
         }
 
-        if (cpResourceLoader != null)
+        if (cpResourceLoader != null) {
             cpResourceLoader.close();
+        }
         return result;
     }
 
-    private static void runExtensions(List extensions, SchemaTypeSystem system, File classesDir)
-    {
-        if (extensions != null && extensions.size() > 0)
-        {
+    private static void runExtensions(List extensions, SchemaTypeSystem system, File classesDir) {
+        if (extensions != null && extensions.size() > 0) {
             SchemaCompilerExtension sce = null;
             Iterator i = extensions.iterator();
             Map extensionParms = null;
             String classesDirName = null;
-            try
-            {
+            try {
                 classesDirName = classesDir.getCanonicalPath();
-            }
-            catch(java.io.IOException e)
-            {
+            } catch (java.io.IOException e) {
                 System.out.println("WARNING: Unable to get the path for schema jar file");
                 classesDirName = classesDir.getAbsolutePath();
             }
 
-            while (i.hasNext())
-            {
+            while (i.hasNext()) {
                 Extension extension = (Extension) i.next();
-                try
-                {
+                try {
                     sce = (SchemaCompilerExtension) extension.getClassName().newInstance();
-                }
-                catch (InstantiationException e)
-                {
+                } catch (InstantiationException e) {
                     System.out.println("UNABLE to instantiate schema compiler extension:" + extension.getClassName().getName());
                     System.out.println("EXTENSION Class was not run");
                     break;
-                }
-                catch (IllegalAccessException e)
-                {
+                } catch (IllegalAccessException e) {
                     System.out.println("ILLEGAL ACCESS Exception when attempting to instantiate schema compiler extension: " + extension.getClassName().getName());
                     System.out.println("EXTENSION Class was not run");
                     break;
@@ -1198,8 +1097,7 @@
                 System.out.println("Running Extension: " + sce.getExtensionName());
                 extensionParms = new HashMap();
                 Iterator parmsi = extension.getParams().iterator();
-                while (parmsi.hasNext())
-                {
+                while (parmsi.hasNext()) {
                     Extension.Param p = (Extension.Param) parmsi.next();
                     extensionParms.put(p.getName(), p.getValue());
                 }
@@ -1210,16 +1108,15 @@
     }
 
 
-    private static boolean wsdlContainsEncoded(XmlObject wsdldoc)
-    {
+    private static boolean wsdlContainsEncoded(XmlObject wsdldoc) {
         // search for any <soap:body use="encoded"/> etc.
         XmlObject[] useAttrs = wsdldoc.selectPath(
-                "declare namespace soap='http://schemas.xmlsoap.org/wsdl/soap/' " +
-                ".//soap:body/@use|.//soap:header/@use|.//soap:fault/@use");
-        for (int i = 0; i < useAttrs.length; i++)
-        {
-            if ("encoded".equals(((SimpleValue)useAttrs[i]).getStringValue()))
+            "declare namespace soap='http://schemas.xmlsoap.org/wsdl/soap/' " +
+            ".//soap:body/@use|.//soap:header/@use|.//soap:fault/@use");
+        for (int i = 0; i < useAttrs.length; i++) {
+            if ("encoded".equals(((SimpleValue) useAttrs[i]).getStringValue())) {
                 return true;
+            }
         }
         return false;
     }
@@ -1227,8 +1124,8 @@
     private static final String CONFIG_URI = "http://xml.apache.org/xmlbeans/2004/02/xbean/config";
     private static final String COMPATIBILITY_CONFIG_URI = "http://www.bea.com/2002/09/xbean/config";
     private static final Map MAP_COMPATIBILITY_CONFIG_URIS;
-    static
-    {
+
+    static {
         MAP_COMPATIBILITY_CONFIG_URIS = new HashMap();
         MAP_COMPATIBILITY_CONFIG_URIS.put(COMPATIBILITY_CONFIG_URI, CONFIG_URI);
     }
diff --git a/src/main/java/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java b/src/main/java/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java
index 614dc3b..3f5cc67 100644
--- a/src/main/java/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java
+++ b/src/main/java/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java
@@ -15,69 +15,56 @@
 
 package org.apache.xmlbeans.impl.validator;
 
-import org.apache.xmlbeans.impl.common.XMLNameHelper;
+import org.apache.xmlbeans.*;
 import org.apache.xmlbeans.impl.common.GenericXmlInputStream;
-import org.apache.xmlbeans.impl.common.ValidatorListener.Event;
 import org.apache.xmlbeans.impl.common.ValidatorListener;
+import org.apache.xmlbeans.impl.common.ValidatorListener.Event;
+import org.apache.xmlbeans.impl.common.XMLNameHelper;
 import org.apache.xmlbeans.impl.common.XmlWhitespace;
 import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem;
-import org.apache.xmlbeans.SchemaType;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlError;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XMLStreamValidationException;
-import java.util.Map;
-import java.util.AbstractCollection;
-import java.util.Iterator;
-import java.util.Collections;
-
-import org.apache.xmlbeans.xml.stream.Attribute;
-import org.apache.xmlbeans.xml.stream.AttributeIterator;
 import org.apache.xmlbeans.xml.stream.CharacterData;
-import org.apache.xmlbeans.xml.stream.StartElement;
-import org.apache.xmlbeans.xml.stream.XMLEvent;
-import org.apache.xmlbeans.xml.stream.XMLInputStream;
-import org.apache.xmlbeans.xml.stream.XMLName;
-import org.apache.xmlbeans.xml.stream.XMLStreamException;
+import org.apache.xmlbeans.xml.stream.*;
+
 import javax.xml.namespace.QName;
+import java.util.AbstractCollection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
 
 /**
  * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
  */
 public final class ValidatingXMLInputStream
-    extends GenericXmlInputStream implements Event
-{
-    public ValidatingXMLInputStream (
+    extends GenericXmlInputStream implements Event {
+    public ValidatingXMLInputStream(
         XMLInputStream xis,
-        SchemaTypeLoader typeLoader, SchemaType sType, XmlOptions options )
-            throws XMLStreamException
-    {
+        SchemaTypeLoader typeLoader, SchemaType sType, XmlOptions options)
+        throws XMLStreamException {
         _source = xis;
 
         // Figure out the root type
 
-        options = XmlOptions.maskNull( options );
-        
-        SchemaType type = (SchemaType) options.get( XmlOptions.DOCUMENT_TYPE );
+        options = XmlOptions.maskNull(options);
 
-        if (type == null)
+        SchemaType type = options.getDocumentType();
+
+        if (type == null) {
             type = sType;
+        }
 
-        if (type == null)
-        {
+        if (type == null) {
             type = BuiltinSchemaTypeSystem.ST_ANY_TYPE;
 
             xis = xis.getSubStream();
 
-            if (xis.skip( XMLEvent.START_ELEMENT ))
-            {
+            if (xis.skip(XMLEvent.START_ELEMENT)) {
                 SchemaType docType =
                     typeLoader.findDocumentType(
-                        XMLNameHelper.getQName( xis.next().getName() ) );
+                        XMLNameHelper.getQName(xis.next().getName()));
 
-                if (docType != null)
+                if (docType != null) {
                     type = docType;
+                }
             }
 
             xis.close();
@@ -87,303 +74,277 @@
 
         _validator =
             new Validator(
-                type, null, typeLoader, options, new ExceptionXmlErrorListener() );
+                type, null, typeLoader, options, new ExceptionXmlErrorListener());
 
-        nextEvent( ValidatorListener.BEGIN );
+        nextEvent(ValidatorListener.BEGIN);
     }
 
     // TODO - this is the quick and dirty impl of streaming validation,
     // may objects are created (like strings) which can be optimized
-    
-    protected XMLEvent nextEvent ( ) throws XMLStreamException
-    {
+
+    protected XMLEvent nextEvent() throws XMLStreamException {
         XMLEvent e = _source.next();
 
-        if (e == null)
-        {
-            if (!_finished)
-            {
+        if (e == null) {
+            if (!_finished) {
                 flushText();
-                nextEvent( ValidatorListener.END );
+                nextEvent(ValidatorListener.END);
                 _finished = true;
             }
-        }
-        else
-        {
-            switch ( e.getType() )
-            {
-            case XMLEvent.CHARACTER_DATA :
-            case XMLEvent.SPACE :
-            {
-                CharacterData cd = (CharacterData) e;
+        } else {
+            switch (e.getType()) {
+                case XMLEvent.CHARACTER_DATA:
+                case XMLEvent.SPACE: {
+                    CharacterData cd = (CharacterData) e;
 
-                if (cd.hasContent())
-                    _text.append( cd.getContent() );
-
-                break;
-            }
-            case XMLEvent.START_ELEMENT :
-            {
-                StartElement se = (StartElement) e;
-                
-                flushText();
-
-                // Used for prefix to namespace mapping
-                _startElement = se;
-
-                // Prepare the xsi:* values
-                
-                AttributeIterator attrs = se.getAttributes();
-
-                while ( attrs.hasNext() )
-                {
-                    Attribute attr = attrs.next();
-
-                    XMLName attrName = attr.getName();
-
-                    if ("http://www.w3.org/2001/XMLSchema-instance".equals(
-                            attrName.getNamespaceUri() ))
-                    {
-                        String local = attrName.getLocalName();
-
-                        if (local.equals( "type" ))
-                            _xsiType = attr.getValue();
-                        else if (local.equals( "nil" ))
-                            _xsiNil = attr.getValue();
-                        else if (local.equals( "schemaLocation" ))
-                            _xsiLoc = attr.getValue();
-                        else if (local.equals( "noNamespaceSchemaLocation" ))
-                            _xsiNoLoc = attr.getValue();
-                    }
-                }
-
-                // Emit the START
-
-                // TODO - should delay the aquisition of the name
-                _name = e.getName();
-
-                nextEvent( ValidatorListener.BEGIN );
-                
-                // Emit the attrs
-                
-                attrs = se.getAttributes();
-
-                while ( attrs.hasNext() )
-                {
-                    Attribute attr = attrs.next();
-
-                    XMLName attrName = attr.getName();
-
-                    if ("http://www.w3.org/2001/XMLSchema-instance".equals(
-                            attrName.getNamespaceUri() ))
-                    {
-                        String local = attrName.getLocalName();
-
-                        if (local.equals( "type" ))
-                            continue;
-                        else if (local.equals( "nil" ))
-                            continue;
-                        else if (local.equals( "schemaLocation" ))
-                            continue;
-                        else if (local.equals( "noNamespaceSchemaLocation" ))
-                            continue;
+                    if (cd.hasContent()) {
+                        _text.append(cd.getContent());
                     }
 
-                    // TODO - God, this is lame :-)
+                    break;
+                }
+                case XMLEvent.START_ELEMENT: {
+                    StartElement se = (StartElement) e;
 
-                    _text.append( attr.getValue() );
-                    _name = attr.getName();
-                    
-                    nextEvent( ValidatorListener.ATTR );
+                    flushText();
+
+                    // Used for prefix to namespace mapping
+                    _startElement = se;
+
+                    // Prepare the xsi:* values
+
+                    AttributeIterator attrs = se.getAttributes();
+
+                    while (attrs.hasNext()) {
+                        Attribute attr = attrs.next();
+
+                        XMLName attrName = attr.getName();
+
+                        if ("http://www.w3.org/2001/XMLSchema-instance".equals(
+                            attrName.getNamespaceUri())) {
+                            String local = attrName.getLocalName();
+
+                            if (local.equals("type")) {
+                                _xsiType = attr.getValue();
+                            } else if (local.equals("nil")) {
+                                _xsiNil = attr.getValue();
+                            } else if (local.equals("schemaLocation")) {
+                                _xsiLoc = attr.getValue();
+                            } else if (local.equals("noNamespaceSchemaLocation")) {
+                                _xsiNoLoc = attr.getValue();
+                            }
+                        }
+                    }
+
+                    // Emit the START
+
+                    // TODO - should delay the aquisition of the name
+                    _name = e.getName();
+
+                    nextEvent(ValidatorListener.BEGIN);
+
+                    // Emit the attrs
+
+                    attrs = se.getAttributes();
+
+                    while (attrs.hasNext()) {
+                        Attribute attr = attrs.next();
+
+                        XMLName attrName = attr.getName();
+
+                        if ("http://www.w3.org/2001/XMLSchema-instance".equals(
+                            attrName.getNamespaceUri())) {
+                            String local = attrName.getLocalName();
+
+                            if (local.equals("type")) {
+                                continue;
+                            } else if (local.equals("nil")) {
+                                continue;
+                            } else if (local.equals("schemaLocation")) {
+                                continue;
+                            } else if (local.equals("noNamespaceSchemaLocation")) {
+                                continue;
+                            }
+                        }
+
+                        // TODO - God, this is lame :-)
+
+                        _text.append(attr.getValue());
+                        _name = attr.getName();
+
+                        nextEvent(ValidatorListener.ATTR);
+                    }
+
+                    clearText();
+
+                    _startElement = null;
+
+                    break;
                 }
 
-                clearText();
+                case XMLEvent.END_ELEMENT: {
+                    flushText();
 
-                _startElement = null;
+                    nextEvent(ValidatorListener.END);
 
-                break;
-            }
-
-            case XMLEvent.END_ELEMENT :
-            {
-                flushText();
-                
-                nextEvent( ValidatorListener.END );
-
-                break;
-            }
+                    break;
+                }
             }
         }
 
         return e;
     }
 
-    private void clearText ( )
-    {
-        _text.delete( 0, _text.length() );
+    private void clearText() {
+        _text.delete(0, _text.length());
     }
-    
-    private void flushText ( ) throws XMLStreamException
-    {
-        if (_text.length() > 0)
-        {
-            nextEvent( ValidatorListener.TEXT );
+
+    private void flushText() throws XMLStreamException {
+        if (_text.length() > 0) {
+            nextEvent(ValidatorListener.TEXT);
             clearText();
         }
     }
-    
-    public String getNamespaceForPrefix ( String prefix )
-    {
-        if (_startElement == null)
+
+    public String getNamespaceForPrefix(String prefix) {
+        if (_startElement == null) {
             return null;
+        }
 
         Map map = _startElement.getNamespaceMap();
 
-        if (map == null)
+        if (map == null) {
             return null;
+        }
 
-        return (String) map.get( prefix );
+        return (String) map.get(prefix);
     }
 
-    public XmlCursor getLocationAsCursor ( )
-    {
+    public XmlCursor getLocationAsCursor() {
         return null;
     }
 
-    public javax.xml.stream.Location getLocation()
-    {
-        try
-        {
+    public javax.xml.stream.Location getLocation() {
+        try {
             final org.apache.xmlbeans.xml.stream.Location xeLoc = _source.peek().getLocation();
 
-            if (xeLoc==null)
+            if (xeLoc == null) {
                 return null;
+            }
 
-            javax.xml.stream.Location loc = new javax.xml.stream.Location()
-            {
-                public int getLineNumber()
-                { return xeLoc.getLineNumber(); }
+            javax.xml.stream.Location loc = new javax.xml.stream.Location() {
+                public int getLineNumber() {
+                    return xeLoc.getLineNumber();
+                }
 
-                public int getColumnNumber()
-                { return xeLoc.getColumnNumber(); }
+                public int getColumnNumber() {
+                    return xeLoc.getColumnNumber();
+                }
 
-                public int getCharacterOffset()
-                { return -1;}
+                public int getCharacterOffset() {
+                    return -1;
+                }
 
-                public String getPublicId()
-                { return xeLoc.getPublicId(); }
+                public String getPublicId() {
+                    return xeLoc.getPublicId();
+                }
 
-                public String getSystemId()
-                { return xeLoc.getSystemId(); }
+                public String getSystemId() {
+                    return xeLoc.getSystemId();
+                }
             };
 
             return loc;
-        }
-        catch (XMLStreamException e)
-        {
+        } catch (XMLStreamException e) {
             return null;
         }
     }
 
-    public String getXsiType ( )
-    {
+    public String getXsiType() {
         return _xsiType;
     }
-    
-    public String getXsiNil ( )
-    {
+
+    public String getXsiNil() {
         return _xsiNil;
     }
 
-    public String getXsiLoc ( )
-    {
+    public String getXsiLoc() {
         return _xsiLoc;
     }
 
-    public String getXsiNoLoc ( )
-    {
+    public String getXsiNoLoc() {
         return _xsiNoLoc;
     }
 
-    public QName getName ( )
-    {
-        return XMLNameHelper.getQName( _name );
+    public QName getName() {
+        return XMLNameHelper.getQName(_name);
     }
 
-    public String getText ( )
-    {
+    public String getText() {
         return _text.toString();
     }
 
-    public String getText ( int wsr )
-    {
-        return XmlWhitespace.collapse( _text.toString(), wsr );
+    public String getText(int wsr) {
+        return XmlWhitespace.collapse(_text.toString(), wsr);
     }
 
-    public boolean textIsWhitespace ( )
-    {
-        for ( int i = 0 ; i < _text.length() ; i++ )
-        {
-            switch ( _text.charAt( i ) )
-            {
+    public boolean textIsWhitespace() {
+        for (int i = 0; i < _text.length(); i++) {
+            switch (_text.charAt(i)) {
                 case ' ':
                 case '\n':
                 case '\r':
                 case '\t':
                     break;
 
-                default :
+                default:
                     return false;
             }
         }
-        
+
         return true;
     }
-    
-    private final class ExceptionXmlErrorListener extends AbstractCollection
-    {
-        public boolean add(Object o)
-        {
+
+    private final class ExceptionXmlErrorListener extends AbstractCollection {
+        public boolean add(Object o) {
             assert ValidatingXMLInputStream.this._exception == null;
-            
-            ValidatingXMLInputStream.this._exception = 
-                new XMLStreamValidationException( (XmlError)o );
+
+            ValidatingXMLInputStream.this._exception =
+                new XMLStreamValidationException((XmlError) o);
 
             return false;
         }
 
-        public Iterator iterator()
-        {
+        public Iterator iterator() {
             return Collections.EMPTY_LIST.iterator();
         }
 
-        public int size()
-        {
+        public int size() {
             return 0;
         }
     }
 
-    private void nextEvent ( int kind )
-        throws XMLStreamException
-    {
+    private void nextEvent(int kind)
+        throws XMLStreamException {
         assert _exception == null;
-        
-        _validator.nextEvent( kind, this );
 
-        if (_exception != null)
+        _validator.nextEvent(kind, this);
+
+        if (_exception != null) {
             throw _exception;
+        }
     }
-    
+
     private XMLStreamValidationException _exception;
 
     private XMLInputStream _source;
-    private Validator      _validator;
-    private StringBuilder   _text = new StringBuilder();
-    private boolean        _finished;
-    private String         _xsiType;
-    private String         _xsiNil;
-    private String         _xsiLoc;
-    private String         _xsiNoLoc;
-    private XMLName        _name;
-    private StartElement   _startElement;
+    private Validator _validator;
+    private StringBuilder _text = new StringBuilder();
+    private boolean _finished;
+    private String _xsiType;
+    private String _xsiNil;
+    private String _xsiLoc;
+    private String _xsiNoLoc;
+    private XMLName _name;
+    private StartElement _startElement;
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
index 5c1d5fd..724a64f 100644
--- a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
+++ b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
@@ -15,78 +15,31 @@
 
 package org.apache.xmlbeans.impl.validator;
 
-import org.apache.xmlbeans.impl.common.IdentityConstraint;
-import org.apache.xmlbeans.impl.common.QNameHelper;
-import org.apache.xmlbeans.impl.common.ValidationContext;
-import org.apache.xmlbeans.impl.common.ValidatorListener;
-import org.apache.xmlbeans.impl.common.XmlWhitespace;
-import org.apache.xmlbeans.impl.common.InvalidLexicalValueException;
-import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl;
+import org.apache.xmlbeans.*;
+import org.apache.xmlbeans.impl.common.*;
 import org.apache.xmlbeans.impl.schema.SchemaTypeImpl;
-import org.apache.xmlbeans.impl.values.JavaBase64HolderEx;
-import org.apache.xmlbeans.impl.values.JavaBooleanHolder;
-import org.apache.xmlbeans.impl.values.JavaBooleanHolderEx;
-import org.apache.xmlbeans.impl.values.JavaDecimalHolderEx;
-import org.apache.xmlbeans.impl.values.JavaDoubleHolderEx;
-import org.apache.xmlbeans.impl.values.JavaFloatHolderEx;
-import org.apache.xmlbeans.impl.values.JavaHexBinaryHolderEx;
-import org.apache.xmlbeans.impl.values.JavaNotationHolderEx;
-import org.apache.xmlbeans.impl.values.JavaQNameHolderEx;
-import org.apache.xmlbeans.impl.values.JavaStringEnumerationHolderEx;
-import org.apache.xmlbeans.impl.values.JavaUriHolderEx;
-import org.apache.xmlbeans.impl.values.NamespaceContext;
-import org.apache.xmlbeans.impl.values.XmlDateImpl;
-import org.apache.xmlbeans.impl.values.XmlDurationImpl;
-import org.apache.xmlbeans.impl.values.XmlListImpl;
-import org.apache.xmlbeans.impl.values.XmlQNameImpl;
-import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
+import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl;
 import org.apache.xmlbeans.impl.util.XsTypeConverter;
-import org.apache.xmlbeans.GDate;
-import org.apache.xmlbeans.GDuration;
-import org.apache.xmlbeans.QNameSet;
-import org.apache.xmlbeans.XmlQName;
-import org.apache.xmlbeans.SchemaAttributeModel;
-import org.apache.xmlbeans.SchemaField;
-import org.apache.xmlbeans.SchemaLocalAttribute;
-import org.apache.xmlbeans.SchemaLocalElement;
-import org.apache.xmlbeans.SchemaGlobalElement;
-import org.apache.xmlbeans.SchemaParticle;
-import org.apache.xmlbeans.SchemaType;
-import org.apache.xmlbeans.SchemaTypeLoader;
-import org.apache.xmlbeans.XmlError;
-import org.apache.xmlbeans.XmlErrorCodes;
-import org.apache.xmlbeans.XmlValidationError;
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.SimpleValue;
-import org.apache.xmlbeans.SchemaProperty;
-import org.apache.xmlbeans.XmlString;
+import org.apache.xmlbeans.impl.values.*;
 
+import javax.xml.namespace.QName;
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import javax.xml.namespace.QName;
+import java.util.*;
 
 public final class Validator
-    implements ValidatorListener
-{
-    public Validator (
+    implements ValidatorListener {
+    public Validator(
         SchemaType type, SchemaField field, SchemaTypeLoader globalLoader,
-        XmlOptions options, Collection defaultErrorListener )
-    {
+        XmlOptions options, Collection<XmlError> defaultErrorListener) {
         options = XmlOptions.maskNull(options);
-        _errorListener = (Collection) options.get(XmlOptions.ERROR_LISTENER);
-        _treatLaxAsSkip = options.hasOption(XmlOptions.VALIDATE_TREAT_LAX_AS_SKIP);
-        _strict = options.hasOption(XmlOptions.VALIDATE_STRICT);
+        _errorListener = options.getErrorListener();
+        _treatLaxAsSkip = options.isValidateTreatLaxAsSkip();
+        _strict = options.isValidateStrict();
 
-        if (_errorListener == null)
+        if (_errorListener == null) {
             _errorListener = defaultErrorListener;
+        }
 
         _constraintEngine = new IdentityConstraint(_errorListener, type.isDocumentType());
 
@@ -97,11 +50,9 @@
         _vc = new ValidatorVC();
     }
 
-    private class ValidatorVC implements ValidationContext
-    {
+    private class ValidatorVC implements ValidationContext {
         // KHK: remove this
-        public void invalid ( String message )
-        {
+        public void invalid(String message) {
             // TODO (dutta) Addtional Attributes for validation error have limited information
             //at this time but will be a part of the second round of refactoring
 
@@ -109,8 +60,7 @@
                 XmlValidationError.ATTRIBUTE_TYPE_INVALID, null);
         }
 
-        public void invalid ( String code, Object[] args )
-        {
+        public void invalid(String code, Object[] args) {
             // TODO (dutta) Addtional Attributes for validation error have limited information
             //at this time but will be a part of the second round of refactoring
 
@@ -121,57 +71,49 @@
         Event _event;
     }
 
-    public boolean isValid ( )
-    {
+    public boolean isValid() {
         return !_invalid && _constraintEngine.isValid();
     }
 
     // KHK: remove this
-    private void emitError ( Event event, String message, QName offendingQName,
-                             SchemaType expectedSchemaType, List expectedQNames,
-                             int errorType, SchemaType badSchemaType)
-    {
-        emitError(event, message, null, null, XmlError.SEVERITY_ERROR, null, offendingQName , expectedSchemaType,
-            expectedQNames , errorType, badSchemaType);
+    private void emitError(Event event, String message, QName offendingQName,
+                           SchemaType expectedSchemaType, List expectedQNames,
+                           int errorType, SchemaType badSchemaType) {
+        emitError(event, message, null, null, XmlError.SEVERITY_ERROR, null, offendingQName, expectedSchemaType,
+            expectedQNames, errorType, badSchemaType);
     }
 
-    private void emitError ( Event event, String code, Object[] args, QName offendingQName,
-                             SchemaType expectedSchemaType, List expectedQNames,
-                             int errorType, SchemaType badSchemaType)
-    {
-        emitError(event, null, code, args, XmlError.SEVERITY_ERROR, null, offendingQName , expectedSchemaType,
-            expectedQNames , errorType, badSchemaType);
+    private void emitError(Event event, String code, Object[] args, QName offendingQName,
+                           SchemaType expectedSchemaType, List expectedQNames,
+                           int errorType, SchemaType badSchemaType) {
+        emitError(event, null, code, args, XmlError.SEVERITY_ERROR, null, offendingQName, expectedSchemaType,
+            expectedQNames, errorType, badSchemaType);
     }
 
     // KHK: remove 'message' parameter
-    private void emitError ( Event event, String message, String code, Object[] args, int severity,
-                             QName fieldName, QName offendingQName,
-                             SchemaType expectedSchemaType, List expectedQNames,
-                             int errorType, SchemaType badSchemaType )
-    {
+    private void emitError(Event event, String message, String code, Object[] args, int severity,
+                           QName fieldName, QName offendingQName,
+                           SchemaType expectedSchemaType, List expectedQNames,
+                           int errorType, SchemaType badSchemaType) {
         _errorState++;
 
-        if (_suspendErrors == 0)
-        {
-            if (severity == XmlError.SEVERITY_ERROR)
+        if (_suspendErrors == 0) {
+            if (severity == XmlError.SEVERITY_ERROR) {
                 _invalid = true;
+            }
 
-            if (_errorListener != null)
-            {
+            if (_errorListener != null) {
                 assert event != null;
                 XmlError error;
                 XmlCursor curs = event.getLocationAsCursor();
-                if (curs != null)
-                {
+                if (curs != null) {
                     // non-streaming validation uses XmlCursor
-                    error = XmlValidationError.forCursorWithDetails( message, code, args, severity,
+                    error = XmlValidationError.forCursorWithDetails(message, code, args, severity,
                         curs, fieldName, offendingQName, expectedSchemaType, expectedQNames,
                         errorType, badSchemaType);
-                }
-                else
-                {
+                } else {
                     // streaming validation uses Location
-                    error = XmlValidationError.forLocationWithDetails( message, code, args, severity,
+                    error = XmlValidationError.forLocationWithDetails(message, code, args, severity,
                         event.getLocation(), fieldName, offendingQName, expectedSchemaType, expectedQNames,
                         errorType, badSchemaType);
                 }
@@ -181,21 +123,18 @@
         }
     }
 
-    private void emitFieldError ( Event event, String code, Object[] args, QName offendingQName,
-                                  SchemaType expectedSchemaType, List expectedQNames,
-                                  int errorType, SchemaType badSchemaType )
-    {
+    private void emitFieldError(Event event, String code, Object[] args, QName offendingQName,
+                                SchemaType expectedSchemaType, List expectedQNames,
+                                int errorType, SchemaType badSchemaType) {
         emitFieldError(event, null, code, args, XmlError.SEVERITY_ERROR, offendingQName,
-                expectedSchemaType, expectedQNames, errorType, badSchemaType);
+            expectedSchemaType, expectedQNames, errorType, badSchemaType);
     }
 
-    private void emitFieldError ( Event event, String message, String code, Object[] args, int severity, QName offendingQName,
-                                  SchemaType expectedSchemaType, List expectedQNames,
-                                  int errorType, SchemaType badSchemaType )
-    {
+    private void emitFieldError(Event event, String message, String code, Object[] args, int severity, QName offendingQName,
+                                SchemaType expectedSchemaType, List expectedQNames,
+                                int errorType, SchemaType badSchemaType) {
         QName fieldName = null;
-        if (_stateStack != null && _stateStack._field != null)
-        {
+        if (_stateStack != null && _stateStack._field != null) {
             fieldName = _stateStack._field.getName();
         }
 
@@ -218,51 +157,55 @@
 //        }
 //    }
 
-    public void nextEvent ( int kind, Event event )
-    {
+    public void nextEvent(int kind, Event event) {
         resetValues();
 
-        if (_eatContent > 0)
-        {
-            switch ( kind )
-            {
-            case END   : _eatContent--; break;
-            case BEGIN : _eatContent++; break;
+        if (_eatContent > 0) {
+            switch (kind) {
+                case END:
+                    _eatContent--;
+                    break;
+                case BEGIN:
+                    _eatContent++;
+                    break;
             }
-        }
-        else
-        {
+        } else {
             assert
                 kind == BEGIN || kind == ATTR ||
-                    kind == END || kind == TEXT || kind == ENDATTRS;
+                kind == END || kind == TEXT || kind == ENDATTRS;
 
-            switch ( kind )
-            {
-            case BEGIN    : beginEvent(    event ); break;
-            case ATTR     : attrEvent(     event ); break;
-            case ENDATTRS : endAttrsEvent( event ); break;
-            case TEXT     : textEvent(     event ); break;
-            case END      : endEvent(      event ); break;
+            switch (kind) {
+                case BEGIN:
+                    beginEvent(event);
+                    break;
+                case ATTR:
+                    attrEvent(event);
+                    break;
+                case ENDATTRS:
+                    endAttrsEvent(event);
+                    break;
+                case TEXT:
+                    textEvent(event);
+                    break;
+                case END:
+                    endEvent(event);
+                    break;
             }
         }
     }
 
-    private void beginEvent ( Event event )
-    {
+    private void beginEvent(Event event) {
         _localElement = null;
         _wildcardElement = null;
         State state = topState();
 
-        SchemaType  elementType  = null;
+        SchemaType elementType = null;
         SchemaField elementField = null;
 
-        if (state == null)
-        {
+        if (state == null) {
             elementType = _rootType;
             elementField = _rootField;
-        }
-        else
-        {
+        } else {
 
             QName name = event.getName();
 
@@ -270,27 +213,24 @@
 
             state._isEmpty = false;
 
-            if (state._isNil)
-            {
+            if (state._isNil) {
                 emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT,
-                    null,  state._field.getName(), state._type, null,
+                    null, state._field.getName(), state._type, null,
                     XmlValidationError.NIL_ELEMENT, state._type);
 
                 _eatContent = 1;
                 return;
             }
 
-            if (!state._isNil && state._field != null && state._field.isFixed())
-            {
+            if (!state._isNil && state._field != null && state._field.isFixed()) {
                 emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_WITH_CONTENT,
-                    new Object[] { QNameHelper.pretty(state._field.getName()) },
+                    new Object[]{QNameHelper.pretty(state._field.getName())},
                     state._field.getName(), state._type, null,
                     XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
             }
 
-            if (!state.visit( name ))
-            {
-                findDetailedErrorBegin(event ,state , name);
+            if (!state.visit(name)) {
+                findDetailedErrorBegin(event, state, name);
 
                 _eatContent = 1;
 
@@ -300,18 +240,16 @@
             SchemaParticle currentParticle = state.currentParticle();
             _wildcardElement = currentParticle;
 
-            if (currentParticle.getParticleType() == SchemaParticle.WILDCARD)
-            {
+            if (currentParticle.getParticleType() == SchemaParticle.WILDCARD) {
                 //_wildcardElement = currentParticle;
                 QNameSet elemWildcardSet = currentParticle.getWildcardSet();
 
-                if (!elemWildcardSet.contains( name ))
-                {
+                if (!elemWildcardSet.contains(name)) {
                     // Additional processing may be needed to generate more
                     // descriptive messages
                     // KHK: cvc-complex-type.2.4? cvc-particle.1.3? cvc-wildcard-namespace ?
                     emitFieldError(event, XmlErrorCodes.PARTICLE_VALID$NOT_WILDCARD_VALID,
-                        new Object[] { QNameHelper.pretty(name) },
+                        new Object[]{QNameHelper.pretty(name)},
                         name, null, null,
                         XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
 
@@ -323,22 +261,19 @@
                 int wildcardProcess = currentParticle.getWildcardProcess();
 
                 if (wildcardProcess == SchemaParticle.SKIP ||
-                    wildcardProcess == SchemaParticle.LAX && _treatLaxAsSkip)
-                {
+                    wildcardProcess == SchemaParticle.LAX && _treatLaxAsSkip) {
                     _eatContent = 1;
                     return;
                 }
 
-                _localElement = _globalTypes.findElement( name );
+                _localElement = _globalTypes.findElement(name);
                 elementField = _localElement;
 
-                if (elementField == null)
-                {
-                    if (wildcardProcess == SchemaParticle.STRICT)
-                    {
+                if (elementField == null) {
+                    if (wildcardProcess == SchemaParticle.STRICT) {
                         // KHK: cvc-complex-type.2.4c? cvc-assess-elt.1.1.1.3.2?
-                        emitFieldError( event, XmlErrorCodes.ASSESS_ELEM_SCHEMA_VALID$NOT_RESOLVED,
-                            new Object[] { QNameHelper.pretty(name) },
+                        emitFieldError(event, XmlErrorCodes.ASSESS_ELEM_SCHEMA_VALID$NOT_RESOLVED,
+                            new Object[]{QNameHelper.pretty(name)},
                             name, state._type, null,
                             XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
                     }
@@ -347,9 +282,7 @@
 
                     return;
                 }
-            }
-            else
-            {
+            } else {
                 assert currentParticle.getParticleType() == SchemaParticle.ELEMENT;
 
                 // If the current element particle name does not match the name
@@ -357,12 +290,10 @@
                 // the current particle. Replace the field with the global
                 // element for the replacement
 
-                if (! currentParticle.getName().equals(name))
-                {
-                    if (((SchemaLocalElement)currentParticle).blockSubstitution())
-                    {
-                        emitFieldError( event, XmlErrorCodes.PARTICLE_VALID$BLOCK_SUBSTITUTION,
-                            new Object[] { QNameHelper.pretty(name) },
+                if (!currentParticle.getName().equals(name)) {
+                    if (((SchemaLocalElement) currentParticle).blockSubstitution()) {
+                        emitFieldError(event, XmlErrorCodes.PARTICLE_VALID$BLOCK_SUBSTITUTION,
+                            new Object[]{QNameHelper.pretty(name)},
                             name, state._type, null,
                             XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
 
@@ -374,14 +305,11 @@
 
                     assert newField != null;
 
-                    if (newField != null)
-                    {
+                    if (newField != null) {
                         elementField = newField;
                         _localElement = newField;
                     }
-                }
-                else
-                {
+                } else {
                     elementField = (SchemaField) currentParticle;
                 }
             }
@@ -395,9 +323,8 @@
         // the no-type is always invalid (even if there is an xsi:type)
         //
 
-        if (elementType.isNoType())
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE,
+        if (elementType.isNoType()) {
+            emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE,
                 null, event.getName(), null, null,
                 XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
@@ -412,8 +339,7 @@
 
         String value = event.getXsiType();
 
-        if (value != null)
-        {
+        if (value != null) {
             // Turn off the listener so a public error message
             // does not get generated, but I can see if there was
             // an error through the error state
@@ -422,37 +348,29 @@
 
             _suspendErrors++;
 
-            try
-            {
+            try {
                 _vc._event = null;
 
-                xsiType = _globalTypes.findType( XmlQNameImpl.validateLexical( value, _vc, event ) );
-            }
-            catch ( Throwable t )
-            {
+                xsiType = _globalTypes.findType(XmlQNameImpl.validateLexical(value, _vc, event));
+            } catch (Throwable t) {
                 _errorState++;
-            }
-            finally
-            {
+            } finally {
                 _suspendErrors--;
             }
 
-            if (originalErrorState != _errorState)
-            {
+            if (originalErrorState != _errorState) {
                 // not sure how to extract this one
-                emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_INVALID_QNAME,
-                    new Object[] { value }, event.getName(), xsiType, null,
+                emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_INVALID_QNAME,
+                    new Object[]{value}, event.getName(), xsiType, null,
                     XmlValidationError.ELEMENT_TYPE_INVALID, state._type);
 
                 _eatContent = 1;
 
                 return;
-            }
-            else if (xsiType == null)
-            {
+            } else if (xsiType == null) {
                 // NOT SURE errorAttributes._expectedSchemaType = xsiType;
-                emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_FOUND,
-                    new Object[] { value }, event.getName(), null, null,
+                emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_FOUND,
+                    new Object[]{value}, event.getName(), null, null,
                     XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
                 _eatContent = 1;
@@ -461,12 +379,10 @@
             }
         }
 
-        if (xsiType != null && !xsiType.equals(elementType))
-        {
-            if (!elementType.isAssignableFrom(xsiType))
-            {
-                emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_DERIVED,
-                    new Object[] { xsiType, elementType }, event.getName(), elementType, null,
+        if (xsiType != null && !xsiType.equals(elementType)) {
+            if (!elementType.isAssignableFrom(xsiType)) {
+                emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_DERIVED,
+                    new Object[]{xsiType, elementType}, event.getName(), elementType, null,
                     XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
 
                 _eatContent = 1;
@@ -474,15 +390,12 @@
                 return;
             }
 
-            if (elementType.blockExtension())
-            {
-                for ( SchemaType t = xsiType ; ! t.equals( elementType ) ;
-                      t = t.getBaseType() )
-                {
-                    if (t.getDerivationType() == SchemaType.DT_EXTENSION)
-                    {
-                        emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION,
-                            new Object[] { xsiType, elementType }, event.getName(), elementType, null,
+            if (elementType.blockExtension()) {
+                for (SchemaType t = xsiType; !t.equals(elementType);
+                     t = t.getBaseType()) {
+                    if (t.getDerivationType() == SchemaType.DT_EXTENSION) {
+                        emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION,
+                            new Object[]{xsiType, elementType}, event.getName(), elementType, null,
                             XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
 
                         _eatContent = 1;
@@ -492,15 +405,12 @@
                 }
             }
 
-            if (elementType.blockRestriction())
-            {
-                for ( SchemaType t = xsiType ; ! t.equals( elementType ) ;
-                      t = t.getBaseType() )
-                {
-                    if (t.getDerivationType() == SchemaType.DT_RESTRICTION)
-                    {
-                        emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION,
-                            new Object[] { xsiType, elementType }, event.getName(), elementType, null,
+            if (elementType.blockRestriction()) {
+                for (SchemaType t = xsiType; !t.equals(elementType);
+                     t = t.getBaseType()) {
+                    if (t.getDerivationType() == SchemaType.DT_RESTRICTION) {
+                        emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION,
+                            new Object[]{xsiType, elementType}, event.getName(), elementType, null,
                             XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
 
                         _eatContent = 1;
@@ -510,22 +420,18 @@
                 }
             }
 
-            if (elementField instanceof SchemaLocalElement)
-            {
-                SchemaLocalElement sle  = (SchemaLocalElement)elementField;
+            if (elementField instanceof SchemaLocalElement) {
+                SchemaLocalElement sle = (SchemaLocalElement) elementField;
                 _localElement = sle;
 
-                if (sle.blockExtension() || sle.blockRestriction())
-                {
-                    for ( SchemaType t = xsiType ; ! t.equals( elementType ) ;
-                          t = t.getBaseType() )
-                    {
+                if (sle.blockExtension() || sle.blockRestriction()) {
+                    for (SchemaType t = xsiType; !t.equals(elementType);
+                         t = t.getBaseType()) {
                         if ((t.getDerivationType() == SchemaType.DT_RESTRICTION && sle.blockRestriction()) ||
-                            (t.getDerivationType() == SchemaType.DT_EXTENSION && sle.blockExtension()))
-                        {
+                            (t.getDerivationType() == SchemaType.DT_EXTENSION && sle.blockExtension())) {
                             //need to find a way to get the right type
-                            emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_PROHIBITED_SUBST,
-                                new Object[] { xsiType, QNameHelper.pretty(sle.getName()) },
+                            emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_PROHIBITED_SUBST,
+                                new Object[]{xsiType, QNameHelper.pretty(sle.getName())},
                                 sle.getName(), null, null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
                             _eatContent = 1;
@@ -539,16 +445,14 @@
             elementType = xsiType;
         }
 
-        if (elementField instanceof SchemaLocalElement)
-        {
-            SchemaLocalElement sle = (SchemaLocalElement)elementField;
+        if (elementField instanceof SchemaLocalElement) {
+            SchemaLocalElement sle = (SchemaLocalElement) elementField;
             _localElement = sle;
 
-            if (sle.isAbstract())
-            {
+            if (sle.isAbstract()) {
                 //todo (dutta) need to find a way to get the right type
                 emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT,
-                    new Object[] { QNameHelper.pretty(sle.getName()) },
+                    new Object[]{QNameHelper.pretty(sle.getName())},
                     sle.getName(), null, null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
                 _eatContent = 1;
@@ -556,10 +460,9 @@
             }
         }
 
-        if (elementType != null && elementType.isAbstract())
-        {
+        if (elementType != null && elementType.isAbstract()) {
             emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT,
-                new Object[] { elementType },
+                new Object[]{elementType},
                 event.getName(), elementType, null, XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
 
             _eatContent = 1;
@@ -572,32 +475,29 @@
 
         String nilValue = event.getXsiNil();
 
-        if (nilValue != null)
-        {
+        if (nilValue != null) {
             _vc._event = event;
             isNil = JavaBooleanHolder.validateLexical(nilValue, _vc);
             hasNil = true;
         }
 
         // note in schema spec 3.3.4, you're not even allowed to say xsi:nil="false" if you're not nillable!
-        if (hasNil && (elementField == null || !elementField.isNillable()))
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NOT_NILLABLE, null,
+        if (hasNil && (elementField == null || !elementField.isNillable())) {
+            emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NOT_NILLABLE, null,
                 elementField == null ? null : elementField.getName(), elementType, null,
                 XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
 
             _eatContent = 1;
             return;
         }
-        
-        if (isNil && elementField != null && elementField.isFixed())
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_FIXED, null,
+
+        if (isNil && elementField != null && elementField.isFixed()) {
+            emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_FIXED, null,
                 elementField == null ? null : elementField.getName(), elementType, null,
                 XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type));
         }
 
-        newState( elementType, elementField, isNil );
+        newState(elementType, elementField, isNil);
 
         // Dispatch this element event to any identity constraints
         // As well as adding any new identity constraints that exist
@@ -607,33 +507,31 @@
             elementType,
             elementField instanceof SchemaLocalElement
                 ? ((SchemaLocalElement) elementField).getIdentityConstraints()
-                : null );
+                : null);
     }
 
-    private void attrEvent ( Event event )
-    {
+    private void attrEvent(Event event) {
         QName attrName = event.getName();
 
         State state = topState();
 
-        if (state._attrs == null)
+        if (state._attrs == null) {
             state._attrs = new HashSet();
+        }
 
-        if (state._attrs.contains( attrName ))
-        {
-            emitFieldError( event, XmlErrorCodes.XML_DUPLICATE_ATTRIBUTE,
-                new Object[] { QNameHelper.pretty( attrName ) },
-                attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type );
+        if (state._attrs.contains(attrName)) {
+            emitFieldError(event, XmlErrorCodes.XML_DUPLICATE_ATTRIBUTE,
+                new Object[]{QNameHelper.pretty(attrName)},
+                attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
 
             return;
         }
 
-        state._attrs.add( attrName );
+        state._attrs.add(attrName);
 
-        if (!state._canHaveAttrs)
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD,
-                new Object[] {QNameHelper.pretty( attrName )}, attrName, null, null,
+        if (!state._canHaveAttrs) {
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD,
+                new Object[]{QNameHelper.pretty(attrName)}, attrName, null, null,
                 XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
             return;
         }
@@ -641,26 +539,24 @@
         SchemaLocalAttribute attrSchema =
             state._attrModel == null
                 ? null
-                : state._attrModel.getAttribute( attrName );
+                : state._attrModel.getAttribute(attrName);
 
-        if (attrSchema != null)
-        {
+        if (attrSchema != null) {
             _localAttribute = attrSchema;
 
-            if (attrSchema.getUse() == SchemaLocalAttribute.PROHIBITED)
-            {
-                emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$PROHIBITED_ATTRIBUTE,
-                    new Object[] { QNameHelper.pretty( attrName ) } ,
-                    attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type );
+            if (attrSchema.getUse() == SchemaLocalAttribute.PROHIBITED) {
+                emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$PROHIBITED_ATTRIBUTE,
+                    new Object[]{QNameHelper.pretty(attrName)},
+                    attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
 
                 return;
             }
 
             String value =
                 validateSimpleType(
-                    attrSchema.getType(), attrSchema, event, false, false );
+                    attrSchema.getType(), attrSchema, event, false, false);
 
-            _constraintEngine.attr( event, attrName, attrSchema.getType(), value );
+            _constraintEngine.attr(event, attrName, attrSchema.getType(), value);
 
             return;
         }
@@ -669,11 +565,10 @@
 
         _wildcardAttribute = state._attrModel;
 
-        if (wildcardProcess == SchemaAttributeModel.NONE)
-        {
+        if (wildcardProcess == SchemaAttributeModel.NONE) {
             // todo (dutta) need additional logic to determine the expectedSchemaType
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD,
-                new Object[] { QNameHelper.pretty( attrName ) },
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD,
+                new Object[]{QNameHelper.pretty(attrName)},
                 attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
 
             return;
@@ -681,34 +576,34 @@
 
         QNameSet attrWildcardSet = state._attrModel.getWildcardSet();
 
-        if (!attrWildcardSet.contains( attrName ))
-        {
+        if (!attrWildcardSet.contains(attrName)) {
             // todo (dutta) need additional logic to determine the expectedSchemaType
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NOT_WILDCARD_VALID,
-                new Object[] { QNameHelper.pretty( attrName ) },
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NOT_WILDCARD_VALID,
+                new Object[]{QNameHelper.pretty(attrName)},
                 attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
 
             return;
         }
 
         if (wildcardProcess == SchemaAttributeModel.SKIP ||
-            wildcardProcess == SchemaAttributeModel.LAX && _treatLaxAsSkip)
+            wildcardProcess == SchemaAttributeModel.LAX && _treatLaxAsSkip) {
             return;
+        }
 
-        attrSchema = _globalTypes.findAttribute( attrName );
+        attrSchema = _globalTypes.findAttribute(attrName);
         _localAttribute = attrSchema;
 
-        if (attrSchema == null)
-        {
-            if (wildcardProcess == SchemaAttributeModel.LAX)
+        if (attrSchema == null) {
+            if (wildcardProcess == SchemaAttributeModel.LAX) {
                 return;
+            }
 
             assert wildcardProcess == SchemaAttributeModel.STRICT;
 
             // KHK: cvc-assess-attr.1.2 ?
             // todo (dutta) need additional logic to determine the expectedSchemaType
-            emitFieldError( event, XmlErrorCodes.ASSESS_ATTR_SCHEMA_VALID$NOT_RESOLVED,
-                new Object[] { QNameHelper.pretty( attrName ) },
+            emitFieldError(event, XmlErrorCodes.ASSESS_ATTR_SCHEMA_VALID$NOT_RESOLVED,
+                new Object[]{QNameHelper.pretty(attrName)},
                 attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
 
             return;
@@ -716,35 +611,28 @@
 
         String value =
             validateSimpleType(
-                attrSchema.getType(), attrSchema, event, false, false );
+                attrSchema.getType(), attrSchema, event, false, false);
 
-        _constraintEngine.attr( event, attrName, attrSchema.getType(), value );
+        _constraintEngine.attr(event, attrName, attrSchema.getType(), value);
     }
 
-    private void endAttrsEvent ( Event event )
-    {
+    private void endAttrsEvent(Event event) {
         State state = topState();
 
-        if (state._attrModel != null)
-        {
+        if (state._attrModel != null) {
             SchemaLocalAttribute[] attrs = state._attrModel.getAttributes();
 
-            for ( int i = 0 ; i < attrs.length ; i++ )
-            {
-                SchemaLocalAttribute sla = attrs[ i ];
+            for (int i = 0; i < attrs.length; i++) {
+                SchemaLocalAttribute sla = attrs[i];
 
                 if (state._attrs == null ||
-                        !state._attrs.contains( sla.getName() ))
-                {
-                    if (sla.getUse() == SchemaLocalAttribute.REQUIRED)
-                    {
+                    !state._attrs.contains(sla.getName())) {
+                    if (sla.getUse() == SchemaLocalAttribute.REQUIRED) {
                         // KHK: cvc-complex-type.4
-                        emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE,
-                            new Object[] { QNameHelper.pretty(sla.getName()) },
+                        emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE,
+                            new Object[]{QNameHelper.pretty(sla.getName())},
                             sla.getName(), null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type);
-                    }
-                    else if (sla.isDefault() || sla.isFixed())
-                    {
+                    } else if (sla.isDefault() || sla.isFixed()) {
                         _constraintEngine.attr(event, sla.getName(), sla.getType(), sla.getDefaultText());
 
                         // We don't need to validate attribute defaults because this is done at compiletime.
@@ -775,65 +663,56 @@
         }
     }
 
-    private void endEvent ( Event event )
-    {
+    private void endEvent(Event event) {
         _localElement = null;
         _wildcardElement = null;
         State state = topState();
 
-        if (!state._isNil)
-        {
-            if (!state.end())
-            {
-                findDetailedErrorEnd(event,state);
+        if (!state._isNil) {
+            if (!state.end()) {
+                findDetailedErrorEnd(event, state);
             }
 
             // This end event has no text, use this fact to pass no text to
             // handleText
 
-            if (state._isEmpty)
-                handleText( event, true, state._field );
+            if (state._isEmpty) {
+                handleText(event, true, state._field);
+            }
         }
 
-        popState( event );
+        popState(event);
 
-        _constraintEngine.endElement( event );
+        _constraintEngine.endElement(event);
     }
 
-    private void textEvent ( Event event )
-    {
+    private void textEvent(Event event) {
         State state = topState();
 
-        if (state._isNil)
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT, null,
+        if (state._isNil) {
+            emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT, null,
                 state._field.getName(), state._type, null,
-                XmlValidationError.NIL_ELEMENT, state._type );
+                XmlValidationError.NIL_ELEMENT, state._type);
+        } else {
+            handleText(event, false, state._field);
         }
-        else
-            handleText( event, false, state._field );
 
         state._isEmpty = false;
     }
 
 
-    private void handleText (
-        Event event, boolean emptyContent, SchemaField field )
-    {
+    private void handleText(
+        Event event, boolean emptyContent, SchemaField field) {
         State state = topState();
 
-        if (!state._sawText)
-        {
-            if (state._hasSimpleContent)
-            {
+        if (!state._sawText) {
+            if (state._hasSimpleContent) {
                 String value =
                     validateSimpleType(
-                        state._type, field, event, emptyContent, true );
+                        state._type, field, event, emptyContent, true);
 
-                _constraintEngine.text( event, state._type, value, false );
-            }
-            else if (state._canHaveMixedContent)
-            {
+                _constraintEngine.text(event, state._type, value, false);
+            } else if (state._canHaveMixedContent) {
                 // handles cvc-elt.5.2.2.2.1, checking mixed content against fixed.
                 // if we see <mixedType>a</b>c</mixedType>, we validate against
                 // the first 'a' text and we check the content of mixedType to
@@ -841,39 +720,33 @@
                 // the 'c' text since there will already be an error for <b/>
                 String value =
                     validateSimpleType(
-                        XmlString.type, field, event, emptyContent, true );
+                        XmlString.type, field, event, emptyContent, true);
 
-                _constraintEngine.text( event, XmlString.type, value, false );
+                _constraintEngine.text(event, XmlString.type, value, false);
+            } else if (emptyContent) {
+                _constraintEngine.text(event, state._type, null, true);
+            } else {
+                _constraintEngine.text(event, state._type, "", false);
             }
-            else if (emptyContent)
-            {
-                _constraintEngine.text( event, state._type, null, true );
-            }
-            else
-                _constraintEngine.text( event, state._type, "", false);
         }
 
         if (!emptyContent && !state._canHaveMixedContent &&
-            !event.textIsWhitespace() && !state._hasSimpleContent)
-        {
-            if (field instanceof SchemaLocalElement)
-            {
-                SchemaLocalElement e = (SchemaLocalElement)field;
+            !event.textIsWhitespace() && !state._hasSimpleContent) {
+            if (field instanceof SchemaLocalElement) {
+                SchemaLocalElement e = (SchemaLocalElement) field;
 
                 assert state._type.getContentType() == SchemaType.EMPTY_CONTENT ||
-                    state._type.getContentType() == SchemaType.ELEMENT_CONTENT;
+                       state._type.getContentType() == SchemaType.ELEMENT_CONTENT;
 
                 // KHK: cvc-complex-type.2.1 or .2.3
                 String errorCode = (state._type.getContentType() == SchemaType.EMPTY_CONTENT ?
                     XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EMPTY_WITH_CONTENT :
                     XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_ONLY_WITH_TEXT);
 
-                emitError(event, errorCode,new Object[] {QNameHelper.pretty(e.getName())},
+                emitError(event, errorCode, new Object[]{QNameHelper.pretty(e.getName())},
                     e.getName(), field.getType(), null,
                     XmlValidationError.ELEMENT_TYPE_INVALID, null);
-            }
-            else
-            {
+            } else {
                 // KHK: cvc-complex-type.2.1 or .2.3
                 // todo (dutta) offendingQName = not sure how to get this(event.getName()??);
                 emitError(event, "Can't have mixed content", event.getName(),
@@ -881,127 +754,113 @@
             }
         }
 
-        if (!emptyContent)
+        if (!emptyContent) {
             state._sawText = true;
+        }
     }
 
-    private void findDetailedErrorBegin(Event event, State state, QName qName)
-    {
+    private void findDetailedErrorBegin(Event event, State state, QName qName) {
         ArrayList expectedNames = new ArrayList();
         ArrayList optionalNames = new ArrayList();
 
         SchemaProperty[] eltProperties = state._type.getElementProperties();
-        for (int ii = 0; ii < eltProperties.length; ii++)
-        {
+        for (int ii = 0; ii < eltProperties.length; ii++) {
             //Get the element from the schema
             SchemaProperty sProp = eltProperties[ii];
 
             // test if the element is valid
-            if (state.test(sProp.getName()))
-            {
-                if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs()))
+            if (state.test(sProp.getName())) {
+                if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs())) {
                     optionalNames.add(sProp.getName());
-                else
+                } else {
                     expectedNames.add(sProp.getName());
+                }
             }
         }
 
         List names = (expectedNames.size() > 0 ? expectedNames : optionalNames);
 
-        if (names.size() > 0)
-        {
+        if (names.size() > 0) {
             StringBuilder buf = new StringBuilder();
-            for (Iterator iter = names.iterator(); iter.hasNext();)
-            {
+            for (Iterator iter = names.iterator(); iter.hasNext(); ) {
                 QName qname = (QName) iter.next();
                 buf.append(QNameHelper.pretty(qname));
-                if (iter.hasNext())
+                if (iter.hasNext()) {
                     buf.append(" ");
+                }
             }
 
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_DIFFERENT_ELEMENT,
-                new Object[] { new Integer(names.size()), buf.toString(), QNameHelper.pretty(qName) },
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_DIFFERENT_ELEMENT,
+                new Object[]{new Integer(names.size()), buf.toString(), QNameHelper.pretty(qName)},
                 qName, null, names, XmlValidationError.INCORRECT_ELEMENT, state._type);
-        }
-        else
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_NOT_ALLOWED,
-                new Object[] { QNameHelper.pretty(qName) },
+        } else {
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_NOT_ALLOWED,
+                new Object[]{QNameHelper.pretty(qName)},
                 qName, null, null, XmlValidationError.INCORRECT_ELEMENT, state._type);
         }
     }
 
-    private void findDetailedErrorEnd(Event event, State state)
-    {
-        SchemaProperty[] eltProperties  = state._type.getElementProperties();
+    private void findDetailedErrorEnd(Event event, State state) {
+        SchemaProperty[] eltProperties = state._type.getElementProperties();
 
         ArrayList expectedNames = new ArrayList();
         ArrayList optionalNames = new ArrayList();
 
-        for (int ii = 0; ii < eltProperties.length; ii++)
-        {
+        for (int ii = 0; ii < eltProperties.length; ii++) {
             //Get the element from the schema
             SchemaProperty sProp = eltProperties[ii];
 
             // test if the element is valid
-            if (state.test(sProp.getName()))
-            {
-                if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs()))
+            if (state.test(sProp.getName())) {
+                if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs())) {
                     optionalNames.add(sProp.getName());
-                else
+                } else {
                     expectedNames.add(sProp.getName());
+                }
             }
         }
 
         List names = (expectedNames.size() > 0 ? expectedNames : optionalNames);
 
-        if (names.size() > 0)
-        {
+        if (names.size() > 0) {
             StringBuilder buf = new StringBuilder();
-            for (Iterator iter = names.iterator(); iter.hasNext();)
-            {
+            for (Iterator iter = names.iterator(); iter.hasNext(); ) {
                 QName qname = (QName) iter.next();
                 buf.append(QNameHelper.pretty(qname));
-                if (iter.hasNext())
+                if (iter.hasNext()) {
                     buf.append(" ");
+                }
             }
 
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT,
-                new Object[] { new Integer(names.size()), buf.toString() },
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT,
+                new Object[]{new Integer(names.size()), buf.toString()},
                 null, null, names, XmlValidationError.INCORRECT_ELEMENT, state._type);
-        }
-        else
-        {
-            emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_ELEMENT,
+        } else {
+            emitFieldError(event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_ELEMENT,
                 null, null, null, null, XmlValidationError.ELEMENT_NOT_ALLOWED, state._type);
         }
     }
 
 
-    private final class State
-    {
-        boolean visit ( QName name )
-        {
-            return _canHaveElements && _visitor.visit( name );
+    private final class State {
+        boolean visit(QName name) {
+            return _canHaveElements && _visitor.visit(name);
         }
 
-        boolean test( QName name )
-        {
-            return _canHaveElements && _visitor.testValid( name );
+        boolean test(QName name) {
+            return _canHaveElements && _visitor.testValid(name);
         }
 
-        boolean end ( )
-        {
-            return !_canHaveElements || _visitor.visit( null );
+        boolean end() {
+            return !_canHaveElements || _visitor.visit(null);
         }
 
-        SchemaParticle currentParticle ( )
-        {
+        SchemaParticle currentParticle() {
             assert _visitor != null;
             return _visitor.currentParticle();
         }
 
-        SchemaType  _type;
+        SchemaType _type;
         SchemaField _field;
 
         boolean _canHaveAttrs;
@@ -1022,12 +881,10 @@
         State _next;
     }
 
-    private boolean derivedFromInteger( SchemaType type )
-    {
+    private boolean derivedFromInteger(SchemaType type) {
         int btc = type.getBuiltinTypeCode();
 
-        while (btc == SchemaType.BTC_NOT_BUILTIN)
-        {
+        while (btc == SchemaType.BTC_NOT_BUILTIN) {
             type = type.getBaseType();
             btc = type.getBuiltinTypeCode();
         }
@@ -1035,8 +892,7 @@
         return btc >= SchemaType.BTC_INTEGER && btc <= SchemaType.BTC_UNSIGNED_BYTE;
     }
 
-    private void newState ( SchemaType type, SchemaField field, boolean isNil )
-    {
+    private void newState(SchemaType type, SchemaField field, boolean isNil) {
         State state = new State();
 
         state._type = type;
@@ -1044,86 +900,78 @@
         state._isEmpty = true;
         state._isNil = isNil;
 
-        if (type.isSimpleType())
-        {
+        if (type.isSimpleType()) {
             state._hasSimpleContent = true;
-        }
-        else
-        {
+        } else {
             state._canHaveAttrs = true;
             state._attrModel = type.getAttributeModel();
 
-            switch ( type.getContentType() )
-            {
-            case SchemaType.EMPTY_CONTENT :
-                break;
+            switch (type.getContentType()) {
+                case SchemaType.EMPTY_CONTENT:
+                    break;
 
-            case SchemaType.SIMPLE_CONTENT :
-                state._hasSimpleContent = true;
-                break;
+                case SchemaType.SIMPLE_CONTENT:
+                    state._hasSimpleContent = true;
+                    break;
 
-            case SchemaType.MIXED_CONTENT :
-                state._canHaveMixedContent = true;
-                // Fall through
+                case SchemaType.MIXED_CONTENT:
+                    state._canHaveMixedContent = true;
+                    // Fall through
 
-            case SchemaType.ELEMENT_CONTENT :
+                case SchemaType.ELEMENT_CONTENT:
 
-                SchemaParticle particle = type.getContentModel();
+                    SchemaParticle particle = type.getContentModel();
 
-                state._canHaveElements = particle != null;
+                    state._canHaveElements = particle != null;
 
-                if (state._canHaveElements)
-                    state._visitor = initVisitor( particle );
+                    if (state._canHaveElements) {
+                        state._visitor = initVisitor(particle);
+                    }
 
-                break;
+                    break;
 
-            default :
-                throw new RuntimeException( "Unexpected content type" );
+                default:
+                    throw new RuntimeException("Unexpected content type");
             }
         }
 
-        pushState( state );
+        pushState(state);
     }
 
-    private void popState ( Event e )
-    {
-        if (_stateStack._visitor != null)
-        {
-            poolVisitor( _stateStack._visitor );
+    private void popState(Event e) {
+        if (_stateStack._visitor != null) {
+            poolVisitor(_stateStack._visitor);
             _stateStack._visitor = null;
         }
 
         _stateStack = _stateStack._next;
     }
 
-    private void pushState ( State state )
-    {
+    private void pushState(State state) {
         state._next = _stateStack;
         _stateStack = state;
     }
 
     private LinkedList _visitorPool = new LinkedList();
 
-    private void poolVisitor( SchemaTypeVisitorImpl visitor )
-    {
-        _visitorPool.add( visitor );
+    private void poolVisitor(SchemaTypeVisitorImpl visitor) {
+        _visitorPool.add(visitor);
     }
 
-    private SchemaTypeVisitorImpl initVisitor( SchemaParticle particle )
-    {
-        if (_visitorPool.isEmpty())
-            return new SchemaTypeVisitorImpl( particle );
+    private SchemaTypeVisitorImpl initVisitor(SchemaParticle particle) {
+        if (_visitorPool.isEmpty()) {
+            return new SchemaTypeVisitorImpl(particle);
+        }
 
         SchemaTypeVisitorImpl result =
             (SchemaTypeVisitorImpl) _visitorPool.removeLast();
 
-        result.init( particle );
+        result.init(particle);
 
         return result;
     }
 
-    private State topState ( )
-    {
+    private State topState() {
         return _stateStack;
     }
 
@@ -1135,13 +983,11 @@
     // where the default is a qname)
     //
 
-    private String validateSimpleType (
+    private String validateSimpleType(
         SchemaType type, SchemaField field, Event event,
-        boolean emptyContent, boolean canApplyDefault )
-    {
+        boolean emptyContent, boolean canApplyDefault) {
         if (!type.isSimpleType() &&
-                type.getContentType() != SchemaType.SIMPLE_CONTENT)
-        {
+            type.getContentType() != SchemaType.SIMPLE_CONTENT) {
             assert false;
             // throw new RuntimeException( "Not a simple type" );
             return null; // should never happen
@@ -1151,10 +997,9 @@
         // the no-type is always invalid
         //
 
-        if (type.isNoType())
-        {
+        if (type.isNoType()) {
             emitError(event, (field.isAttribute() ? XmlErrorCodes.ATTR_LOCALLY_VALID$NO_TYPE : XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE),
-                null, field.getName(), type, null,  XmlValidationError.ELEMENT_TYPE_INVALID, null);
+                null, field.getName(), type, null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
             return null;
         }
@@ -1164,22 +1009,19 @@
 
         String value = "";
 
-        if (!emptyContent)
-        {
+        if (!emptyContent) {
             int wsr = type.getWhiteSpaceRule();
-            value = wsr == SchemaType.WS_PRESERVE ? event.getText() : event.getText( wsr );
+            value = wsr == SchemaType.WS_PRESERVE ? event.getText() : event.getText(wsr);
         }
 
         // See if I can apply a default/fixed value
 
         if (value.length() == 0 && canApplyDefault && field != null &&
-                (field.isDefault() || field.isFixed()))
-        {
-            if (XmlQName.type.isAssignableFrom(type))
-            {
+            (field.isDefault() || field.isFixed())) {
+            if (XmlQName.type.isAssignableFrom(type)) {
                 // TODO: will be fixed in XmlSchema 1.1
-                emitError( event, "Default QName values are unsupported for " +
-                    QNameHelper.readable(type) + " - ignoring.", null, null,
+                emitError(event, "Default QName values are unsupported for " +
+                                 QNameHelper.readable(type) + " - ignoring.", null, null,
                     XmlError.SEVERITY_INFO, field.getName(), null, type, null,
                     XmlValidationError.ELEMENT_TYPE_INVALID, null);
 
@@ -1188,57 +1030,55 @@
 
             String defaultValue =
                 XmlWhitespace.collapse(
-                    field.getDefaultText(), type.getWhiteSpaceRule() );
+                    field.getDefaultText(), type.getWhiteSpaceRule());
 
 // BUGBUG - should validate defaultValue at compile time
             // KHK: cvc-elt.5.1.2 ?
             return
-                validateSimpleType( type, defaultValue, event )
+                validateSimpleType(type, defaultValue, event)
                     ? defaultValue
                     : null;
         }
 
         // KHK: cvc-elt.5.2.1 ?
-        if (!validateSimpleType( type, value, event ))
+        if (!validateSimpleType(type, value, event)) {
             return null;
+        }
 
-        if (field != null && field.isFixed())
-        {
+        if (field != null && field.isFixed()) {
 // TODO - fixed value should have been cooked at compile time
             String fixedValue =
                 XmlWhitespace.collapse(
-                    field.getDefaultText(), type.getWhiteSpaceRule() );
+                    field.getDefaultText(), type.getWhiteSpaceRule());
 
-            if (!validateSimpleType( type, fixedValue, event ))
+            if (!validateSimpleType(type, fixedValue, event)) {
                 return null;
+            }
 
-            XmlObject val = type.newValue( value );
-            XmlObject def = type.newValue( fixedValue );
+            XmlObject val = type.newValue(value);
+            XmlObject def = type.newValue(fixedValue);
 
-            if (!val.valueEquals( def ))
-            {
+            if (!val.valueEquals(def)) {
                 // TODO (dutta) - make this more verbose
-                if (field.isAttribute())
-                {
+                if (field.isAttribute()) {
                     // KHK: check for is cvc-complex-type.3.1 or cvc-au
                     emitError(event, XmlErrorCodes.ATTR_LOCALLY_VALID$FIXED,
-                        new Object[] { value, fixedValue, QNameHelper.pretty(event.getName()) },
+                        new Object[]{value, fixedValue, QNameHelper.pretty(event.getName())},
                         null, field.getType(), null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
-                }
-                else
-                {
+                } else {
                     String errorCode = null;
 
                     // see rule 5 of cvc-elt: Element Locally Valid (Element)
-                    if (field.getType().getContentType() == SchemaType.MIXED_CONTENT)
+                    if (field.getType().getContentType() == SchemaType.MIXED_CONTENT) {
                         errorCode = XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_VALID_MIXED_CONTENT;
-                    else if (type.isSimpleType())
+                    } else if (type.isSimpleType()) {
                         errorCode = XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_VALID_SIMPLE_TYPE;
-                    else
+                    } else {
                         assert false : "Element with fixed may not be EMPTY or ELEMENT_ONLY";
+                    }
 
                     emitError(event, errorCode,
-                        new Object[] { value, fixedValue },
+                        new Object[]{value, fixedValue},
                         field.getName(), field.getType(), null, XmlValidationError.ELEMENT_TYPE_INVALID, null);
                 }
 
@@ -1249,33 +1089,36 @@
         return value;
     }
 
-    private boolean validateSimpleType (
-        SchemaType type, String value, Event event )
-    {
+    private boolean validateSimpleType(
+        SchemaType type, String value, Event event) {
         if (!type.isSimpleType() &&
-                type.getContentType() != SchemaType.SIMPLE_CONTENT)
-        {
+            type.getContentType() != SchemaType.SIMPLE_CONTENT) {
             assert false;
-            throw new RuntimeException( "Not a simple type" );
+            throw new RuntimeException("Not a simple type");
         }
 
         int retState = _errorState;
 
-        switch ( type.getSimpleVariety() )
-        {
-        case SchemaType.ATOMIC : validateAtomicType( type, value, event );break;
-        case SchemaType.UNION  : validateUnionType(  type, value, event );break;
-        case SchemaType.LIST   : validateListType(   type, value, event );break;
+        switch (type.getSimpleVariety()) {
+            case SchemaType.ATOMIC:
+                validateAtomicType(type, value, event);
+                break;
+            case SchemaType.UNION:
+                validateUnionType(type, value, event);
+                break;
+            case SchemaType.LIST:
+                validateListType(type, value, event);
+                break;
 
-        default : throw new RuntimeException( "Unexpected simple variety" );
+            default:
+                throw new RuntimeException("Unexpected simple variety");
         }
 
         return retState == _errorState;
     }
 
-    private void validateAtomicType (
-        SchemaType type, String value, Event event )
-    {
+    private void validateAtomicType(
+        SchemaType type, String value, Event event) {
         // Now we should have only an atomic type to validate
 
         assert type.getSimpleVariety() == SchemaType.ATOMIC;
@@ -1284,180 +1127,166 @@
         int errorState = _errorState;
         _vc._event = event;
 
-        switch ( type.getPrimitiveType().getBuiltinTypeCode() )
-        {
-        case SchemaType.BTC_ANY_SIMPLE :
-        {
-            // Always valid!
-            _stringValue = value;
-            break;
-        }
-        case SchemaType.BTC_STRING :
-        {
-            JavaStringEnumerationHolderEx.validateLexical( value, type, _vc );
-            _stringValue = value;
-            break;
-        }
-        case SchemaType.BTC_DECIMAL :
-        {
-            JavaDecimalHolderEx.validateLexical( value, type, _vc );
-
-            // An additional rule states that if the type is xs:integer or derived from it,
-            // then the decimal dot is not allowed.
-            // verify that values extending xsd:integer don't have a decimal point
-            if ( derivedFromInteger( type ) && value.lastIndexOf('.') >= 0 )
-            {
-                _vc.invalid(XmlErrorCodes.INTEGER, new Object[] { value });
+        switch (type.getPrimitiveType().getBuiltinTypeCode()) {
+            case SchemaType.BTC_ANY_SIMPLE: {
+                // Always valid!
+                _stringValue = value;
+                break;
             }
-
-            if (errorState == _errorState)
-            {
-                _decimalValue = new BigDecimal( value );
-                JavaDecimalHolderEx.validateValue( _decimalValue, type, _vc );
+            case SchemaType.BTC_STRING: {
+                JavaStringEnumerationHolderEx.validateLexical(value, type, _vc);
+                _stringValue = value;
+                break;
             }
+            case SchemaType.BTC_DECIMAL: {
+                JavaDecimalHolderEx.validateLexical(value, type, _vc);
 
-            break;
-        }
-        case SchemaType.BTC_BOOLEAN :
-        {
-            _booleanValue = JavaBooleanHolderEx.validateLexical( value, type, _vc );
-            break;
-        }
-        case SchemaType.BTC_FLOAT :
-        {
-            float f =
-                JavaFloatHolderEx.validateLexical( value, type, _vc );
-
-            if (errorState == _errorState)
-                JavaFloatHolderEx.validateValue( f, type, _vc );
-
-            _floatValue = f;
-            break;
-        }
-        case SchemaType.BTC_DOUBLE :
-        {
-            double d =
-                JavaDoubleHolderEx.validateLexical( value, type, _vc );
-
-            if (errorState == _errorState)
-                JavaDoubleHolderEx.validateValue( d, type, _vc );
-
-            _doubleValue = d;
-            break;
-        }
-        case SchemaType.BTC_QNAME :
-        {
-            QName n =
-                JavaQNameHolderEx.validateLexical(
-                    value, type, _vc, event );
-
-            if (errorState == _errorState)
-                JavaQNameHolderEx.validateValue( n, type, _vc );
-
-            _qnameValue = n;
-            break;
-        }
-        case SchemaType.BTC_ANY_URI :
-        {
-            JavaUriHolderEx.validateLexical( value, type, _vc );
-            // Do strict validation
-            if (_strict)
-            {
-                try
-                {
-                    XsTypeConverter.lexAnyURI( value );
+                // An additional rule states that if the type is xs:integer or derived from it,
+                // then the decimal dot is not allowed.
+                // verify that values extending xsd:integer don't have a decimal point
+                if (derivedFromInteger(type) && value.lastIndexOf('.') >= 0) {
+                    _vc.invalid(XmlErrorCodes.INTEGER, new Object[]{value});
                 }
-                catch (InvalidLexicalValueException ilve)
-                {
-                     _vc.invalid(XmlErrorCodes.ANYURI, new Object[] { value });
+
+                if (errorState == _errorState) {
+                    _decimalValue = new BigDecimal(value);
+                    JavaDecimalHolderEx.validateValue(_decimalValue, type, _vc);
                 }
+
+                break;
             }
-            _stringValue = value;
-            break;
-        }
-        case SchemaType.BTC_G_MONTH :
-        {
-            // In the case of gMonth, there is some strict mode validation to do
-            if (_strict && value.length() == 6 &&
-                value.charAt( 4 ) == '-' && value.charAt( 5 ) == '-')
-                _vc.invalid(XmlErrorCodes.DATE, new Object[] { value });
-            // Fall through
-        }
-        case SchemaType.BTC_DATE_TIME :
-        case SchemaType.BTC_TIME :
-        case SchemaType.BTC_DATE :
-        case SchemaType.BTC_G_YEAR_MONTH :
-        case SchemaType.BTC_G_YEAR :
-        case SchemaType.BTC_G_MONTH_DAY :
-        case SchemaType.BTC_G_DAY :
-        {
-            GDate d = XmlDateImpl.validateLexical( value, type, _vc );
+            case SchemaType.BTC_BOOLEAN: {
+                _booleanValue = JavaBooleanHolderEx.validateLexical(value, type, _vc);
+                break;
+            }
+            case SchemaType.BTC_FLOAT: {
+                float f =
+                    JavaFloatHolderEx.validateLexical(value, type, _vc);
 
-            if (d != null)
-                XmlDateImpl.validateValue( d, type, _vc );
+                if (errorState == _errorState) {
+                    JavaFloatHolderEx.validateValue(f, type, _vc);
+                }
 
-            _gdateValue = d;
-            break;
-        }
-        case SchemaType.BTC_DURATION :
-        {
-            GDuration d = XmlDurationImpl.validateLexical( value, type, _vc );
+                _floatValue = f;
+                break;
+            }
+            case SchemaType.BTC_DOUBLE: {
+                double d =
+                    JavaDoubleHolderEx.validateLexical(value, type, _vc);
 
-            if (d != null)
-                XmlDurationImpl.validateValue( d, type, _vc );
+                if (errorState == _errorState) {
+                    JavaDoubleHolderEx.validateValue(d, type, _vc);
+                }
 
-            _gdurationValue = d;
-            break;
-        }
-        case SchemaType.BTC_BASE_64_BINARY :
-        {
-            byte[] v =
-                JavaBase64HolderEx.validateLexical( value, type, _vc );
+                _doubleValue = d;
+                break;
+            }
+            case SchemaType.BTC_QNAME: {
+                QName n =
+                    JavaQNameHolderEx.validateLexical(
+                        value, type, _vc, event);
 
-            if (v != null)
-                JavaBase64HolderEx.validateValue( v, type, _vc );
+                if (errorState == _errorState) {
+                    JavaQNameHolderEx.validateValue(n, type, _vc);
+                }
 
-            _byteArrayValue = v;
-            break;
-        }
-        case SchemaType.BTC_HEX_BINARY :
-        {
-            byte[] v =
-                JavaHexBinaryHolderEx.validateLexical( value, type, _vc );
+                _qnameValue = n;
+                break;
+            }
+            case SchemaType.BTC_ANY_URI: {
+                JavaUriHolderEx.validateLexical(value, type, _vc);
+                // Do strict validation
+                if (_strict) {
+                    try {
+                        XsTypeConverter.lexAnyURI(value);
+                    } catch (InvalidLexicalValueException ilve) {
+                        _vc.invalid(XmlErrorCodes.ANYURI, new Object[]{value});
+                    }
+                }
+                _stringValue = value;
+                break;
+            }
+            case SchemaType.BTC_G_MONTH: {
+                // In the case of gMonth, there is some strict mode validation to do
+                if (_strict && value.length() == 6 &&
+                    value.charAt(4) == '-' && value.charAt(5) == '-') {
+                    _vc.invalid(XmlErrorCodes.DATE, new Object[]{value});
+                }
+                // Fall through
+            }
+            case SchemaType.BTC_DATE_TIME:
+            case SchemaType.BTC_TIME:
+            case SchemaType.BTC_DATE:
+            case SchemaType.BTC_G_YEAR_MONTH:
+            case SchemaType.BTC_G_YEAR:
+            case SchemaType.BTC_G_MONTH_DAY:
+            case SchemaType.BTC_G_DAY: {
+                GDate d = XmlDateImpl.validateLexical(value, type, _vc);
 
-            if (v != null)
-                JavaHexBinaryHolderEx.validateValue( v, type, _vc );
+                if (d != null) {
+                    XmlDateImpl.validateValue(d, type, _vc);
+                }
 
-            _byteArrayValue = v;
-            break;
-        }
-        case SchemaType.BTC_NOTATION :
-        {
-            QName n =
-                JavaNotationHolderEx.validateLexical(
-                    value, type, _vc, event );
+                _gdateValue = d;
+                break;
+            }
+            case SchemaType.BTC_DURATION: {
+                GDuration d = XmlDurationImpl.validateLexical(value, type, _vc);
 
-            if (errorState == _errorState)
-                JavaNotationHolderEx.validateValue( n, type, _vc );
+                if (d != null) {
+                    XmlDurationImpl.validateValue(d, type, _vc);
+                }
 
-            _qnameValue = n;
-            break;
-        }
+                _gdurationValue = d;
+                break;
+            }
+            case SchemaType.BTC_BASE_64_BINARY: {
+                byte[] v =
+                    JavaBase64HolderEx.validateLexical(value, type, _vc);
 
-        default :
-            throw new RuntimeException( "Unexpected primitive type code" );
+                if (v != null) {
+                    JavaBase64HolderEx.validateValue(v, type, _vc);
+                }
+
+                _byteArrayValue = v;
+                break;
+            }
+            case SchemaType.BTC_HEX_BINARY: {
+                byte[] v =
+                    JavaHexBinaryHolderEx.validateLexical(value, type, _vc);
+
+                if (v != null) {
+                    JavaHexBinaryHolderEx.validateValue(v, type, _vc);
+                }
+
+                _byteArrayValue = v;
+                break;
+            }
+            case SchemaType.BTC_NOTATION: {
+                QName n =
+                    JavaNotationHolderEx.validateLexical(
+                        value, type, _vc, event);
+
+                if (errorState == _errorState) {
+                    JavaNotationHolderEx.validateValue(n, type, _vc);
+                }
+
+                _qnameValue = n;
+                break;
+            }
+
+            default:
+                throw new RuntimeException("Unexpected primitive type code");
         }
     }
 
-    private void validateListType (
-        SchemaType type, String value, Event event )
-    {
+    private void validateListType(
+        SchemaType type, String value, Event event) {
         int errorState = _errorState;
 
-        if (!type.matchPatternFacet( value ))
-        {
+        if (!type.matchPatternFacet(value)) {
             emitError(event, XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID,
-                new Object[] { "list", value, QNameHelper.readable(type) },
+                new Object[]{"list", value, QNameHelper.readable(type)},
                 null, type, null, XmlValidationError.LIST_INVALID, null);
         }
 
@@ -1466,35 +1295,29 @@
         int i;
         XmlObject o;
 
-        if ((o = type.getFacet( SchemaType.FACET_LENGTH )) != null)
-        {
-            if ((i = ((SimpleValue)o).getIntValue()) != items.length)
-            {
+        if ((o = type.getFacet(SchemaType.FACET_LENGTH)) != null) {
+            if ((i = ((SimpleValue) o).getIntValue()) != items.length) {
                 //offending Qname not valid
                 emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH,
-                    new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) },
+                    new Object[]{value, new Integer(items.length), new Integer(i), QNameHelper.readable(type)},
                     null, type, null, XmlValidationError.LIST_INVALID, null);
             }
         }
 
-        if ((o = type.getFacet( SchemaType.FACET_MIN_LENGTH )) != null)
-        {
-            if ((i = ((SimpleValue)o).getIntValue()) > items.length)
-            {
+        if ((o = type.getFacet(SchemaType.FACET_MIN_LENGTH)) != null) {
+            if ((i = ((SimpleValue) o).getIntValue()) > items.length) {
                 //offending Qname not valid
                 emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH,
-                    new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) },
+                    new Object[]{value, new Integer(items.length), new Integer(i), QNameHelper.readable(type)},
                     null, type, null, XmlValidationError.LIST_INVALID, null);
             }
         }
 
-        if ((o = type.getFacet( SchemaType.FACET_MAX_LENGTH )) != null)
-        {
-            if ((i = ((SimpleValue)o).getIntValue()) < items.length)
-            {
+        if ((o = type.getFacet(SchemaType.FACET_MAX_LENGTH)) != null) {
+            if ((i = ((SimpleValue) o).getIntValue()) < items.length) {
                 //offending Qname not valid
                 emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH,
-                    new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) },
+                    new Object[]{value, new Integer(items.length), new Integer(i), QNameHelper.readable(type)},
                     null, type, null, XmlValidationError.LIST_INVALID, null);
             }
         }
@@ -1503,55 +1326,45 @@
         _listValue = new ArrayList();
         _listTypes = new ArrayList();
 
-        for ( i = 0 ; i < items.length ; i++ )
-        {
+        for (i = 0; i < items.length; i++) {
             validateSimpleType(
-                itemType, items[i], event );
+                itemType, items[i], event);
             addToList(itemType);
         }
 
         // If no errors up to this point, then I can create an
         // XmlList from this value and campare it again enums.
 
-        if (errorState == _errorState)
-        {
-            if (type.getEnumerationValues() != null)
-            {
+        if (errorState == _errorState) {
+            if (type.getEnumerationValues() != null) {
                 // Lists which contain QNames will need a resolver
 
                 NamespaceContext.push(
-                    new NamespaceContext( event ) );
+                    new NamespaceContext(event));
 
-                try
-                {
-                    XmlObject listValue = ( (SchemaTypeImpl) type).newValidatingValue( value );
-                }
-                catch (XmlValueOutOfRangeException e)
-                {
+                try {
+                    XmlObject listValue = ((SchemaTypeImpl) type).newValidatingValue(value);
+                } catch (XmlValueOutOfRangeException e) {
                     //offending Qname not valid ??
                     emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID,
-                        new Object[] { "list", value, QNameHelper.readable(type) },
+                        new Object[]{"list", value, QNameHelper.readable(type)},
                         null, type, null, XmlValidationError.LIST_INVALID, null);
-                }
-                finally
-                {
+                } finally {
                     NamespaceContext.pop();
                 }
             }
         }
     }
 
-    private void validateUnionType (
-        SchemaType type, String value, Event event )
-    {
+    private void validateUnionType(
+        SchemaType type, String value, Event event) {
         // TODO - if xsi:type is specified on a union, it selects
         // that union member type
 
-        if (!type.matchPatternFacet( value ))
-        {
+        if (!type.matchPatternFacet(value)) {
             //offending Qname not valid ??
             emitError(event, XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID,
-                new Object[] { "union", value, QNameHelper.readable(type) },
+                new Object[]{"union", value, QNameHelper.readable(type)},
                 null, type, null, XmlValidationError.UNION_INVALID, null);
         }
 
@@ -1563,34 +1376,29 @@
         int originalState = _errorState;
 
         int i;
-        for ( i = 0 ; i < types.length ; i++ )
-        {
-            int memberWsr = types[ i ].getWhiteSpaceRule();
+        for (i = 0; i < types.length; i++) {
+            int memberWsr = types[i].getWhiteSpaceRule();
 
-            if (memberWsr == SchemaType.WS_UNSPECIFIED)
+            if (memberWsr == SchemaType.WS_UNSPECIFIED) {
                 memberWsr = SchemaType.WS_PRESERVE;
+            }
 
-            if (memberWsr != currentWsr)
-            {
+            if (memberWsr != currentWsr) {
                 currentWsr = memberWsr;
-                currentValue = XmlWhitespace.collapse( value, currentWsr );
+                currentValue = XmlWhitespace.collapse(value, currentWsr);
             }
 
             int originalErrorState = _errorState;
 
             _suspendErrors++;
 
-            try
-            {
-                validateSimpleType( types[ i ], currentValue, event );
-            }
-            finally
-            {
+            try {
+                validateSimpleType(types[i], currentValue, event);
+            } finally {
                 _suspendErrors--;
             }
 
-            if (originalErrorState == _errorState)
-            {
+            if (originalErrorState == _errorState) {
                 _unionType = types[i];
                 break;
             }
@@ -1598,168 +1406,142 @@
 
         _errorState = originalState;
 
-        if (i >= types.length)
-        {
+        if (i >= types.length) {
             //offending Qname not valid ??
             emitError(event, XmlErrorCodes.DATATYPE_VALID$UNION,
-                new Object[] { value, QNameHelper.readable(type) },
+                new Object[]{value, QNameHelper.readable(type)},
                 null, type, null, XmlValidationError.UNION_INVALID, null);
-        }
-        else
-        {
+        } else {
             XmlObject[] unionEnumvals = type.getEnumerationValues();
 
-            if (unionEnumvals != null)
-            {
+            if (unionEnumvals != null) {
                 // Unions which contain QNames will need a resolver
 
-                NamespaceContext.push( new NamespaceContext( event ) );
+                NamespaceContext.push(new NamespaceContext(event));
 
-                try
-                {
-                    XmlObject unionValue = type.newValue( value );
+                try {
+                    XmlObject unionValue = type.newValue(value);
 
-                    for ( i = 0 ; i < unionEnumvals.length ; i++ )
-                    {
-                        if (unionValue.valueEquals( unionEnumvals[ i ] ))
+                    for (i = 0; i < unionEnumvals.length; i++) {
+                        if (unionValue.valueEquals(unionEnumvals[i])) {
                             break;
+                        }
                     }
 
-                    if (i >= unionEnumvals.length)
-                    {
+                    if (i >= unionEnumvals.length) {
                         //offending Qname not valid ??
                         emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID,
-                            new Object[] { "union", value, QNameHelper.readable(type) },
+                            new Object[]{"union", value, QNameHelper.readable(type)},
                             null, type, null, XmlValidationError.UNION_INVALID, null);
                     }
-                }
-                catch (XmlValueOutOfRangeException e)
-                {
+                } catch (XmlValueOutOfRangeException e) {
                     // actually, the current union code always ends up here when invalid
 
                     //offending Qname not valid ??
                     emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID,
-                        new Object[] { "union", value, QNameHelper.readable(type) },
+                        new Object[]{"union", value, QNameHelper.readable(type)},
                         null, type, null, XmlValidationError.UNION_INVALID, null);
-                }
-                finally
-                {
+                } finally {
                     NamespaceContext.pop();
                 }
             }
         }
     }
 
-    private void addToList(SchemaType type)
-    {
+    private void addToList(SchemaType type) {
         if (type.getSimpleVariety() != SchemaType.ATOMIC &&
-            type.getSimpleVariety() != SchemaType.UNION)
+            type.getSimpleVariety() != SchemaType.UNION) {
             return;
+        }
 
-        if (type.getUnionMemberTypes().length>0 && getUnionType()!=null)
-        {
+        if (type.getUnionMemberTypes().length > 0 && getUnionType() != null) {
             type = getUnionType();
             _unionType = null;
         }
 
         _listTypes.add(type);
 
-        if (type.getPrimitiveType() == null)
-        {
+        if (type.getPrimitiveType() == null) {
             // instance has an error for this value so there is no primitive type.
             // an error should already have been produced.
             _listValue.add(null);
             return;
         }
 
-        switch ( type.getPrimitiveType().getBuiltinTypeCode() )
-        {
-            case SchemaType.BTC_ANY_SIMPLE :
-                {
-                    _listValue.add(_stringValue);
-                    break;
-                }
-            case SchemaType.BTC_STRING :
-                {
-                    _listValue.add(_stringValue);
-                    _stringValue = null;
-                    break;
-                }
-            case SchemaType.BTC_DECIMAL :
-                {
-                    _listValue.add( _decimalValue );
-                    _decimalValue = null;
-                    break;
-                }
-            case SchemaType.BTC_BOOLEAN :
-                {
-                    _listValue.add(_booleanValue ? Boolean.TRUE : Boolean.FALSE);
-                    _booleanValue = false;
-                    break;
-                }
-            case SchemaType.BTC_FLOAT :
-                {
-                    _listValue.add(new Float(_floatValue));
-                    _floatValue = 0;
-                    break;
-                }
-            case SchemaType.BTC_DOUBLE :
-                {
-                    _listValue.add(new Double(_doubleValue));
-                    _doubleValue = 0;
-                    break;
-                }
-            case SchemaType.BTC_QNAME :
-                {
-                    _listValue.add(_qnameValue);
-                    _qnameValue = null;
-                    break;
-                }
-            case SchemaType.BTC_ANY_URI :
-                {
-                    _listTypes.add(_stringValue);
-                    break;
-                }
-            case SchemaType.BTC_DATE_TIME :
-            case SchemaType.BTC_TIME :
-            case SchemaType.BTC_DATE :
-            case SchemaType.BTC_G_YEAR_MONTH :
-            case SchemaType.BTC_G_YEAR :
-            case SchemaType.BTC_G_MONTH_DAY :
-            case SchemaType.BTC_G_DAY :
-            case SchemaType.BTC_G_MONTH :
-                {
-                    _listValue.add(_gdateValue);
-                    _gdateValue = null;
-                    break;
-                }
-            case SchemaType.BTC_DURATION :
-                {
-                    _listValue.add(_gdurationValue);
-                    _gdurationValue = null;
-                    break;
-                }
-            case SchemaType.BTC_BASE_64_BINARY :
-                {
-                    _listValue.add(_byteArrayValue);
-                    _byteArrayValue = null;
-                    break;
-                }
-            case SchemaType.BTC_HEX_BINARY :
-                {
-                    _listValue.add(_byteArrayValue);
-                    _byteArrayValue = null;
-                    break;
-                }
-            case SchemaType.BTC_NOTATION :
-                {
-                    _listValue.add(_qnameValue);
-                    _qnameValue = null;
-                    break;
-                }
+        switch (type.getPrimitiveType().getBuiltinTypeCode()) {
+            case SchemaType.BTC_ANY_SIMPLE: {
+                _listValue.add(_stringValue);
+                break;
+            }
+            case SchemaType.BTC_STRING: {
+                _listValue.add(_stringValue);
+                _stringValue = null;
+                break;
+            }
+            case SchemaType.BTC_DECIMAL: {
+                _listValue.add(_decimalValue);
+                _decimalValue = null;
+                break;
+            }
+            case SchemaType.BTC_BOOLEAN: {
+                _listValue.add(_booleanValue ? Boolean.TRUE : Boolean.FALSE);
+                _booleanValue = false;
+                break;
+            }
+            case SchemaType.BTC_FLOAT: {
+                _listValue.add(new Float(_floatValue));
+                _floatValue = 0;
+                break;
+            }
+            case SchemaType.BTC_DOUBLE: {
+                _listValue.add(new Double(_doubleValue));
+                _doubleValue = 0;
+                break;
+            }
+            case SchemaType.BTC_QNAME: {
+                _listValue.add(_qnameValue);
+                _qnameValue = null;
+                break;
+            }
+            case SchemaType.BTC_ANY_URI: {
+                _listTypes.add(_stringValue);
+                break;
+            }
+            case SchemaType.BTC_DATE_TIME:
+            case SchemaType.BTC_TIME:
+            case SchemaType.BTC_DATE:
+            case SchemaType.BTC_G_YEAR_MONTH:
+            case SchemaType.BTC_G_YEAR:
+            case SchemaType.BTC_G_MONTH_DAY:
+            case SchemaType.BTC_G_DAY:
+            case SchemaType.BTC_G_MONTH: {
+                _listValue.add(_gdateValue);
+                _gdateValue = null;
+                break;
+            }
+            case SchemaType.BTC_DURATION: {
+                _listValue.add(_gdurationValue);
+                _gdurationValue = null;
+                break;
+            }
+            case SchemaType.BTC_BASE_64_BINARY: {
+                _listValue.add(_byteArrayValue);
+                _byteArrayValue = null;
+                break;
+            }
+            case SchemaType.BTC_HEX_BINARY: {
+                _listValue.add(_byteArrayValue);
+                _byteArrayValue = null;
+                break;
+            }
+            case SchemaType.BTC_NOTATION: {
+                _listValue.add(_qnameValue);
+                _qnameValue = null;
+                break;
+            }
 
-            default :
-                throw new RuntimeException( "Unexpected primitive type code" );
+            default:
+                throw new RuntimeException("Unexpected primitive type code");
         }
     }
 
@@ -1767,25 +1549,25 @@
     // Members of the validator class
     //
 
-    private boolean            _invalid;
-    private SchemaType         _rootType;
-    private SchemaField        _rootField;
-    private SchemaTypeLoader   _globalTypes;
-    private State              _stateStack;
-    private int                _errorState;
-    private Collection         _errorListener;
-    private boolean            _treatLaxAsSkip;
-    private boolean            _strict;
-    private ValidatorVC        _vc;
-    private int                _suspendErrors;
+    private boolean _invalid;
+    private SchemaType _rootType;
+    private SchemaField _rootField;
+    private SchemaTypeLoader _globalTypes;
+    private State _stateStack;
+    private int _errorState;
+    private Collection<XmlError> _errorListener;
+    private boolean _treatLaxAsSkip;
+    private boolean _strict;
+    private ValidatorVC _vc;
+    private int _suspendErrors;
     private IdentityConstraint _constraintEngine;
-    private int                _eatContent;
+    private int _eatContent;
 
-    private SchemaLocalElement   _localElement;
-    private SchemaParticle       _wildcardElement;
+    private SchemaLocalElement _localElement;
+    private SchemaParticle _wildcardElement;
     private SchemaLocalAttribute _localAttribute;
     private SchemaAttributeModel _wildcardAttribute;
-    private SchemaType           _unionType;
+    private SchemaType _unionType;
 
     // Strongly typed values
     private String _stringValue;
@@ -1800,8 +1582,7 @@
     private List _listValue;
     private List _listTypes;
 
-    private void resetValues()
-    {
+    private void resetValues() {
         _localAttribute = null;
         _wildcardAttribute = null;
         _stringValue = null;
@@ -1828,11 +1609,11 @@
      * see {@link SchemaType#isNoType}. Or can be the parent type, for unrecognized elements
      * that are part of wildcards.
      */
-    public SchemaType getCurrentElementSchemaType ( )
-    {
+    public SchemaType getCurrentElementSchemaType() {
         State state = topState();
-        if (state!=null)
+        if (state != null) {
             return state._type;
+        }
 
         return null;
     }
@@ -1840,20 +1621,22 @@
     /**
      * @return Returns the curent local element, null if one is not available, see {@link #getCurrentWildcardElement()}.
      */
-    public SchemaLocalElement getCurrentElement ( )
-    {
-        if (_localElement != null)
+    public SchemaLocalElement getCurrentElement() {
+        if (_localElement != null) {
             return _localElement;
+        }
 
         // it means the element is to be skiped and it doesn't have a known SchemaLocalElement
 
-        if (_eatContent > 0)
+        if (_eatContent > 0) {
             return null;
+        }
 
         //try getting it from the stack (this should happen after END)
 
-        if (_stateStack != null && _stateStack._field instanceof SchemaLocalElement)
+        if (_stateStack != null && _stateStack._field instanceof SchemaLocalElement) {
             return (SchemaLocalElement) _stateStack._field;
+        }
 
         return null;
     }
@@ -1862,8 +1645,7 @@
      * @return Returns the current particle, if this is a wildcard particle {@link SchemaParticle#WILDCARD}
      * method {@link #getCurrentElement()} might return null if wildcard's processContents is skip or lax.
      */
-    public SchemaParticle getCurrentWildcardElement()
-    {
+    public SchemaParticle getCurrentWildcardElement() {
         return _wildcardElement;
     }
 
@@ -1871,76 +1653,62 @@
      * @return Returns the curent local attribute, global attribute if the current attribute is part of an
      * attribute wildcard, or null if none is available.
      */
-    public SchemaLocalAttribute getCurrentAttribute()
-    {
+    public SchemaLocalAttribute getCurrentAttribute() {
         return _localAttribute;
     }
 
     /**
      * @return Returns the attribute model for attributes if available, else null is returned.
      */
-    public SchemaAttributeModel getCurrentWildcardAttribute()
-    {
+    public SchemaAttributeModel getCurrentWildcardAttribute() {
         return _wildcardAttribute;
     }
 
-    public String getStringValue()
-    {
+    public String getStringValue() {
         return _stringValue;
     }
 
-    public BigDecimal getDecimalValue()
-    {
+    public BigDecimal getDecimalValue() {
         return _decimalValue;
     }
 
-    public boolean getBooleanValue()
-    {
+    public boolean getBooleanValue() {
         return _booleanValue;
     }
 
-    public float getFloatValue()
-    {
+    public float getFloatValue() {
         return _floatValue;
     }
 
-    public double getDoubleValue()
-    {
+    public double getDoubleValue() {
         return _doubleValue;
     }
 
-    public QName getQNameValue()
-    {
+    public QName getQNameValue() {
         return _qnameValue;
     }
 
-    public GDate getGDateValue()
-    {
+    public GDate getGDateValue() {
         return _gdateValue;
     }
 
-    public GDuration getGDurationValue()
-    {
+    public GDuration getGDurationValue() {
         return _gdurationValue;
     }
 
-    public byte[] getByteArrayValue()
-    {
+    public byte[] getByteArrayValue() {
         return _byteArrayValue;
     }
 
-    public List getListValue()
-    {
+    public List getListValue() {
         return _listValue;
     }
 
-    public List getListTypes()
-    {
+    public List getListTypes() {
         return _listTypes;
     }
 
-    public SchemaType getUnionType()
-    {
+    public SchemaType getUnionType() {
         return _unionType;
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/values/XmlObjectBase.java b/src/main/java/org/apache/xmlbeans/impl/values/XmlObjectBase.java
index 2a2a12a..6456f97 100644
--- a/src/main/java/org/apache/xmlbeans/impl/values/XmlObjectBase.java
+++ b/src/main/java/org/apache/xmlbeans/impl/values/XmlObjectBase.java
@@ -15,131 +15,81 @@
 
 package org.apache.xmlbeans.impl.values;
 
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamReader;
-
-import org.apache.xmlbeans.xml.stream.XMLInputStream;
-
-import java.math.BigInteger;
-import java.math.BigDecimal;
-import java.io.Serializable;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.lang.reflect.Array;
-import java.util.Date;
-import java.util.List;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.ArrayList;
-
-import org.apache.xmlbeans.impl.common.XmlLocale;
-import org.apache.xmlbeans.impl.common.XmlWhitespace;
-import org.apache.xmlbeans.impl.common.ValidationContext;
-import org.apache.xmlbeans.impl.common.GlobalLock;
-import org.apache.xmlbeans.impl.common.XmlErrorWatcher;
-import org.apache.xmlbeans.impl.common.QNameHelper;
+import org.apache.xmlbeans.*;
+import org.apache.xmlbeans.impl.common.*;
 import org.apache.xmlbeans.impl.schema.SchemaTypeImpl;
 import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl;
 import org.apache.xmlbeans.impl.validator.Validator;
-import org.apache.xmlbeans.XmlErrorCodes;
-import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.SchemaAttributeModel;
-import org.apache.xmlbeans.XmlAnySimpleType;
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlOptions;
-import org.apache.xmlbeans.XmlDocumentProperties;
-import org.apache.xmlbeans.SimpleValue;
-import org.apache.xmlbeans.SchemaType;
-import org.apache.xmlbeans.SchemaField;
-import org.apache.xmlbeans.SchemaProperty;
-import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlRuntimeException;
-import org.apache.xmlbeans.QNameSet;
-import org.apache.xmlbeans.GDate;
-import org.apache.xmlbeans.GDuration;
-import org.apache.xmlbeans.GDateSpecification;
-import org.apache.xmlbeans.GDurationSpecification;
-import org.apache.xmlbeans.StringEnumAbstractBase;
-import org.apache.xmlbeans.XmlBeans;
-import org.apache.xmlbeans.XmlError;
-import org.apache.xmlbeans.SchemaLocalAttribute;
-import org.apache.xmlbeans.DelegateXmlObject;
-import org.apache.xmlbeans.SchemaTypeLoader;
-
+import org.apache.xmlbeans.xml.stream.XMLInputStream;
 import org.w3c.dom.Node;
-
 import org.xml.sax.ContentHandler;
-import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
 
-public abstract class XmlObjectBase implements TypeStoreUser, Serializable, XmlObject, SimpleValue
-{
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+public abstract class XmlObjectBase implements TypeStoreUser, Serializable, XmlObject, SimpleValue {
     public static final short MAJOR_VERSION_NUMBER = (short) 1; // for serialization
     public static final short MINOR_VERSION_NUMBER = (short) 1; // for serialization
 
     public static final short KIND_SETTERHELPER_SINGLETON = 1;
     public static final short KIND_SETTERHELPER_ARRAYITEM = 2;
 
-    public final Object monitor()
-    {
-        if (has_store())
+    public final Object monitor() {
+        if (has_store()) {
             return get_store().get_locale();
+        }
         return this;
     }
 
-    private static XmlObjectBase underlying(XmlObject obj)
-    {
-        if (obj == null)
+    private static XmlObjectBase underlying(XmlObject obj) {
+        if (obj == null) {
             return null;
-        if (obj instanceof XmlObjectBase)
-            return (XmlObjectBase)obj;
-        while (obj instanceof DelegateXmlObject)
-            obj = ((DelegateXmlObject)obj).underlyingXmlObject();
-        if (obj instanceof XmlObjectBase)
-            return (XmlObjectBase)obj;
+        }
+        if (obj instanceof XmlObjectBase) {
+            return (XmlObjectBase) obj;
+        }
+        while (obj instanceof DelegateXmlObject) {
+            obj = ((DelegateXmlObject) obj).underlyingXmlObject();
+        }
+        if (obj instanceof XmlObjectBase) {
+            return (XmlObjectBase) obj;
+        }
         throw new IllegalStateException("Non-native implementations of XmlObject should extend FilterXmlObject or implement DelegateXmlObject");
     }
 
-    public final XmlObject copy()
-    {
-        if (preCheck())
+    public final XmlObject copy() {
+        if (preCheck()) {
             return _copy();
-        else
-            synchronized (monitor())
-            {
+        } else {
+            synchronized (monitor()) {
                 return _copy();
             }
+        }
     }
 
-    public final XmlObject copy(XmlOptions options)
-    {
-        if (preCheck())
+    public final XmlObject copy(XmlOptions options) {
+        if (preCheck()) {
             return _copy(options);
-        else
-            synchronized (monitor())
-            {
+        } else {
+            synchronized (monitor()) {
                 return _copy(options);
             }
+        }
     }
 
-    private boolean preCheck()
-    {
+    private boolean preCheck() {
 //        if ( isImmutable() )
 //            return true;
-        if ( has_store() )
+        if (has_store()) {
             return get_store().get_locale().noSync();
+        }
         return false;
     }
 
@@ -147,8 +97,7 @@
      * Same as copy() but unsynchronized.
      * Warning: Using this method in mutithreaded environment can cause invalid states.
      */
-    public final XmlObject _copy()
-    {
+    public final XmlObject _copy() {
         return _copy(null);
     }
 
@@ -157,131 +106,208 @@
      * If Locale.COPY_USE_NEW_LOCALE is set in the options, a new locale will be created for the copy.
      * Warning: Using this method in mutithreaded environment can cause invalid states.
      */
-    public final XmlObject _copy(XmlOptions xmlOptions)
-    {
+    public final XmlObject _copy(XmlOptions xmlOptions) {
         // immutable objects don't get copied. They're immutable
-        if (isImmutable())
+        if (isImmutable()) {
             return this;
+        }
 
         check_orphaned();
 
         SchemaTypeLoader stl = get_store().get_schematypeloader();
-        XmlObject result = (XmlObject)get_store().copy(stl, schemaType(), xmlOptions);
 
-        return result;
+        return (XmlObject) get_store().copy(stl, schemaType(), xmlOptions);
     }
 
-    public XmlDocumentProperties documentProperties()
-        { XmlCursor cur = newCursorForce(); try { return cur.documentProperties(); } finally { cur.dispose(); } }
+    public XmlDocumentProperties documentProperties() {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.documentProperties();
+        } finally {
+            cur.dispose();
+        }
+    }
 
     /**
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
-    public XMLInputStream newXMLInputStream()
-        { return newXMLInputStream(null); }
+    public XMLInputStream newXMLInputStream() {
+        return newXMLInputStream(null);
+    }
 
     /**
      * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
      */
-    public XMLInputStream newXMLInputStream(XmlOptions options)
-        { XmlCursor cur = newCursorForce(); try { return cur.newXMLInputStream(makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public XMLInputStream newXMLInputStream(XmlOptions options) {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.newXMLInputStream(makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public XMLStreamReader newXMLStreamReader()
-        { return newXMLStreamReader(null); }
+    public XMLStreamReader newXMLStreamReader() {
+        return newXMLStreamReader(null);
+    }
 
-    public XMLStreamReader newXMLStreamReader(XmlOptions options)
-        { XmlCursor cur = newCursorForce(); try { return cur.newXMLStreamReader(makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public XMLStreamReader newXMLStreamReader(XmlOptions options) {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.newXMLStreamReader(makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public InputStream newInputStream()
-        { return newInputStream(null); }
+    public InputStream newInputStream() {
+        return newInputStream(null);
+    }
 
-    public InputStream newInputStream(XmlOptions options)
-        { XmlCursor cur = newCursorForce(); try { return cur.newInputStream(makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public InputStream newInputStream(XmlOptions options) {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.newInputStream(makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public Reader newReader()
-        { return newReader(null); }
+    public Reader newReader() {
+        return newReader(null);
+    }
 
-    public Reader newReader(XmlOptions options)
-        { XmlCursor cur = newCursorForce(); try { return cur.newReader(makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public Reader newReader(XmlOptions options) {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.newReader(makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public Node getDomNode()
-        { XmlCursor cur = newCursorForce(); try { return cur.getDomNode(); } finally { cur.dispose(); } }
+    public Node getDomNode() {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.getDomNode();
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public Node newDomNode()
-        { return newDomNode(null); }
+    public Node newDomNode() {
+        return newDomNode(null);
+    }
 
-    public Node newDomNode(XmlOptions options)
-        { XmlCursor cur = newCursorForce(); try { return cur.newDomNode(makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public Node newDomNode(XmlOptions options) {
+        XmlCursor cur = newCursorForce();
+        try {
+            return cur.newDomNode(makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException
-        { XmlCursor cur = newCursorForce(); try { cur.save(ch, lh, makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException {
+        XmlCursor cur = newCursorForce();
+        try {
+            cur.save(ch, lh, makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public void save(File file, XmlOptions options) throws IOException
-        { XmlCursor cur = newCursorForce(); try { cur.save(file, makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public void save(File file, XmlOptions options) throws IOException {
+        XmlCursor cur = newCursorForce();
+        try {
+            cur.save(file, makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public void save(OutputStream os, XmlOptions options) throws IOException
-        { XmlCursor cur = newCursorForce(); try { cur.save(os, makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public void save(OutputStream os, XmlOptions options) throws IOException {
+        XmlCursor cur = newCursorForce();
+        try {
+            cur.save(os, makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public void save(Writer w, XmlOptions options) throws IOException
-        { XmlCursor cur = newCursorForce(); try { cur.save(w, makeInnerOptions(options)); } finally { cur.dispose(); } }
+    public void save(Writer w, XmlOptions options) throws IOException {
+        XmlCursor cur = newCursorForce();
+        try {
+            cur.save(w, makeInnerOptions(options));
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public void save(ContentHandler ch, LexicalHandler lh) throws SAXException
-        { save( ch, lh, null ); }
+    public void save(ContentHandler ch, LexicalHandler lh) throws SAXException {
+        save(ch, lh, null);
+    }
 
-    public void save(File file) throws IOException
-        { save( file, null ); }
+    public void save(File file) throws IOException {
+        save(file, null);
+    }
 
-    public void save(OutputStream os) throws IOException
-        { save( os, null ); }
+    public void save(OutputStream os) throws IOException {
+        save(os, null);
+    }
 
-    public void save(Writer w) throws IOException
-        { save( w, null ); }
+    public void save(Writer w) throws IOException {
+        save(w, null);
+    }
 
-    public void dump()
-        { XmlCursor cur = newCursorForce(); try { cur.dump(); } finally { cur.dispose(); } }
+    public void dump() {
+        XmlCursor cur = newCursorForce();
+        try {
+            cur.dump();
+        } finally {
+            cur.dispose();
+        }
+    }
 
-    public XmlCursor newCursorForce()
-    {
-        synchronized (monitor())
-        {
+    public XmlCursor newCursorForce() {
+        synchronized (monitor()) {
             return ensureStore().newCursor();
         }
     }
 
-    private XmlObject ensureStore()
-    {
-        if ((_flags & FLAG_STORE) != 0)
+    private XmlObject ensureStore() {
+        if ((_flags & FLAG_STORE) != 0) {
             return this;
+        }
 
         check_dated();
 
         String value =
             (_flags & FLAG_NIL) != 0
                 ? ""
-                : compute_text( has_store() ? get_store() : null );
+                : compute_text(has_store() ? get_store() : null);
 
         XmlOptions options = new XmlOptions().setDocumentType(schemaType());
 
-        XmlObject x = XmlObject.Factory.newInstance( options );
+        XmlObject x = XmlObject.Factory.newInstance(options);
 
         XmlCursor c = x.newCursor();
         c.toNextToken();
-        c.insertChars( value );
+        c.insertChars(value);
 
         return x;
     }
 
-    private static XmlOptions makeInnerOptions(XmlOptions options)
-    {
-        XmlOptions innerOptions = new XmlOptions( options );
-        innerOptions.put( XmlOptions.SAVE_INNER );
+    private static XmlOptions makeInnerOptions(XmlOptions options) {
+        XmlOptions innerOptions = new XmlOptions(options);
+        innerOptions.setSaveInner();
         return innerOptions;
     }
 
-    public XmlCursor newCursor()
-    {
-        if ((_flags & FLAG_STORE) == 0)
+    public XmlCursor newCursor() {
+        if ((_flags & FLAG_STORE) == 0) {
             throw new IllegalStateException("XML Value Objects cannot create cursors");
+        }
 
         check_orphaned();
 
@@ -289,15 +315,33 @@
 
         XmlLocale l = getXmlLocale();
 
-        if (l.noSync())         { l.enter(); try { return get_store().new_cursor(); } finally { l.exit(); } }
-        else synchronized ( l ) { l.enter(); try { return get_store().new_cursor(); } finally { l.exit(); } }
+        if (l.noSync()) {
+            l.enter();
+            try {
+                return get_store().new_cursor();
+            } finally {
+                l.exit();
+            }
+        } else {
+            synchronized (l) {
+                l.enter();
+                try {
+                    return get_store().new_cursor();
+                } finally {
+                    l.exit();
+                }
+            }
+        }
 
     }
 
     public abstract SchemaType schemaType();
 
-    public SchemaType instanceType()
-        { synchronized (monitor()) { return isNil() ? null : schemaType(); } }
+    public SchemaType instanceType() {
+        synchronized (monitor()) {
+            return isNil() ? null : schemaType();
+        }
+    }
 
     private SchemaField schemaField() {
         SchemaType st = schemaType();
@@ -306,8 +350,9 @@
         // First check if this field has an anonymous type
         field = st.getContainerField();
 
-        if (field == null)
+        if (field == null) {
             field = get_store().get_schema_field();
+        }
 
         return field;
     }
@@ -316,63 +361,57 @@
      * Use _voorVc when you want to throw a ValueOutOfRangeException when
      * validating a simple type.
      */
-    private static final class ValueOutOfRangeValidationContext implements ValidationContext
-    {
-        public void invalid(String message)
-        {
-            throw new XmlValueOutOfRangeException( message );
+    private static final class ValueOutOfRangeValidationContext implements ValidationContext {
+        public void invalid(String message) {
+            throw new XmlValueOutOfRangeException(message);
         }
 
-        public void invalid(String code, Object[] args)
-        {
-            throw new XmlValueOutOfRangeException( code, args );
+        public void invalid(String code, Object[] args) {
+            throw new XmlValueOutOfRangeException(code, args);
         }
     }
 
     /**
      * Used to supply validation context for the validate_value methods
      */
-    private static final class ImmutableValueValidationContext implements ValidationContext
-    {
-        private XmlObject _loc;
-        private Collection _coll;
-        ImmutableValueValidationContext(Collection coll, XmlObject loc)
-        {
+    private static final class ImmutableValueValidationContext implements ValidationContext {
+        private final XmlObject _loc;
+        private final Collection<XmlError> _coll;
+
+        ImmutableValueValidationContext(Collection<XmlError> coll, XmlObject loc) {
             _coll = coll;
             _loc = loc;
         }
-        public void invalid(String message)
-        {
-           _coll.add(XmlError.forObject(message, _loc));
+
+        public void invalid(String message) {
+            _coll.add(XmlError.forObject(message, _loc));
         }
-        public void invalid(String code, Object[] args)
-        {
+
+        public void invalid(String code, Object[] args) {
             _coll.add(XmlError.forObject(code, args, _loc));
         }
     }
 
     public static final ValidationContext _voorVc = new ValueOutOfRangeValidationContext();
 
-    public boolean validate()
-        { return validate(null); }
+    public boolean validate() {
+        return validate(null);
+    }
 
-    public boolean validate(XmlOptions options)
-    {
-        if ((_flags & FLAG_STORE) == 0)
-        {
-            if ((_flags & FLAG_IMMUTABLE) != 0)
-            {
+    public boolean validate(XmlOptions options) {
+        if ((_flags & FLAG_STORE) == 0) {
+            if ((_flags & FLAG_IMMUTABLE) != 0) {
                 return validate_immutable(options);
             }
 
             throw new IllegalStateException(
-                    "XML objects with no underlying store cannot be validated");
+                "XML objects with no underlying store cannot be validated");
         }
 
-        synchronized (monitor())
-        {
-            if ((_flags & FLAG_ORPHANED) != 0)
+        synchronized (monitor()) {
+            if ((_flags & FLAG_ORPHANED) != 0) {
                 throw new XmlValueDisconnectedException();
+            }
 
             SchemaField field = schemaField();
             SchemaType type = schemaType();
@@ -383,211 +422,195 @@
                 new Validator(
                     type, field, typeStore.get_schematypeloader(), options, null);
 
-            typeStore.validate( validator );
+            typeStore.validate(validator);
 
             return validator.isValid();
         }
     }
 
-    private boolean validate_immutable(XmlOptions options)
-    {
-        Collection errorListener = options == null ? null : (Collection)options.get(XmlOptions.ERROR_LISTENER);
+    private boolean validate_immutable(XmlOptions options) {
+        Collection<XmlError> errorListener = options == null ? null : options.getErrorListener();
         XmlErrorWatcher watcher = new XmlErrorWatcher(errorListener);
         if (!(schemaType().isSimpleType() || options != null &&
-                options.hasOption(XmlOptions.VALIDATE_TEXT_ONLY)))
-        {
+                                             options.isValidateTextOnly())) {
             // cannot have any required attributes or elements
             SchemaProperty[] properties = schemaType().getProperties();
-            for (int i = 0; i < properties.length; i++)
-            {
-                if (properties[i].getMinOccurs().signum() > 0)
-                {
+            for (SchemaProperty property : properties) {
+                if (property.getMinOccurs().signum() > 0) {
                     // KHK: error code?
-                    if (properties[i].isAttribute())
-                        watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE, new Object[]{QNameHelper.pretty(properties[i].getName()), }, this));
-                    else
-                        watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT, new Object[]{properties[i].getMinOccurs(), QNameHelper.pretty(properties[i].getName()), }, this));
+                    if (property.isAttribute()) {
+                        watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE, new Object[]{QNameHelper.pretty(property.getName()),}, this));
+                    } else {
+                        watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT, new Object[]{property.getMinOccurs(), QNameHelper.pretty(property.getName()),}, this));
+                    }
                 }
             }
 
-            if (schemaType().getContentType() != SchemaType.SIMPLE_CONTENT)
+            if (schemaType().getContentType() != SchemaType.SIMPLE_CONTENT) {
                 return !watcher.hasError(); // don't validate non-simple-content
+            }
         }
 
-        String text = (String)_textsource;
-        if (text == null)
+        String text = (String) _textsource;
+        if (text == null) {
             text = "";
+        }
         validate_simpleval(text, new ImmutableValueValidationContext(watcher, this));
         return !watcher.hasError();
     }
 
-    protected void validate_simpleval(String lexical, ValidationContext ctx)
-    {
-        return;
+    protected void validate_simpleval(String lexical, ValidationContext ctx) {
     }
 
-    private static XmlObject[] _typedArray(XmlObject[] input)
-    {
-        if (input.length == 0)
+    private static XmlObject[] _typedArray(XmlObject[] input) {
+        if (input.length == 0) {
             return input;
-        SchemaType commonType = input[0].schemaType();
-        if (commonType.equals(XmlObject.type) || commonType.isNoType())
-            return input;
-        for (int i = 1; i < input.length; i++)
-        {
-            if (input[i].schemaType().isNoType())
-                return input;
-            commonType = commonType.getCommonBaseType(input[i].schemaType());
-            if (commonType.equals(XmlObject.type))
-                return input;
         }
-        Class desiredClass = commonType.getJavaClass();
-        while (desiredClass == null)
-        {
-            commonType = commonType.getBaseType();
-            if (XmlObject.type.equals(commonType))
+        SchemaType commonType = input[0].schemaType();
+        if (commonType.equals(XmlObject.type) || commonType.isNoType()) {
+            return input;
+        }
+        for (int i = 1; i < input.length; i++) {
+            if (input[i].schemaType().isNoType()) {
                 return input;
+            }
+            commonType = commonType.getCommonBaseType(input[i].schemaType());
+            if (commonType.equals(XmlObject.type)) {
+                return input;
+            }
+        }
+        Class<?> desiredClass = commonType.getJavaClass();
+        while (desiredClass == null) {
+            commonType = commonType.getBaseType();
+            if (XmlObject.type.equals(commonType)) {
+                return input;
+            }
             desiredClass = commonType.getJavaClass();
         }
 
-        XmlObject[] result = (XmlObject[])Array.newInstance(desiredClass, input.length);
+        XmlObject[] result = (XmlObject[]) Array.newInstance(desiredClass, input.length);
         System.arraycopy(input, 0, result, 0, input.length);
         return result;
     }
 
-    public XmlObject[] selectPath ( String path )
-    {
-        return selectPath( path, null );
+    public XmlObject[] selectPath(String path) {
+        return selectPath(path, null);
     }
 
-    public XmlObject[] selectPath ( String path, XmlOptions options )
-    {
-        XmlObject [] selections;
+    public XmlObject[] selectPath(String path, XmlOptions options) {
+        XmlObject[] selections;
 
         // all user-level code; doesn't need to be synchronized
 
         XmlCursor c = newCursor();
 
-        if (c == null)
+        if (c == null) {
             throw new XmlValueDisconnectedException();
+        }
 
-        try
-        {
-            c.selectPath( path, options );
+        try {
+            c.selectPath(path, options);
 
-            if (!c.hasNextSelection())
+            if (!c.hasNextSelection()) {
                 selections = EMPTY_RESULT;
-            else
-            {
-                selections = new XmlObject [ c.getSelectionCount() ];
+            } else {
+                selections = new XmlObject[c.getSelectionCount()];
 
-                for (int i = 0 ; c.toNextSelection() ; i++)
-                {
-                    if ((selections[ i ] = c.getObject()) == null)
-                    {
-                        if ( !c.toParent() || (selections[ i ] = c.getObject()) == null )
-                        throw
-                            new XmlRuntimeException(
-                                "Path must select only elements " +
-                                    "and attributes" );
+                for (int i = 0; c.toNextSelection(); i++) {
+                    if ((selections[i] = c.getObject()) == null) {
+                        if (!c.toParent() || (selections[i] = c.getObject()) == null) {
+                            throw
+                                new XmlRuntimeException(
+                                    "Path must select only elements " +
+                                    "and attributes");
+                        }
                     }
                 }
             }
-        }
-        finally
-        {
+        } finally {
             c.dispose();
         }
 
-         return _typedArray(selections);
+        return _typedArray(selections);
     }
 
-    public XmlObject[] execQuery ( String path )
-    {
-        return execQuery( path, null );
+    public XmlObject[] execQuery(String path) {
+        return execQuery(path, null);
     }
 
-    public XmlObject[] execQuery ( String queryExpr, XmlOptions options )
-    {
-        synchronized (monitor())
-        {
+    public XmlObject[] execQuery(String queryExpr, XmlOptions options) {
+        synchronized (monitor()) {
             TypeStore typeStore = get_store();
 
-            if (typeStore == null)
-            {
+            if (typeStore == null) {
                 throw
                     new XmlRuntimeException(
-                        "Cannot do XQuery on XML Value Objects" );
+                        "Cannot do XQuery on XML Value Objects");
             }
 
-            try
-            {
-                return _typedArray(typeStore.exec_query( queryExpr, options ));
-            }
-            catch (XmlException e)
-            {
-                throw new XmlRuntimeException( e );
+            try {
+                return _typedArray(typeStore.exec_query(queryExpr, options));
+            } catch (XmlException e) {
+                throw new XmlRuntimeException(e);
             }
         }
     }
 
-    public XmlObject changeType(SchemaType type)
-    {
-        if (type == null)
-            throw new IllegalArgumentException( "Invalid type (null)" );
-
-        if ((_flags & FLAG_STORE) == 0)
-        {
-            throw
-                new IllegalStateException(
-                    "XML Value Objects cannot have thier type changed" );
+    public XmlObject changeType(SchemaType type) {
+        if (type == null) {
+            throw new IllegalArgumentException("Invalid type (null)");
         }
 
-        synchronized (monitor())
-        {
+        if ((_flags & FLAG_STORE) == 0) {
+            throw
+                new IllegalStateException(
+                    "XML Value Objects cannot have thier type changed");
+        }
+
+        synchronized (monitor()) {
             check_orphaned();
-            return (XmlObject) get_store().change_type( type );
+            return (XmlObject) get_store().change_type(type);
         }
     }
 
-    public XmlObject substitute(QName name, SchemaType type)
-    {
-        if (name == null)
-            throw new IllegalArgumentException( "Invalid name (null)" );
-
-        if (type == null)
-            throw new IllegalArgumentException( "Invalid type (null)" );
-
-        if ((_flags & FLAG_STORE) == 0)
-        {
-            throw
-                new IllegalStateException(
-                    "XML Value Objects cannot be used with substitution" );
+    public XmlObject substitute(QName name, SchemaType type) {
+        if (name == null) {
+            throw new IllegalArgumentException("Invalid name (null)");
         }
 
-        synchronized (monitor())
-        {
+        if (type == null) {
+            throw new IllegalArgumentException("Invalid type (null)");
+        }
+
+        if ((_flags & FLAG_STORE) == 0) {
+            throw
+                new IllegalStateException(
+                    "XML Value Objects cannot be used with substitution");
+        }
+
+        synchronized (monitor()) {
             check_orphaned();
-            return (XmlObject) get_store().substitute( name, type );
+            return (XmlObject) get_store().substitute(name, type);
         }
     }
 
     private int _flags;
     private Object _textsource;
 
-    protected XmlObjectBase()
-    {
+    protected XmlObjectBase() {
         _flags = FLAG_NILLABLE | FLAG_NIL;
     }
 
-    public void init_flags(SchemaProperty prop)
-    {
-        if (prop == null) return;
+    public void init_flags(SchemaProperty prop) {
+        if (prop == null) {
+            return;
+        }
 
         if (prop.hasDefault() == SchemaProperty.VARIABLE ||
             prop.hasFixed() == SchemaProperty.VARIABLE ||
-            prop.hasNillable() == SchemaProperty.VARIABLE)
+            prop.hasNillable() == SchemaProperty.VARIABLE) {
             return;
+        }
 
         _flags &= ~FLAGS_ELEMENT;
         _flags |=
@@ -597,81 +620,75 @@
             (FLAG_NOT_VARIABLE);
     }
 
-    {
-        assert TypeStore.NILLABLE   == 1;
-        assert TypeStore.HASDEFAULT == 2;
-        assert TypeStore.FIXED      == 4;
-    }
-
-    private static final int FLAG_NILLABLE        = TypeStore.NILLABLE;
-    private static final int FLAG_HASDEFAULT      = TypeStore.HASDEFAULT;
-    private static final int FLAG_FIXED           = TypeStore.FIXED;
-    private static final int FLAG_ATTRIBUTE       =     8;
-    private static final int FLAG_STORE           =    16;
-    private static final int FLAG_VALUE_DATED     =    32;
-    private static final int FLAG_NIL             =    64;
-    private static final int FLAG_NIL_DATED       =   128;
-    private static final int FLAG_ISDEFAULT       =   256;
-    private static final int FLAG_ELEMENT_DATED   =   512;
-    private static final int FLAG_SETTINGDEFAULT  =  1024;
-    private static final int FLAG_ORPHANED        =  2048;
-    private static final int FLAG_IMMUTABLE       =  4096;
-    private static final int FLAG_COMPLEXTYPE     =  8192;
-    private static final int FLAG_COMPLEXCONTENT  = 16384;
-    private static final int FLAG_NOT_VARIABLE    = 32768;
+    private static final int FLAG_NILLABLE = TypeStore.NILLABLE;
+    private static final int FLAG_HASDEFAULT = TypeStore.HASDEFAULT;
+    private static final int FLAG_FIXED = TypeStore.FIXED;
+    private static final int FLAG_ATTRIBUTE = 8;
+    private static final int FLAG_STORE = 16;
+    private static final int FLAG_VALUE_DATED = 32;
+    private static final int FLAG_NIL = 64;
+    private static final int FLAG_NIL_DATED = 128;
+    private static final int FLAG_ISDEFAULT = 256;
+    private static final int FLAG_ELEMENT_DATED = 512;
+    private static final int FLAG_SETTINGDEFAULT = 1024;
+    private static final int FLAG_ORPHANED = 2048;
+    private static final int FLAG_IMMUTABLE = 4096;
+    private static final int FLAG_COMPLEXTYPE = 8192;
+    private static final int FLAG_COMPLEXCONTENT = 16384;
+    private static final int FLAG_NOT_VARIABLE = 32768;
     private static final int FLAG_VALIDATE_ON_SET = 65536;
 
 
     /**
      * The three dated flags are always stacked:
-     *     FLAG_ELEMENT_DATED implies FLAG_NIL_DATED is set
-     *     FLAG_NIL_DATED implies FLAG_TEXT_DATED is set.
+     * FLAG_ELEMENT_DATED implies FLAG_NIL_DATED is set
+     * FLAG_NIL_DATED implies FLAG_TEXT_DATED is set.
      * checkers work on the flags from top to bottom.
      */
     private static final int FLAGS_DATED =
-            FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED;
+        FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED;
 
     /**
      * The three element status flags have one interrlationshiop:
-     *     FLAG_FIXED implies FLAG_HASDEFAULT is set.
+     * FLAG_FIXED implies FLAG_HASDEFAULT is set.
      * These flags are used when setting nils, defaults, strings.
      * Since an initial get implies setting from text, they're
      * also used during getting.
      */
     private static final int FLAGS_ELEMENT =
-            FLAG_NILLABLE | FLAG_FIXED | FLAG_HASDEFAULT;
+        FLAG_NILLABLE | FLAG_FIXED | FLAG_HASDEFAULT;
 
 
     /**
      * Called by restriction subclasses within their constructors to enable
      * complex type support.
      */
-    protected void initComplexType(boolean complexType, boolean complexContent)
-    {
+    protected void initComplexType(boolean complexType, boolean complexContent) {
         _flags |= (complexType ? FLAG_COMPLEXTYPE : 0) |
                   (complexContent ? FLAG_COMPLEXCONTENT : 0);
     }
 
-    protected boolean _isComplexType()
-        { return (_flags & FLAG_COMPLEXTYPE) != 0; }
+    protected boolean _isComplexType() {
+        return (_flags & FLAG_COMPLEXTYPE) != 0;
+    }
 
-    protected boolean _isComplexContent()
-        { return (_flags & FLAG_COMPLEXCONTENT) != 0; }
+    protected boolean _isComplexContent() {
+        return (_flags & FLAG_COMPLEXCONTENT) != 0;
+    }
 
     public void setValidateOnSet() {
         _flags |= FLAG_VALIDATE_ON_SET;
     }
 
-    protected boolean _validateOnSet()
-        { return (_flags & FLAG_VALIDATE_ON_SET) != 0; }
+    protected boolean _validateOnSet() {
+        return (_flags & FLAG_VALIDATE_ON_SET) != 0;
+    }
 
     /**
      * True if the value is nilled.
      */
-    public final boolean isNil()
-    {
-        synchronized (monitor())
-        {
+    public final boolean isNil() {
+        synchronized (monitor()) {
             check_dated();
             return ((_flags & FLAG_NIL) != 0);
         }
@@ -680,8 +697,7 @@
     /**
      * True if the value is fixed.
      */
-    public final boolean isFixed()
-    {
+    public final boolean isFixed() {
         check_element_dated();
         return ((_flags & FLAG_FIXED) != 0);
     }
@@ -689,8 +705,7 @@
     /**
      * True if the value is allowed to be nil.
      */
-    public final boolean isNillable()
-    {
+    public final boolean isNillable() {
         check_element_dated();
         return ((_flags & FLAG_NILLABLE) != 0);
     }
@@ -698,8 +713,7 @@
     /**
      * True if the value is currently defaulted.
      */
-    public final boolean isDefaultable()
-    {
+    public final boolean isDefaultable() {
         check_element_dated();
         return ((_flags & FLAG_HASDEFAULT) != 0);
     }
@@ -707,8 +721,7 @@
     /**
      * True if the value is currently defaulted.
      */
-    public final boolean isDefault()
-    {
+    public final boolean isDefault() {
         check_dated();
         return ((_flags & FLAG_ISDEFAULT) != 0);
     }
@@ -717,16 +730,15 @@
     /**
      * Nils the value.
      */
-    public final void setNil()
-    {
-        synchronized (monitor())
-        {
+    public final void setNil() {
+        synchronized (monitor()) {
             set_prepare();
 
             // if we're not nillable, throw exception on setNil(true)
             if ((_flags & FLAG_NILLABLE) == 0 &&
-                (_flags & FLAG_VALIDATE_ON_SET) != 0)
+                (_flags & FLAG_VALIDATE_ON_SET) != 0) {
                 throw new XmlValueNotNillableException();
+            }
 
             // the implementation should zero the value to reflect nil
             set_nil();
@@ -735,14 +747,11 @@
             _flags |= FLAG_NIL;
 
             // ordinary commit except no clearing of nil flag
-            if ((_flags & FLAG_STORE) != 0)
-            {
+            if ((_flags & FLAG_STORE) != 0) {
                 get_store().invalidate_text();
                 _flags &= ~FLAGS_DATED;
                 get_store().invalidate_nil();
-            }
-            else
-            {
+            } else {
                 _textsource = null;
             }
         }
@@ -753,8 +762,7 @@
      * chained values. (See XmlAnySimpleType (allSimpleValue), union
      * implementations).
      */
-    protected int elementFlags()
-    {
+    protected int elementFlags() {
         check_element_dated();
         return (_flags & FLAGS_ELEMENT);
     }
@@ -763,14 +771,14 @@
      * Used to make a free-standing xml simple value instance immutable.
      * This is a one-way street, and it is illegal to attempt to make a
      * value that is embedded in an xml document immutable.
-     *
+     * <p>
      * Once a value is marked as immutable, it is illegal to call setters
      * of any kind.
      */
-    public void setImmutable()
-    {
-        if ((_flags & (FLAG_IMMUTABLE | FLAG_STORE)) != 0)
+    public void setImmutable() {
+        if ((_flags & (FLAG_IMMUTABLE | FLAG_STORE)) != 0) {
             throw new IllegalStateException();
+        }
 
         _flags |= FLAG_IMMUTABLE;
     }
@@ -778,35 +786,34 @@
     /**
      * Is this instance an immutable value?
      */
-    public boolean isImmutable()
-    {
+    public boolean isImmutable() {
         return (_flags & FLAG_IMMUTABLE) != 0;
     }
 
 
-
-
     // TEXTUSER implementation
 
     /**
      * Called to initialize the TypeStore associated with this XmlObject
      * implementation. If not called, this is a free-floating value holder.
-     *
+     * <p>
      * When a value is first attached, it is put in a completely invalidated
      * state.
      */
-    public final void attach_store(TypeStore store)
-    {
+    public final void attach_store(TypeStore store) {
         _textsource = store;
-        if ((_flags & FLAG_IMMUTABLE) != 0)
+        if ((_flags & FLAG_IMMUTABLE) != 0) {
             throw new IllegalStateException();
+        }
         _flags |= FLAG_STORE | FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED;
 
-        if (store.is_attribute())
+        if (store.is_attribute()) {
             _flags |= FLAG_ATTRIBUTE;
+        }
 
-        if (store.validate_on_set())
+        if (store.validate_on_set()) {
             _flags |= FLAG_VALIDATE_ON_SET;
+        }
     }
 
     /**
@@ -814,14 +821,12 @@
      * invalidated and should be fetched next time the value is
      * needed.
      */
-    public final void invalidate_value()
-    {
-        assert((_flags & FLAG_STORE) != 0);
+    public final void invalidate_value() {
+        assert ((_flags & FLAG_STORE) != 0);
         _flags |= FLAG_VALUE_DATED;
     }
 
-    public final boolean uses_invalidate_value()
-    {
+    public final boolean uses_invalidate_value() {
         SchemaType type = schemaType();
         return type.isSimpleType() || type.getContentType() == SchemaType.SIMPLE_CONTENT;
     }
@@ -832,9 +837,8 @@
      * invalidated and both should be consulted next time the value
      * is needed.
      */
-    public final void invalidate_nilvalue()
-    {
-        assert((_flags & FLAG_STORE) != 0);
+    public final void invalidate_nilvalue() {
+        assert ((_flags & FLAG_STORE) != 0);
         _flags |= FLAG_VALUE_DATED | FLAG_NIL_DATED;
     }
 
@@ -845,9 +849,8 @@
      * text may have changed too); so the store should be consulted
      * next time any setter or getter is called.
      */
-    public final void invalidate_element_order()
-    {
-        assert((_flags & FLAG_STORE) != 0);
+    public final void invalidate_element_order() {
+        assert ((_flags & FLAG_STORE) != 0);
         _flags |= FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED;
     }
 
@@ -855,19 +858,16 @@
      * Used by the ComplexTypeImpl subclass to get direct access
      * to the store.
      */
-    public final TypeStore get_store()
-    {
-        assert((_flags & FLAG_STORE) != 0);
-        return (TypeStore)_textsource;
+    public final TypeStore get_store() {
+        assert ((_flags & FLAG_STORE) != 0);
+        return (TypeStore) _textsource;
     }
 
-    public final XmlLocale getXmlLocale ( )
-    {
+    public final XmlLocale getXmlLocale() {
         return get_store().get_locale();
     }
 
-    protected final boolean has_store()
-    {
+    protected final boolean has_store() {
         return (_flags & FLAG_STORE) != 0;
     }
 
@@ -876,24 +876,23 @@
      * text value from us. This is done after we have invalidated
      * the store (typically when our value has been set).
      */
-    public final String build_text(NamespaceManager nsm)
-    {
-        assert((_flags & FLAG_STORE) != 0);
-        assert((_flags & FLAG_VALUE_DATED) == 0);
-        if ((_flags & (FLAG_NIL | FLAG_ISDEFAULT)) != 0)
+    public final String build_text(NamespaceManager nsm) {
+        assert ((_flags & FLAG_STORE) != 0);
+        assert ((_flags & FLAG_VALUE_DATED) == 0);
+        if ((_flags & (FLAG_NIL | FLAG_ISDEFAULT)) != 0) {
             return "";
+        }
         return compute_text(
-                    nsm == null ? has_store() ? get_store() : null : nsm);
+            nsm == null ? has_store() ? get_store() : null : nsm);
     }
 
     /**
      * A store will call back on build_nil after we've called invalidate_nil
      * and it needs to know what the nil value is.
      */
-    public boolean build_nil()
-    {
-        assert((_flags & FLAG_STORE) != 0);
-        assert((_flags & FLAG_VALUE_DATED) == 0);
+    public boolean build_nil() {
+        assert ((_flags & FLAG_STORE) != 0);
+        assert ((_flags & FLAG_VALUE_DATED) == 0);
         return (_flags & FLAG_NIL) != 0;
     }
 
@@ -902,8 +901,7 @@
      * the text if we're in an invalid state. We're allowed to throw
      * an exception if the text isn't valid for our type.
      */
-    public void validate_now()
-    {
+    public void validate_now() {
         check_dated();
     }
 
@@ -912,12 +910,11 @@
      * After this is done, the object should be considered invalid.
      * Any attempt to access or set a value should result in an
      * exception.
-     *
+     * <p>
      * Note that this is how we handle deletions and xsi:type changes.
      */
-    public void disconnect_store()
-    {
-        assert((_flags & FLAG_STORE) != 0);
+    public void disconnect_store() {
+        assert ((_flags & FLAG_STORE) != 0);
         _flags |= FLAGS_DATED | FLAG_ORPHANED;
         // do NOT null out _textsource, because we need it non-null for synchronization
     }
@@ -926,19 +923,18 @@
      * A typestore user can create a new TypeStoreUser instance for
      * a given element child name as long as you also pass the
      * qname contained by the xsi:type attribute, if any.
-     *
+     * <p>
      * Note that we will ignore the xsiType if it turns out to be invalid.
-     *
+     * <p>
      * Returns null if there is no strongly typed information for that
      * given element (which implies, recusively, no strongly typed information
      * downwards).
      */
-    public TypeStoreUser create_element_user(QName eltName, QName xsiType)
-    {
+    public TypeStoreUser create_element_user(QName eltName, QName xsiType) {
         return
             (TypeStoreUser)
                 ((SchemaTypeImpl) schemaType()).createElementType(
-                    eltName, xsiType, get_store().get_schematypeloader() );
+                    eltName, xsiType, get_store().get_schematypeloader());
 
         /*
         SchemaTypeImpl stype = (SchemaTypeImpl)schemaType().getElementType(eltName, xsiType, get_store().get_schematypeloader());
@@ -951,49 +947,46 @@
     /**
      * A typestore user can create a new TypeStoreUser instance for
      * a given attribute child, based on the attribute name.
-     *
+     * <p>
      * Returns null if there is no strongly typed information for that
      * given attributes.
      */
-    public TypeStoreUser create_attribute_user(QName attrName)
-    {
-        return (TypeStoreUser)((SchemaTypeImpl)schemaType()).createAttributeType(attrName, get_store().get_schematypeloader());
+    public TypeStoreUser create_attribute_user(QName attrName) {
+        return (TypeStoreUser) ((SchemaTypeImpl) schemaType()).createAttributeType(attrName, get_store().get_schematypeloader());
     }
 
-    public SchemaType get_schema_type()
-    {
+    public SchemaType get_schema_type() {
         return schemaType();
     }
 
-    public SchemaType get_element_type(QName eltName, QName xsiType)
-    {
+    public SchemaType get_element_type(QName eltName, QName xsiType) {
         return schemaType().getElementType(
-            eltName, xsiType, get_store().get_schematypeloader() );
+            eltName, xsiType, get_store().get_schematypeloader());
     }
 
-    public SchemaType get_attribute_type(QName attrName)
-    {
+    public SchemaType get_attribute_type(QName attrName) {
         return schemaType().getAttributeType(
-            attrName, get_store().get_schematypeloader() );
+            attrName, get_store().get_schematypeloader());
     }
 
     /**
      * Returns the default element text, if it's consistent. If it's
      * not consistent, returns null, and requires a visitor walk.
-     *
+     * <p>
      * Also returns null if there is no default at all (although
      * that can also be discovered via get_elementflags without
      * doing a walk).
      */
-    public String get_default_element_text(QName eltName)
-    {
-        assert(_isComplexContent());
-        if (!_isComplexContent())
+    public String get_default_element_text(QName eltName) {
+        assert (_isComplexContent());
+        if (!_isComplexContent()) {
             throw new IllegalStateException();
+        }
 
         SchemaProperty prop = schemaType().getElementProperty(eltName);
-        if (prop == null)
+        if (prop == null) {
             return "";
+        }
         return prop.getDefaultText();
     }
 
@@ -1001,15 +994,16 @@
      * Returns the default attribute text for the attribute with
      * the given name, or null if no default.
      */
-    public String get_default_attribute_text(QName attrName)
-    {
-        assert(_isComplexType());
-        if (!_isComplexType())
+    public String get_default_attribute_text(QName attrName) {
+        assert (_isComplexType());
+        if (!_isComplexType()) {
             throw new IllegalStateException();
+        }
 
         SchemaProperty prop = schemaType().getAttributeProperty(attrName);
-        if (prop == null)
+        if (prop == null) {
             return "";
+        }
         return prop.getDefaultText();
     }
 
@@ -1017,18 +1011,20 @@
      * Returns the elementflags, if they're consistent. If they're
      * not, returns -1, and requires a vistor walk.
      */
-    public int get_elementflags(QName eltName)
-    {
-        if (!_isComplexContent())
+    public int get_elementflags(QName eltName) {
+        if (!_isComplexContent()) {
             return 0;
+        }
 
         SchemaProperty prop = schemaType().getElementProperty(eltName);
-        if (prop == null)
+        if (prop == null) {
             return 0;
+        }
         if (prop.hasDefault() == SchemaProperty.VARIABLE ||
             prop.hasFixed() == SchemaProperty.VARIABLE ||
-            prop.hasNillable() == SchemaProperty.VARIABLE)
+            prop.hasNillable() == SchemaProperty.VARIABLE) {
             return -1;
+        }
         return
             (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) |
             (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED) |
@@ -1038,13 +1034,14 @@
     /**
      * Returns the flags for the given attribute.
      */
-    public int get_attributeflags(QName attrName)
-    {
-        if (!_isComplexType())
+    public int get_attributeflags(QName attrName) {
+        if (!_isComplexType()) {
             return 0;
+        }
         SchemaProperty prop = schemaType().getAttributeProperty(attrName);
-        if (prop == null)
+        if (prop == null) {
             return 0;
+        }
         return
             (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) |
             (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED);
@@ -1056,10 +1053,10 @@
      * if it returns true, you're required to call invalidate_element_order
      * on children to the right of any child order rearrangement.
      */
-    public boolean is_child_element_order_sensitive()
-    {
-        if (!_isComplexType())
+    public boolean is_child_element_order_sensitive() {
+        if (!_isComplexType()) {
             return false;
+        }
         return schemaType().isOrderSensitive();
     }
 
@@ -1067,23 +1064,23 @@
      * Inserting a new element is always unambiguous except in one
      * situation: when adding an element after the last one with
      * that name (or the first one if there are none).
-     *
+     * <p>
      * In that case, add the element at the first possible slot
      * BEFORE any element whose qname is contained in the QNameSet
      * given. (If the QNameSet is empty, that means add the new
      * element at the very end.)
-     *
+     * <p>
      * If the returned QNameSet is null, treat it as if the QNameSet
      * contained all QNames, i.e., add the new element at the very
      * first position possible (adjacent to the last element of the
      * same name, or at the very first slot if it is the first elt
      * with that name).
      */
-    public final QNameSet get_element_ending_delimiters(QName eltname)
-    {
+    public final QNameSet get_element_ending_delimiters(QName eltname) {
         SchemaProperty prop = schemaType().getElementProperty(eltname);
-        if (prop == null)
+        if (prop == null) {
             return null;
+        }
         return prop.getJavaSetterDelimiter();
     }
 
@@ -1091,18 +1088,18 @@
      * A typestore user can return a visitor that is used to compute
      * default text and elementflags for an arbitrary element.
      */
-    public TypeStoreVisitor new_visitor()
-    {
-        if (!_isComplexContent())
+    public TypeStoreVisitor new_visitor() {
+        if (!_isComplexContent()) {
             return null;
+        }
         return new SchemaTypeVisitorImpl(schemaType().getContentModel());
     }
 
-    public SchemaField get_attribute_field(QName attrName)
-    {
+    public SchemaField get_attribute_field(QName attrName) {
         SchemaAttributeModel model = schemaType().getAttributeModel();
-        if (model == null)
+        if (model == null) {
             return null;
+        }
         return model.getAttribute(attrName);
     }
 
@@ -1113,10 +1110,10 @@
      * string in the underlying store after checking it
      * against the primitive type for validity.
      */
-    protected void set_String(String v)
-    {
-        if ((_flags & FLAG_IMMUTABLE) != 0)
+    protected void set_String(String v) {
+        if ((_flags & FLAG_IMMUTABLE) != 0) {
             throw new IllegalStateException();
+        }
 
         boolean wasNilled = ((_flags & FLAG_NIL) != 0);
 
@@ -1125,23 +1122,23 @@
         update_from_wscanon_text(wscanon);
 
         // Now store the literal text immediately in the underlying
-        if ((_flags & FLAG_STORE) != 0)
-        {
+        if ((_flags & FLAG_STORE) != 0) {
             _flags &= ~FLAG_VALUE_DATED;
-            if ((_flags & FLAG_SETTINGDEFAULT) == 0)
+            if ((_flags & FLAG_SETTINGDEFAULT) == 0) {
                 get_store().store_text(v);
-            if (wasNilled)
+            }
+            if (wasNilled) {
                 get_store().invalidate_nil();
-        }
-        else
+            }
+        } else {
             _textsource = v;
+        }
     }
 
     /**
      * Update the value based on complex content.
      */
-    protected void update_from_complex_content()
-    {
+    protected void update_from_complex_content() {
         throw new XmlValueNotSupportedException("Complex content");
     }
 
@@ -1152,23 +1149,24 @@
      * that must be applied, and where the value must match
      * a fixed value.
      */
-    private final void update_from_wscanon_text(String v)
-    {
+    private void update_from_wscanon_text(String v) {
         // Whitespace is default if this type treats this space as defaultable
-        if ((_flags & FLAG_HASDEFAULT) != 0 &&  (_flags & FLAG_SETTINGDEFAULT) == 0)
-        {
+        if ((_flags & FLAG_HASDEFAULT) != 0 && (_flags & FLAG_SETTINGDEFAULT) == 0) {
             // This isn't quite correct since the .equals("") test should be
             // done on the actual text, not the wscanon text
-            if ((_flags & FLAG_ATTRIBUTE) == 0 && v.equals(""))
-            {
+            if ((_flags & FLAG_ATTRIBUTE) == 0 && v.equals("")) {
                 String def = get_store().compute_default_text();
-                if (def == null)
+                if (def == null) {
                     throw new XmlValueOutOfRangeException();
+                }
 
                 // protect against recursion with this flag
                 _flags |= FLAG_SETTINGDEFAULT;
-                try { this.setStringValue(def); }
-                finally { _flags &= ~FLAG_SETTINGDEFAULT; }
+                try {
+                    this.setStringValue(def);
+                } finally {
+                    _flags &= ~FLAG_SETTINGDEFAULT;
+                }
                 _flags &= ~FLAG_NIL;
                 _flags |= FLAG_ISDEFAULT;
                 return;
@@ -1185,35 +1183,32 @@
      * Types should return false if they don't treat the given
      * whitespace as a default value.
      */
-    protected boolean is_defaultable_ws(String v)
-    {
+    protected boolean is_defaultable_ws(String v) {
         return true;
     }
 
     /**
      * Returns the whitespace rule that will be applied before
      * building a string to pass to get_text().
-     *
+     * <p>
      * Overridden by subclasses that don't need their text
      * for set_text canonicalized; perhaps they already implement
      * scanners that can deal with whitespace, and they know
      * they have no regex pattern restrictions.
      */
-    protected int get_wscanon_rule()
-    {
+    protected int get_wscanon_rule() {
         return SchemaType.WS_COLLAPSE;
     }
 
     /**
      * Called to canonicalize whitespace before calling set_text.
-     *
+     * <p>
      * Tries to avoid allocation when the string is already canonical, but
      * otherwise this is not particularly efficient. Hopefully the common
      * case is that we pass our wscanon rule to the store via fetch_text
      * and it's canonicalized before we even see it as a string.
      */
-    private final String apply_wscanon(String v)
-    {
+    private String apply_wscanon(String v) {
         return XmlWhitespace.collapse(v, get_wscanon_rule());
     }
 
@@ -1222,28 +1217,27 @@
      * a correct picture of whether we're nillable, fixed, or
      * if we have a default that can be applied.
      */
-    private final void check_element_dated()
-    {
+    private void check_element_dated() {
         if ((_flags & FLAG_ELEMENT_DATED) != 0 &&
-            (_flags & FLAG_NOT_VARIABLE) == 0)
-        {
-            if ((_flags & FLAG_ORPHANED) != 0)
+            (_flags & FLAG_NOT_VARIABLE) == 0) {
+            if ((_flags & FLAG_ORPHANED) != 0) {
                 throw new XmlValueDisconnectedException();
+            }
 
             int eltflags = get_store().compute_flags();
             // int eltflags = 0;
             _flags &= ~(FLAGS_ELEMENT | FLAG_ELEMENT_DATED);
             _flags |= eltflags;
         }
-        if ((_flags & FLAG_NOT_VARIABLE) != 0)
+        if ((_flags & FLAG_NOT_VARIABLE) != 0) {
             _flags &= ~(FLAG_ELEMENT_DATED);
+        }
     }
 
     /**
      * Describes the orphaned status of this object.
      */
-    protected final boolean is_orphaned()
-    {
+    protected final boolean is_orphaned() {
         return (_flags & FLAG_ORPHANED) != 0;
     }
 
@@ -1252,10 +1246,10 @@
      * typed classes to ensure that the object has not been
      * orphaned.
      */
-    protected final void check_orphaned()
-    {
-        if (is_orphaned())
+    protected final void check_orphaned() {
+        if (is_orphaned()) {
             throw new XmlValueDisconnectedException();
+        }
     }
 
     /**
@@ -1263,22 +1257,20 @@
      * that the value being read is valid. If the value
      * has been invalidated, it is re-read from the underlying
      * text store, and this may cause an out of range exception.
-     *
+     * <p>
      * This method deals with nils, nillability, defaults, etc.
      */
-    public final void check_dated()
-    {
-        if ((_flags & FLAGS_DATED) != 0)
-        {
-            if ((_flags & FLAG_ORPHANED) != 0)
+    public final void check_dated() {
+        if ((_flags & FLAGS_DATED) != 0) {
+            if ((_flags & FLAG_ORPHANED) != 0) {
                 throw new XmlValueDisconnectedException();
+            }
 
-            assert((_flags & FLAG_STORE) != 0);
+            assert ((_flags & FLAG_STORE) != 0);
 
             check_element_dated();
 
-            if ((_flags & FLAG_ELEMENT_DATED) != 0)
-            {
+            if ((_flags & FLAG_ELEMENT_DATED) != 0) {
                 int eltflags = get_store().compute_flags();
                 _flags &= ~(FLAGS_ELEMENT | FLAG_ELEMENT_DATED);
                 _flags |= eltflags;
@@ -1286,38 +1278,36 @@
 
             boolean nilled = false;
 
-            if ((_flags & FLAG_NIL_DATED) != 0)
-            {
-                if (get_store().find_nil())
-                {
+            if ((_flags & FLAG_NIL_DATED) != 0) {
+                if (get_store().find_nil()) {
                     if ((_flags & FLAG_NILLABLE) == 0 &&
-                        (_flags & FLAG_VALIDATE_ON_SET) != 0)
+                        (_flags & FLAG_VALIDATE_ON_SET) != 0) {
                         throw new XmlValueOutOfRangeException(); // nil not allowed
+                    }
 
                     // let the implementation know that we're nil now
                     set_nil();
 
                     _flags |= FLAG_NIL;
                     nilled = true;
-                }
-                else
-                {
+                } else {
                     _flags &= ~FLAG_NIL;
                 }
                 _flags &= ~FLAG_NIL_DATED;
             }
 
-            if (!nilled)
-            {
+            if (!nilled) {
                 String text;
 
-                if ((_flags & FLAG_COMPLEXCONTENT) != 0 || (text = get_wscanon_text()) == null)
+                if ((_flags & FLAG_COMPLEXCONTENT) != 0 || (text = get_wscanon_text()) == null) {
                     update_from_complex_content();
-                else
-                {
+                } else {
                     NamespaceContext.push(new NamespaceContext(get_store()));
-                    try { update_from_wscanon_text(text); }
-                    finally { NamespaceContext.pop(); }
+                    try {
+                        update_from_wscanon_text(text);
+                    } finally {
+                        NamespaceContext.pop();
+                    }
                 }
             }
 
@@ -1331,11 +1321,11 @@
      * (1) get the nillable, fixed, etc flags
      * (2) throw an exception if it's fixed (not for strings)
      */
-    private final void set_prepare()
-    {
+    private void set_prepare() {
         check_element_dated();
-        if ((_flags & FLAG_IMMUTABLE) != 0)
+        if ((_flags & FLAG_IMMUTABLE) != 0) {
             throw new IllegalStateException();
+        }
     }
 
     /**
@@ -1345,20 +1335,17 @@
      * latest set beats the previous invalidate. Also,
      * if we were nil, we're no longer.
      */
-    private final void set_commit()
-    {
+    private void set_commit() {
         boolean wasNilled = ((_flags & FLAG_NIL) != 0);
-          _flags &= ~(FLAG_NIL | FLAG_ISDEFAULT);
+        _flags &= ~(FLAG_NIL | FLAG_ISDEFAULT);
 
-        if ((_flags & FLAG_STORE) != 0)
-        {
+        if ((_flags & FLAG_STORE) != 0) {
             _flags &= ~(FLAGS_DATED);
             get_store().invalidate_text();
-            if (wasNilled)
+            if (wasNilled) {
                 get_store().invalidate_nil();
-        }
-        else
-        {
+            }
+        } else {
             _textsource = null;
         }
     }
@@ -1368,13 +1355,12 @@
      * implementation's wscanon rule.
      * Null if not simple content.
      */
-    public final String get_wscanon_text()
-    {
-        if ((_flags & FLAG_STORE) == 0)
-        {
-            return apply_wscanon((String)_textsource);
+    public final String get_wscanon_text() {
+        if ((_flags & FLAG_STORE) == 0) {
+            return apply_wscanon((String) _textsource);
+        } else {
+            return get_store().fetch_text(get_wscanon_rule());
         }
-        else return get_store().fetch_text(get_wscanon_rule());
     }
 
     /**
@@ -1398,63 +1384,87 @@
     // SIMPLE VALUE ACCESSORS BELOW -------------------------------------------
 
     // numerics: fractional
-    public float getFloatValue()
-        { BigDecimal bd = getBigDecimalValue(); return bd == null ? 0.0f : bd.floatValue(); }
-    public double getDoubleValue()
-        { BigDecimal bd = getBigDecimalValue(); return bd == null ? 0.0 : bd.doubleValue(); }
-    public BigDecimal getBigDecimalValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-                new Object[] {getPrimitiveTypeName(), "numeric"}); }
+    public float getFloatValue() {
+        BigDecimal bd = getBigDecimalValue();
+        return bd == null ? 0.0f : bd.floatValue();
+    }
+
+    public double getDoubleValue() {
+        BigDecimal bd = getBigDecimalValue();
+        return bd == null ? 0.0 : bd.doubleValue();
+    }
+
+    public BigDecimal getBigDecimalValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "numeric"});
+    }
 
     // numerics: integral
-    public BigInteger getBigIntegerValue()
-        { BigDecimal bd = bigDecimalValue(); return bd == null ? null : bd.toBigInteger(); }
-
-    public byte getByteValue()
-    {
-        long l = getIntValue();
-        if (l > Byte.MAX_VALUE) throw new XmlValueOutOfRangeException();
-        if (l < Byte.MIN_VALUE) throw new XmlValueOutOfRangeException();
-        return (byte)l;
+    public BigInteger getBigIntegerValue() {
+        BigDecimal bd = bigDecimalValue();
+        return bd == null ? null : bd.toBigInteger();
     }
 
-    public short getShortValue()
-    {
+    public byte getByteValue() {
         long l = getIntValue();
-        if (l > Short.MAX_VALUE) throw new XmlValueOutOfRangeException();
-        if (l < Short.MIN_VALUE) throw new XmlValueOutOfRangeException();
-        return (short)l;
+        if (l > Byte.MAX_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        if (l < Byte.MIN_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        return (byte) l;
     }
 
-    public int getIntValue()
-    {
+    public short getShortValue() {
+        long l = getIntValue();
+        if (l > Short.MAX_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        if (l < Short.MIN_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        return (short) l;
+    }
+
+    public int getIntValue() {
         long l = getLongValue();
-        if (l > Integer.MAX_VALUE) throw new XmlValueOutOfRangeException();
-        if (l < Integer.MIN_VALUE) throw new XmlValueOutOfRangeException();
-        return (int)l;
+        if (l > Integer.MAX_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        if (l < Integer.MIN_VALUE) {
+            throw new XmlValueOutOfRangeException();
+        }
+        return (int) l;
     }
+
     private static final BigInteger _max = BigInteger.valueOf(Long.MAX_VALUE);
     private static final BigInteger _min = BigInteger.valueOf(Long.MIN_VALUE);
 
-    public long getLongValue()
-    {
+    public long getLongValue() {
         BigInteger b = getBigIntegerValue();
-        if (b == null) return 0L;
-        if (b.compareTo(_max) >= 0) throw new XmlValueOutOfRangeException();
-        if (b.compareTo(_min) <= 0) throw new XmlValueOutOfRangeException();
+        if (b == null) {
+            return 0L;
+        }
+        if (b.compareTo(_max) >= 0) {
+            throw new XmlValueOutOfRangeException();
+        }
+        if (b.compareTo(_min) <= 0) {
+            throw new XmlValueOutOfRangeException();
+        }
         return b.longValue();
     }
 
     private static final XmlOptions _toStringOptions =
         buildInnerPrettyOptions();
 
-    static final XmlOptions buildInnerPrettyOptions()
-    {
+    static XmlOptions buildInnerPrettyOptions() {
         XmlOptions options = new XmlOptions();
-        options.put( XmlOptions.SAVE_INNER );
-        options.put( XmlOptions.SAVE_PRETTY_PRINT );
-        options.put( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES );
-        options.put( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE );
+        options.setSaveInner();
+        options.setSavePrettyPrint();
+        options.setSaveAggressiveNamespaces();
+        options.setUseDefaultNamespace();
+
         return options;
     }
 
@@ -1478,436 +1488,748 @@
     }
     */
 
-    public final String toString( )
-    {
-        synchronized (monitor())
-        {
+    public final String toString() {
+        synchronized (monitor()) {
             return ensureStore().xmlText(_toStringOptions);
         }
     }
 
-    public String xmlText()
-    {
+    public String xmlText() {
         return xmlText(null);
     }
 
-    public String xmlText (XmlOptions options)
-    {
+    public String xmlText(XmlOptions options) {
         XmlCursor cur = newCursorForce();
 
-        try
-        {
+        try {
             return cur.xmlText(makeInnerOptions(options));
-        }
-        finally
-        {
+        } finally {
             cur.dispose();
         }
     }
 
     // enums
-    public StringEnumAbstractBase getEnumValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-                new Object[] {getPrimitiveTypeName(), "enum"}); }
+    public StringEnumAbstractBase getEnumValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "enum"});
+    }
 
     // various
-    public String getStringValue()
-    {
-        if (isImmutable())
-        {
-            if ((_flags & FLAG_NIL) != 0)
+    public String getStringValue() {
+        if (isImmutable()) {
+            if ((_flags & FLAG_NIL) != 0) {
                 return null;
+            }
             return compute_text(null);
         }
         // Since complex-content types don't have a "natural" string value, we
         // emit the deeply concatenated, tag-removed content of the tag.
-        synchronized (monitor())
-        {
-            if (_isComplexContent())
+        synchronized (monitor()) {
+            if (_isComplexContent()) {
                 return get_store().fetch_text(TypeStore.WS_PRESERVE);
+            }
 
             check_dated();
-            if ((_flags & FLAG_NIL) != 0)
+            if ((_flags & FLAG_NIL) != 0) {
                 return null;
+            }
             return compute_text(has_store() ? get_store() : null);
         }
     }
 
-    /** @deprecated replaced with {@link #getStringValue} */
-    public String stringValue()
-        { return getStringValue(); }
-    /** @deprecated replaced with {@link #getBooleanValue} */
-    public boolean booleanValue()
-        { return getBooleanValue(); }
-    /** @deprecated replaced with {@link #getByteValue} */
-    public byte byteValue()
-        { return getByteValue(); }
-    /** @deprecated replaced with {@link #getShortValue} */
-    public short shortValue()
-        { return getShortValue(); }
-    /** @deprecated replaced with {@link #getIntValue} */
-    public int intValue()
-        { return getIntValue(); }
-    /** @deprecated replaced with {@link #getLongValue} */
-    public long longValue()
-        { return getLongValue(); }
-    /** @deprecated replaced with {@link #getBigIntegerValue} */
-    public BigInteger bigIntegerValue()
-        { return getBigIntegerValue(); }
-    /** @deprecated replaced with {@link #getBigDecimalValue} */
-    public BigDecimal bigDecimalValue()
-        { return getBigDecimalValue(); }
-    /** @deprecated replaced with {@link #getFloatValue} */
-    public float floatValue()
-        { return getFloatValue(); }
-    /** @deprecated replaced with {@link #getDoubleValue} */
-    public double doubleValue()
-        { return getDoubleValue(); }
-    /** @deprecated replaced with {@link #getByteArrayValue} */
-    public byte[] byteArrayValue()
-        { return getByteArrayValue(); }
-    /** @deprecated replaced with {@link #getEnumValue} */
-    public StringEnumAbstractBase enumValue()
-        { return getEnumValue(); }
-    /** @deprecated replaced with {@link #getCalendarValue} */
-    public Calendar calendarValue()
-        { return getCalendarValue(); }
-    /** @deprecated replaced with {@link #getDateValue} */
-    public Date dateValue()
-        { return getDateValue(); }
-    /** @deprecated replaced with {@link #getGDateValue} */
-    public GDate gDateValue()
-        { return getGDateValue(); }
-    /** @deprecated replaced with {@link #getGDurationValue} */
-    public GDuration gDurationValue()
-        { return getGDurationValue(); }
-    /** @deprecated replaced with {@link #getQNameValue} */
-    public QName qNameValue()
-        { return getQNameValue(); }
-    /** @deprecated replaced with {@link #xgetListValue} */
-    public List xlistValue()
-        { return xgetListValue(); }
-    /** @deprecated replaced with {@link #getListValue} */
-    public List listValue()
-        { return getListValue(); }
-    /** @deprecated replaced with {@link #getObjectValue} */
-    public Object objectValue()
-        { return getObjectValue(); }
+    /**
+     * @deprecated replaced with {@link #getStringValue}
+     */
+    public String stringValue() {
+        return getStringValue();
+    }
 
-    /** @deprecated replaced with {@link #setStringValue} */
-    public void set(String obj)
-        { setStringValue(obj); }
-    /** @deprecated replaced with {@link #setBooleanValue} */
-    public void set(boolean v)
-        { setBooleanValue(v); }
-    /** @deprecated replaced with {@link #setByteValue} */
-    public void set(byte v)
-        { setByteValue(v); }
-    /** @deprecated replaced with {@link #setShortValue} */
-    public void set(short v)
-        { setShortValue(v); }
-    /** @deprecated replaced with {@link #setIntValue} */
-    public void set(int v)
-        { setIntValue(v); }
-    /** @deprecated replaced with {@link #setLongValue} */
-    public void set(long v)
-        { setLongValue(v); }
-    /** @deprecated replaced with {@link #setBigIntegerValue} */
-    public void set(BigInteger obj)
-        { setBigIntegerValue(obj); }
-    /** @deprecated replaced with {@link #setBigDecimalValue} */
-    public void set(BigDecimal obj)
-        { setBigDecimalValue(obj); }
-    /** @deprecated replaced with {@link #setFloatValue} */
-    public void set(float v)
-        { setFloatValue(v); }
-    /** @deprecated replaced with {@link #setDoubleValue} */
-    public void set(double v)
-        { setDoubleValue(v); }
-    /** @deprecated replaced with {@link #setByteArrayValue} */
-    public void set(byte[] obj)
-        { setByteArrayValue(obj); }
-    /** @deprecated replaced with {@link #setEnumValue} */
-    public void set(StringEnumAbstractBase obj)
-        { setEnumValue(obj); }
-    /** @deprecated replaced with {@link #setCalendarValue} */
-    public void set(Calendar obj)
-        { setCalendarValue(obj); }
-    /** @deprecated replaced with {@link #setDateValue} */
-    public void set(Date obj)
-        { setDateValue(obj); }
-    /** @deprecated replaced with {@link #setGDateValue} */
-    public void set(GDateSpecification obj)
-        { setGDateValue(obj); }
-    /** @deprecated replaced with {@link #setGDurationValue} */
-    public void set(GDurationSpecification obj)
-        { setGDurationValue(obj); }
-    /** @deprecated replaced with {@link #setQNameValue} */
-    public void set(QName obj)
-        { setQNameValue(obj); }
-    /** @deprecated replaced with {@link #setListValue} */
-    public void set(List obj)
-        { setListValue(obj); }
-    /** @deprecated replaced with {@link #setObjectValue} */
-    public void objectSet(Object obj)
-        { setObjectValue(obj); }
+    /**
+     * @deprecated replaced with {@link #getBooleanValue}
+     */
+    public boolean booleanValue() {
+        return getBooleanValue();
+    }
 
-    public byte[] getByteArrayValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "byte[]"}); }
-    public boolean getBooleanValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "boolean"}); }
-    public GDate getGDateValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "Date"}); }
-    public Date getDateValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "Date"}); }
-    public Calendar getCalendarValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "Calendar"}); }
-    public GDuration getGDurationValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "Duration"}); }
-    public QName getQNameValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "QName"}); }
-    public List getListValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "List"}); }
-    public List xgetListValue()
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
-            new Object[] {getPrimitiveTypeName(), "List"}); }
-    public Object getObjectValue()
-        { return java_value(this); }
+    /**
+     * @deprecated replaced with {@link #getByteValue}
+     */
+    public byte byteValue() {
+        return getByteValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getShortValue}
+     */
+    public short shortValue() {
+        return getShortValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getIntValue}
+     */
+    public int intValue() {
+        return getIntValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getLongValue}
+     */
+    public long longValue() {
+        return getLongValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getBigIntegerValue}
+     */
+    public BigInteger bigIntegerValue() {
+        return getBigIntegerValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getBigDecimalValue}
+     */
+    public BigDecimal bigDecimalValue() {
+        return getBigDecimalValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getFloatValue}
+     */
+    public float floatValue() {
+        return getFloatValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getDoubleValue}
+     */
+    public double doubleValue() {
+        return getDoubleValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getByteArrayValue}
+     */
+    public byte[] byteArrayValue() {
+        return getByteArrayValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getEnumValue}
+     */
+    public StringEnumAbstractBase enumValue() {
+        return getEnumValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getCalendarValue}
+     */
+    public Calendar calendarValue() {
+        return getCalendarValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getDateValue}
+     */
+    public Date dateValue() {
+        return getDateValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getGDateValue}
+     */
+    public GDate gDateValue() {
+        return getGDateValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getGDurationValue}
+     */
+    public GDuration gDurationValue() {
+        return getGDurationValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getQNameValue}
+     */
+    public QName qNameValue() {
+        return getQNameValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #xgetListValue}
+     */
+    public List xlistValue() {
+        return xgetListValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getListValue}
+     */
+    public List listValue() {
+        return getListValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #getObjectValue}
+     */
+    public Object objectValue() {
+        return getObjectValue();
+    }
+
+    /**
+     * @deprecated replaced with {@link #setStringValue}
+     */
+    public void set(String obj) {
+        setStringValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setBooleanValue}
+     */
+    public void set(boolean v) {
+        setBooleanValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setByteValue}
+     */
+    public void set(byte v) {
+        setByteValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setShortValue}
+     */
+    public void set(short v) {
+        setShortValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setIntValue}
+     */
+    public void set(int v) {
+        setIntValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setLongValue}
+     */
+    public void set(long v) {
+        setLongValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setBigIntegerValue}
+     */
+    public void set(BigInteger obj) {
+        setBigIntegerValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setBigDecimalValue}
+     */
+    public void set(BigDecimal obj) {
+        setBigDecimalValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setFloatValue}
+     */
+    public void set(float v) {
+        setFloatValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setDoubleValue}
+     */
+    public void set(double v) {
+        setDoubleValue(v);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setByteArrayValue}
+     */
+    public void set(byte[] obj) {
+        setByteArrayValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setEnumValue}
+     */
+    public void set(StringEnumAbstractBase obj) {
+        setEnumValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setCalendarValue}
+     */
+    public void set(Calendar obj) {
+        setCalendarValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setDateValue}
+     */
+    public void set(Date obj) {
+        setDateValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setGDateValue}
+     */
+    public void set(GDateSpecification obj) {
+        setGDateValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setGDurationValue}
+     */
+    public void set(GDurationSpecification obj) {
+        setGDurationValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setQNameValue}
+     */
+    public void set(QName obj) {
+        setQNameValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setListValue}
+     */
+    public void set(List obj) {
+        setListValue(obj);
+    }
+
+    /**
+     * @deprecated replaced with {@link #setObjectValue}
+     */
+    public void objectSet(Object obj) {
+        setObjectValue(obj);
+    }
+
+    public byte[] getByteArrayValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "byte[]"});
+    }
+
+    public boolean getBooleanValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "boolean"});
+    }
+
+    public GDate getGDateValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "Date"});
+    }
+
+    public Date getDateValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "Date"});
+    }
+
+    public Calendar getCalendarValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "Calendar"});
+    }
+
+    public GDuration getGDurationValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "Duration"});
+    }
+
+    public QName getQNameValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "QName"});
+    }
+
+    public List getListValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "List"});
+    }
+
+    public List xgetListValue() {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J,
+            new Object[]{getPrimitiveTypeName(), "List"});
+    }
+
+    public Object getObjectValue() {
+        return java_value(this);
+    }
 
     // set this value
-    public final void setBooleanValue(boolean v)
-        { synchronized (monitor()) { set_prepare(); set_boolean(v); set_commit(); } }
-    public final void setByteValue(byte v)
-        { synchronized (monitor()) { set_prepare(); set_byte(v); set_commit(); } }
-    public final void setShortValue(short v)
-        { synchronized (monitor()) { set_prepare(); set_short(v); set_commit(); } }
-    public final void setIntValue(int v)
-        { synchronized (monitor()) { set_prepare(); set_int(v); set_commit(); } }
-    public final void setLongValue(long v)
-        { synchronized (monitor()) { set_prepare(); set_long(v); set_commit(); } }
-    public final void setFloatValue(float v)
-        { synchronized (monitor()) { set_prepare(); set_float(v); set_commit(); } }
-    public final void setDoubleValue(double v)
-        { synchronized (monitor()) { set_prepare(); set_double(v); set_commit(); } }
-    public final void setByteArrayValue(byte[] obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_ByteArray(obj); set_commit(); } } }
-    public final void setEnumValue(StringEnumAbstractBase obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_enum(obj); set_commit(); } } }
-    public final void setBigIntegerValue(BigInteger obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_BigInteger(obj); set_commit(); } } }
-    public final void setBigDecimalValue(BigDecimal obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_BigDecimal(obj); set_commit(); } } }
-    public final void setCalendarValue(Calendar obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_Calendar(obj); set_commit(); } } }
-    public final void setDateValue(Date obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_Date(obj); set_commit(); } } }
-    public final void setGDateValue(GDate obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDate(obj); set_commit(); } } }
-    public final void setGDateValue(GDateSpecification obj)
-    { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDate(obj); set_commit(); } } }
-    public final void setGDurationValue(GDuration obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDuration(obj); set_commit(); } } }
-    public final void setGDurationValue(GDurationSpecification obj)
-    { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDuration(obj); set_commit(); } } }
-    public final void setQNameValue(QName obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_QName(obj); set_commit(); } } }
-    public final void setListValue(List obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_list(obj); set_commit(); } } }
-    public final void setStringValue(String obj)
-        { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_String(obj); /* strings are special, so set_String does its own commit.*/ } } }
+    public final void setBooleanValue(boolean v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_boolean(v);
+            set_commit();
+        }
+    }
 
-    public void setObjectValue(Object o)
-    {
-        if (o == null)
-        {
+    public final void setByteValue(byte v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_byte(v);
+            set_commit();
+        }
+    }
+
+    public final void setShortValue(short v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_short(v);
+            set_commit();
+        }
+    }
+
+    public final void setIntValue(int v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_int(v);
+            set_commit();
+        }
+    }
+
+    public final void setLongValue(long v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_long(v);
+            set_commit();
+        }
+    }
+
+    public final void setFloatValue(float v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_float(v);
+            set_commit();
+        }
+    }
+
+    public final void setDoubleValue(double v) {
+        synchronized (monitor()) {
+            set_prepare();
+            set_double(v);
+            set_commit();
+        }
+    }
+
+    public final void setByteArrayValue(byte[] obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_ByteArray(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setEnumValue(StringEnumAbstractBase obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_enum(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setBigIntegerValue(BigInteger obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_BigInteger(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setBigDecimalValue(BigDecimal obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_BigDecimal(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setCalendarValue(Calendar obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_Calendar(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setDateValue(Date obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_Date(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setGDateValue(GDate obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_GDate(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setGDateValue(GDateSpecification obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_GDate(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setGDurationValue(GDuration obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_GDuration(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setGDurationValue(GDurationSpecification obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_GDuration(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setQNameValue(QName obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_QName(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setListValue(List obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_list(obj);
+                set_commit();
+            }
+        }
+    }
+
+    public final void setStringValue(String obj) {
+        if (obj == null) {
+            setNil();
+        } else {
+            synchronized (monitor()) {
+                set_prepare();
+                set_String(obj); /* strings are special, so set_String does its own commit.*/
+            }
+        }
+    }
+
+    public void setObjectValue(Object o) {
+        if (o == null) {
             setNil();
             return;
         }
 
-        if (o instanceof XmlObject)
-            set( (XmlObject) o );
-        else if (o instanceof String)
-            setStringValue( (String) o );
-        else if (o instanceof StringEnumAbstractBase)
-            setEnumValue( (StringEnumAbstractBase) o );
-        else if (o instanceof BigInteger)
-            setBigIntegerValue( (BigInteger) o );
-        else if (o instanceof BigDecimal)
-            setBigDecimalValue( (BigDecimal) o );
-        else if (o instanceof Byte)
-            setByteValue( ((Byte)o).byteValue() );
-        else if (o instanceof Short)
-            setShortValue( ((Short)o).shortValue() );
-        else if (o instanceof Integer)
-            setIntValue( ((Integer)o).intValue() );
-        else if (o instanceof Long)
-            setLongValue( ((Long)o).longValue() );
-        else if (o instanceof Boolean)
-            setBooleanValue( ((Boolean)o).booleanValue() );
-        else if (o instanceof Float)
-            setFloatValue( ((Float)o).floatValue() );
-        else if (o instanceof Double)
-            setDoubleValue( ((Double)o).doubleValue() );
-        else if (o instanceof Calendar)
-            setCalendarValue( ((Calendar)o) );
-        else if (o instanceof Date)
-            setDateValue( (Date) o );
-        else if (o instanceof GDateSpecification)
-            setGDateValue( (GDateSpecification) o );
-        else if (o instanceof GDurationSpecification)
-            setGDurationValue( (GDurationSpecification) o );
-        else if (o instanceof QName)
-            setQNameValue( (QName) o );
-        else if (o instanceof List)
-            setListValue( (List) o );
-        else if (o instanceof byte[])
-            setByteArrayValue( (byte[]) o );
-        else
-        {
+        if (o instanceof XmlObject) {
+            set((XmlObject) o);
+        } else if (o instanceof String) {
+            setStringValue((String) o);
+        } else if (o instanceof StringEnumAbstractBase) {
+            setEnumValue((StringEnumAbstractBase) o);
+        } else if (o instanceof BigInteger) {
+            setBigIntegerValue((BigInteger) o);
+        } else if (o instanceof BigDecimal) {
+            setBigDecimalValue((BigDecimal) o);
+        } else if (o instanceof Byte) {
+            setByteValue((Byte) o);
+        } else if (o instanceof Short) {
+            setShortValue((Short) o);
+        } else if (o instanceof Integer) {
+            setIntValue((Integer) o);
+        } else if (o instanceof Long) {
+            setLongValue((Long) o);
+        } else if (o instanceof Boolean) {
+            setBooleanValue((Boolean) o);
+        } else if (o instanceof Float) {
+            setFloatValue((Float) o);
+        } else if (o instanceof Double) {
+            setDoubleValue((Double) o);
+        } else if (o instanceof Calendar) {
+            setCalendarValue(((Calendar) o));
+        } else if (o instanceof Date) {
+            setDateValue((Date) o);
+        } else if (o instanceof GDateSpecification) {
+            setGDateValue((GDateSpecification) o);
+        } else if (o instanceof GDurationSpecification) {
+            setGDurationValue((GDurationSpecification) o);
+        } else if (o instanceof QName) {
+            setQNameValue((QName) o);
+        } else if (o instanceof List) {
+            setListValue((List) o);
+        } else if (o instanceof byte[]) {
+            setByteArrayValue((byte[]) o);
+        } else {
             throw
                 new XmlValueNotSupportedException(
                     "Can't set union object of class : " +
-                        o.getClass().getName() );
+                    o.getClass().getName());
         }
     }
 
-    public final void set_newValue(XmlObject obj)
-    {
-        if (obj == null || obj.isNil())
-        {
+    public final void set_newValue(XmlObject obj) {
+        if (obj == null || obj.isNil()) {
             setNil();
             return;
         }
 
         primitive:
-        if (obj instanceof XmlAnySimpleType)
-        {
-            XmlAnySimpleType v = (XmlAnySimpleType)obj;
-            SchemaType instanceType = ((SimpleValue)v).instanceType();
-            assert(instanceType != null) : "Nil case should have been handled already";
+        if (obj instanceof XmlAnySimpleType) {
+            XmlAnySimpleType v = (XmlAnySimpleType) obj;
+            SchemaType instanceType = ((SimpleValue) v).instanceType();
+            assert (instanceType != null) : "Nil case should have been handled already";
 
             // handle lists
-            if (instanceType.getSimpleVariety() == SchemaType.LIST)
-            {
-                synchronized (monitor())
-                {
+            if (instanceType.getSimpleVariety() == SchemaType.LIST) {
+                synchronized (monitor()) {
                     set_prepare();
-                    set_list(((SimpleValue)v).xgetListValue());
+                    set_list(((SimpleValue) v).xgetListValue());
                     set_commit();
                     return;
                 }
             }
 
             // handle atomic types
-            synchronized (monitor())
-            {
-                assert(instanceType.getSimpleVariety() == SchemaType.ATOMIC);
-                switch (instanceType.getPrimitiveType().getBuiltinTypeCode())
-                {
+            synchronized (monitor()) {
+                assert (instanceType.getSimpleVariety() == SchemaType.ATOMIC);
+                switch (instanceType.getPrimitiveType().getBuiltinTypeCode()) {
                     default:
-                        assert(false) : "encountered nonprimitive type.";
-                    // case SchemaType.BTC_ANY_SIMPLE:  This is handled below...
-                    // but we eventually want to handle it with a treecopy, so
-                    // eventually we should break here.
+                        assert (false) : "encountered nonprimitive type.";
+                        // case SchemaType.BTC_ANY_SIMPLE:  This is handled below...
+                        // but we eventually want to handle it with a treecopy, so
+                        // eventually we should break here.
                         break primitive;
 
-                    case SchemaType.BTC_BOOLEAN:
-                    {
-                        boolean bool = ((SimpleValue)v).getBooleanValue();
+                    case SchemaType.BTC_BOOLEAN: {
+                        boolean bool = ((SimpleValue) v).getBooleanValue();
                         set_prepare();
                         set_boolean(bool);
                         break;
                     }
-                    case SchemaType.BTC_BASE_64_BINARY:
-                    {
-                        byte[] byteArr = ((SimpleValue)v).getByteArrayValue();
+                    case SchemaType.BTC_BASE_64_BINARY: {
+                        byte[] byteArr = ((SimpleValue) v).getByteArrayValue();
                         set_prepare();
                         set_b64(byteArr);
                         break;
                     }
-                    case SchemaType.BTC_HEX_BINARY:
-                    {
-                        byte[] byteArr = ((SimpleValue)v).getByteArrayValue();
+                    case SchemaType.BTC_HEX_BINARY: {
+                        byte[] byteArr = ((SimpleValue) v).getByteArrayValue();
                         set_prepare();
                         set_hex(byteArr);
                         break;
                     }
-                    case SchemaType.BTC_QNAME:
-                    {
-                        QName name = ((SimpleValue)v).getQNameValue();
+                    case SchemaType.BTC_QNAME: {
+                        QName name = ((SimpleValue) v).getQNameValue();
                         set_prepare();
                         set_QName(name);
                         break;
                     }
-                    case SchemaType.BTC_FLOAT:
-                    {
-                        float f = ((SimpleValue)v).getFloatValue();
+                    case SchemaType.BTC_FLOAT: {
+                        float f = ((SimpleValue) v).getFloatValue();
                         set_prepare();
                         set_float(f);
                         break;
                     }
-                    case SchemaType.BTC_DOUBLE:
-                    {
-                        double d = ((SimpleValue)v).getDoubleValue();
+                    case SchemaType.BTC_DOUBLE: {
+                        double d = ((SimpleValue) v).getDoubleValue();
                         set_prepare();
                         set_double(d);
                         break;
                     }
-                    case SchemaType.BTC_DECIMAL:
-                    {
-                        switch (instanceType.getDecimalSize())
-                        {
-                            case SchemaType.SIZE_BYTE:
-                            {
-                                byte b = ((SimpleValue)v).getByteValue();
+                    case SchemaType.BTC_DECIMAL: {
+                        switch (instanceType.getDecimalSize()) {
+                            case SchemaType.SIZE_BYTE: {
+                                byte b = ((SimpleValue) v).getByteValue();
                                 set_prepare();
                                 set_byte(b);
                                 break;
                             }
-                            case SchemaType.SIZE_SHORT:
-                            {
-                                short s = ((SimpleValue)v).getShortValue();
+                            case SchemaType.SIZE_SHORT: {
+                                short s = ((SimpleValue) v).getShortValue();
                                 set_prepare();
                                 set_short(s);
                                 break;
                             }
-                            case SchemaType.SIZE_INT:
-                            {
-                                int i = ((SimpleValue)v).getIntValue();
+                            case SchemaType.SIZE_INT: {
+                                int i = ((SimpleValue) v).getIntValue();
                                 set_prepare();
                                 set_int(i);
                                 break;
                             }
-                            case SchemaType.SIZE_LONG:
-                            {
-                                long l = ((SimpleValue)v).getLongValue();
+                            case SchemaType.SIZE_LONG: {
+                                long l = ((SimpleValue) v).getLongValue();
                                 set_prepare();
                                 set_long(l);
                                 break;
                             }
-                            case SchemaType.SIZE_BIG_INTEGER:
-                            {
-                                BigInteger bi = ((SimpleValue)v).getBigIntegerValue();
+                            case SchemaType.SIZE_BIG_INTEGER: {
+                                BigInteger bi = ((SimpleValue) v).getBigIntegerValue();
                                 set_prepare();
                                 set_BigInteger(bi);
                                 break;
                             }
-                            default:
-                            {
-                                assert(false) : "invalid numeric bit count";
+                            default: {
+                                assert (false) : "invalid numeric bit count";
                                 // fallthrough
                             }
-                            case SchemaType.SIZE_BIG_DECIMAL:
-                            {
-                                BigDecimal bd = ((SimpleValue)v).getBigDecimalValue();
+                            case SchemaType.SIZE_BIG_DECIMAL: {
+                                BigDecimal bd = ((SimpleValue) v).getBigDecimalValue();
                                 set_prepare();
                                 set_BigDecimal(bd);
                                 break;
@@ -1915,23 +2237,20 @@
                         }
                         break;
                     }
-                    case SchemaType.BTC_ANY_URI:
-                    {
+                    case SchemaType.BTC_ANY_URI: {
                         String uri = v.getStringValue();
                         set_prepare();
                         set_text(uri);
                         break;
                     }
-                    case SchemaType.BTC_NOTATION:
-                    {
+                    case SchemaType.BTC_NOTATION: {
                         String s = v.getStringValue();
                         set_prepare();
                         set_notation(s);
                         break;
                     }
-                    case SchemaType.BTC_DURATION:
-                    {
-                        GDuration gd = ((SimpleValue)v).getGDurationValue();
+                    case SchemaType.BTC_DURATION: {
+                        GDuration gd = ((SimpleValue) v).getGDurationValue();
                         set_prepare();
                         set_GDuration(gd);
                         break;
@@ -1943,40 +2262,34 @@
                     case SchemaType.BTC_G_YEAR:
                     case SchemaType.BTC_G_MONTH_DAY:
                     case SchemaType.BTC_G_DAY:
-                    case SchemaType.BTC_G_MONTH:
-                    {
-                        GDate gd = ((SimpleValue)v).getGDateValue();
+                    case SchemaType.BTC_G_MONTH: {
+                        GDate gd = ((SimpleValue) v).getGDateValue();
                         set_prepare();
                         set_GDate(gd);
                         break;
                     }
-                    case SchemaType.BTC_STRING:
-                    {
+                    case SchemaType.BTC_STRING: {
                         String s = v.getStringValue();
                         set_prepare();
                         set_String(s);
                         break;
                     }
-                    case SchemaType.BTC_ANY_SIMPLE:
-                        {
-                            boolean pushed = false;
-                            if (!v.isImmutable())
-                            {
-                                pushed = true;
-                                NamespaceContext.push(new NamespaceContext(v));
-                            }
-                            try
-                            {
-                                set_prepare();
-                                set_xmlanysimple(v);
-                            }
-                            finally
-                            {
-                                if (pushed)
-                                    NamespaceContext.pop();
-                            }
-                            break;
+                    case SchemaType.BTC_ANY_SIMPLE: {
+                        boolean pushed = false;
+                        if (!v.isImmutable()) {
+                            pushed = true;
+                            NamespaceContext.push(new NamespaceContext(v));
                         }
+                        try {
+                            set_prepare();
+                            set_xmlanysimple(v);
+                        } finally {
+                            if (pushed) {
+                                NamespaceContext.pop();
+                            }
+                        }
+                        break;
+                    }
                 }
                 set_commit();
                 return; // primitive node tree copy handled.
@@ -1986,102 +2299,88 @@
         throw new IllegalStateException("Complex type unexpected");
     }
 
-    private TypeStoreUser setterHelper ( XmlObjectBase src )
-    {
+    private TypeStoreUser setterHelper(XmlObjectBase src) {
         check_orphaned();
 
         src.check_orphaned();
 
         return
-            get_store().copy_contents_from( src.get_store() ).
-                get_store().change_type( src.schemaType() );
+            get_store().copy_contents_from(src.get_store()).
+                get_store().change_type(src.schemaType());
     }
 
-    public final XmlObject set(XmlObject src)
-    {
-        if (isImmutable())
+    public final XmlObject set(XmlObject src) {
+        if (isImmutable()) {
             throw new IllegalStateException("Cannot set the value of an immutable XmlObject");
+        }
 
         XmlObjectBase obj = underlying(src);
 
         TypeStoreUser newObj = this;
 
-        if (obj == null)
-        {
+        if (obj == null) {
             setNil();
             return this;
         }
 
-        if (obj.isImmutable())
+        if (obj.isImmutable()) {
             setStringValue(obj.getStringValue());
-        else
-        {
+        } else {
             boolean noSyncThis = preCheck();
-            boolean noSyncObj  = obj.preCheck();
+            boolean noSyncObj = obj.preCheck();
 
             if (monitor() == obj.monitor())             // both are in the same locale
             {
                 if (noSyncThis)                         // the locale is not sync
-                    newObj = setterHelper( obj );
-                else                                    // the locale is sync
+                {
+                    newObj = setterHelper(obj);
+                } else                                    // the locale is sync
                 {
                     synchronized (monitor()) {
-                        newObj = setterHelper( obj );
+                        newObj = setterHelper(obj);
                     }
                 }
-            }
-            else                                        // on different locale's
+            } else                                        // on different locale's
             {
-                if (noSyncThis)
-                {
+                if (noSyncThis) {
                     if (noSyncObj)                      // both unsync
                     {
-                        newObj = setterHelper( obj );
-                    }
-                    else                                // only obj is sync
+                        newObj = setterHelper(obj);
+                    } else                                // only obj is sync
                     {
                         synchronized (obj.monitor()) {
-                            newObj = setterHelper( obj );
+                            newObj = setterHelper(obj);
                         }
                     }
-                }
-                else
-                {
+                } else {
                     if (noSyncObj)                      // only this is sync
                     {
                         synchronized (monitor()) {
-                            newObj = setterHelper( obj );
+                            newObj = setterHelper(obj);
                         }
-                    }
-                    else                                // both are sync can't avoid the global lock
+                    } else                                // both are sync can't avoid the global lock
                     {
                         boolean acquired = false;
 
-                        try
-                        {
+                        try {
                             // about to grab two locks: don't deadlock ourselves
                             GlobalLock.acquire();
                             acquired = true;
 
-                            synchronized (monitor())
-                            {
-                                synchronized (obj.monitor())
-                                {
+                            synchronized (monitor()) {
+                                synchronized (obj.monitor()) {
                                     GlobalLock.release();
                                     acquired = false;
 
-                                    newObj = setterHelper( obj );
+                                    newObj = setterHelper(obj);
                                 }
                             }
-                        }
-                        catch (InterruptedException e)
-                        {
+                        } catch (InterruptedException e) {
                             throw new XmlRuntimeException(e);
-                        }
-                        finally
-                        {
-                            if (acquired)
+                        } finally {
+                            if (acquired) {
                                 GlobalLock.release();
+                            }
                         }
                     }
                 }
@@ -2092,151 +2391,126 @@
     }
 
     public final XmlObject generatedSetterHelperImpl(XmlObject src, QName propName, int index,
-        short kindSetterHelper)
-    {
+                                                     short kindSetterHelper) {
 
         XmlObjectBase srcObj = underlying(src);
 
-        if (srcObj == null)
-        {
-            synchronized (monitor())
-            {
+        if (srcObj == null) {
+            synchronized (monitor()) {
                 XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper);
                 target.setNil();
                 return target;
             }
         }
 
-        if (srcObj.isImmutable())
-        {
-            synchronized (monitor())
-            {
+        if (srcObj.isImmutable()) {
+            synchronized (monitor()) {
                 XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper);
                 target.setStringValue(srcObj.getStringValue());
-                return (XmlObject) target;
+                return target;
             }
         }
 
 
         boolean noSyncThis = preCheck();
-        boolean noSyncObj  = srcObj.preCheck();
+        boolean noSyncObj = srcObj.preCheck();
 
-        if (monitor() == srcObj.monitor())             // both are in the same locale
-        {
-            if (noSyncThis)                         // the locale is not sync
-            {
-                return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
-            }
-            else                                    // the locale is sync
-            {
-                synchronized (monitor())
-                {
-                    return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
+        if (monitor() == srcObj.monitor()) {
+            // both are in the same locale
+            if (noSyncThis) {
+                // the locale is not sync
+                return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
+            } else {
+                // the locale is sync
+                synchronized (monitor()) {
+                    return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
                 }
             }
         }
 
-                                               // on different locale's
-        if (noSyncThis)
-        {
-            if (noSyncObj)                      // both unsync
-            {
-                return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
-            }
-            else                                // only obj is sync
-            {
-                synchronized (srcObj.monitor())
-                {
-                    return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
+        if (noSyncThis) {
+            // on different locale's
+            if (noSyncObj) {
+                // both unsync
+                return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
+            } else {
+                // only obj is sync
+                synchronized (srcObj.monitor()) {
+                    return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
                 }
             }
-        }
-        else
-        {
-            if (noSyncObj)                      // only this is sync
-            {
-                synchronized (monitor())
-                {
-                    return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
+        } else {
+            if (noSyncObj) {
+                // only this is sync
+                synchronized (monitor()) {
+                    return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
                 }
-            }
-            else                                // both are sync can't avoid the global lock
-            {
+            } else {
+                // both are sync can't avoid the global lock
                 boolean acquired = false;
 
-                try
-                {
+                try {
                     // about to grab two locks: don't deadlock ourselves
                     GlobalLock.acquire();
                     acquired = true;
 
-                    synchronized (monitor())
-                    {
-                        synchronized (srcObj.monitor())
-                        {
+                    synchronized (monitor()) {
+                        synchronized (srcObj.monitor()) {
                             GlobalLock.release();
                             acquired = false;
 
-                            return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper);
+                            return (XmlObject) objSetterHelper(srcObj, propName, index, kindSetterHelper);
                         }
                     }
-                }
-                catch (InterruptedException e)
-                {
+                } catch (InterruptedException e) {
                     throw new XmlRuntimeException(e);
-                }
-                finally
-                {
-                    if (acquired)
+                } finally {
+                    if (acquired) {
                         GlobalLock.release();
+                    }
                 }
             }
         }
     }
 
-    private TypeStoreUser objSetterHelper(XmlObjectBase srcObj, QName propName, int index, short kindSetterHelper)
-    {
+    private TypeStoreUser objSetterHelper(XmlObjectBase srcObj, QName propName, int index, short kindSetterHelper) {
         XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper);
 
         target.check_orphaned();
         srcObj.check_orphaned();
 
-        return target.get_store().copy_contents_from( srcObj.get_store() ).
-                get_store().change_type( srcObj.schemaType() );
+        return target.get_store().copy_contents_from(srcObj.get_store()).
+            get_store().change_type(srcObj.schemaType());
     }
 
-    private XmlObjectBase getTargetForSetter(QName propName, int index, short kindSetterHelper)
-    {
-        switch (kindSetterHelper)
-        {
-            case KIND_SETTERHELPER_SINGLETON:
-            {
+    private XmlObjectBase getTargetForSetter(QName propName, int index, short kindSetterHelper) {
+        switch (kindSetterHelper) {
+            case KIND_SETTERHELPER_SINGLETON: {
                 check_orphaned();
-                XmlObjectBase target = null;
-                target = (XmlObjectBase)get_store().find_element_user(propName, index);
-                if (target == null)
-                {
-                    target = (XmlObjectBase)get_store().add_element_user(propName);
+                XmlObjectBase target;
+                target = (XmlObjectBase) get_store().find_element_user(propName, index);
+                if (target == null) {
+                    target = (XmlObjectBase) get_store().add_element_user(propName);
                 }
 
-                if (target.isImmutable())
+                if (target.isImmutable()) {
                     throw new IllegalStateException("Cannot set the value of an immutable XmlObject");
+                }
 
                 return target;
             }
 
-            case KIND_SETTERHELPER_ARRAYITEM:
-            {
+            case KIND_SETTERHELPER_ARRAYITEM: {
                 check_orphaned();
-                XmlObjectBase target = null;
-                target = (XmlObjectBase)get_store().find_element_user(propName, index);
-                if (target == null)
-                {
+                XmlObjectBase target;
+                target = (XmlObjectBase) get_store().find_element_user(propName, index);
+                if (target == null) {
                     throw new IndexOutOfBoundsException();
                 }
 
-                if (target.isImmutable())
+                if (target.isImmutable()) {
                     throw new IllegalStateException("Cannot set the value of an immutable XmlObject");
+                }
 
                 return target;
             }
@@ -2250,185 +2524,217 @@
      * Same as set() but unsynchronized.
      * Warning: Using this method in mutithreaded environment can cause invalid states.
      */
-    public final XmlObject _set(XmlObject src)
-    {
-        if (isImmutable())
+    public final XmlObject _set(XmlObject src) {
+        if (isImmutable()) {
             throw new IllegalStateException("Cannot set the value of an immutable XmlObject");
+        }
 
         XmlObjectBase obj = underlying(src);
 
         TypeStoreUser newObj = this;
 
-        if (obj == null)
-        {
+        if (obj == null) {
             setNil();
             return this;
         }
 
-        if (obj.isImmutable())
+        if (obj.isImmutable()) {
             set(obj.stringValue());
-        else
-        {
+        } else {
             check_orphaned();
             obj.check_orphaned();
 
-            newObj = get_store().copy_contents_from( obj.get_store() ).
-                get_store().change_type( obj.schemaType() );
+            newObj = get_store().copy_contents_from(obj.get_store()).
+                get_store().change_type(obj.schemaType());
         }
         return (XmlObject) newObj;
     }
 
-    protected void set_list(List list)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"List", getPrimitiveTypeName() }); }
-    protected void set_boolean(boolean v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"boolean", getPrimitiveTypeName() }); }
-    protected void set_byte(byte v)
-        { set_int((int) v); }
-    protected void set_short(short v)
-        { set_int((int) v); }
-    protected void set_int(int v)
-        { set_long((long) v); }
-    protected void set_long(long v)
-        { set_BigInteger(BigInteger.valueOf(v)); }
-    protected void set_char(char v)
-        { set_String(Character.toString(v)); }
-    protected void set_float(float v)
-        { set_BigDecimal(new BigDecimal(v)); }
-    protected void set_double(double v)
-        { set_BigDecimal(new BigDecimal(v)); }
-
-    protected void set_enum(StringEnumAbstractBase e)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"enum", getPrimitiveTypeName() }); }
-
-    protected void set_ByteArray(byte[] b)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"byte[]", getPrimitiveTypeName() }); }
-    protected void set_b64(byte[] b)
-        { set_ByteArray(b); }
-    protected void set_hex(byte[] b)
-        { set_ByteArray(b); }
-    protected void set_BigInteger(BigInteger v)
-        { set_BigDecimal(new BigDecimal(v)); }
-    protected void set_BigDecimal(BigDecimal v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"numeric", getPrimitiveTypeName() }); }
-    protected void set_Date(Date v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"Date", getPrimitiveTypeName() }); }
-    protected void set_Calendar(Calendar v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"Calendar", getPrimitiveTypeName() }); }
-    protected void set_GDate(GDateSpecification v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"Date", getPrimitiveTypeName() }); }
-    protected void set_GDuration(GDurationSpecification v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"Duration", getPrimitiveTypeName() }); }
-    protected void set_ComplexXml(XmlObject v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"complex content", getPrimitiveTypeName() }); }
-    protected void set_QName(QName v)
-        { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
-            new Object[] {"QName", getPrimitiveTypeName() }); }
-
-    protected void set_notation(String v)
-        { throw new XmlValueNotSupportedException(); }
-
-    protected void set_xmlanysimple(XmlAnySimpleType v)
-        { set_String(v.getStringValue()); }
-
-    private final String getPrimitiveTypeName()
-    {
-        SchemaType type = schemaType();
-        if (type.isNoType())
-            return "unknown";
-        SchemaType t = type.getPrimitiveType();
-        if (t == null)
-            return "complex";
-        else
-            return t.getName().getLocalPart();
+    protected void set_list(List list) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"List", getPrimitiveTypeName()});
     }
 
-    private final boolean comparable_value_spaces(SchemaType t1, SchemaType t2)
-    {
-        assert(t1.getSimpleVariety() != SchemaType.UNION && t2.getSimpleVariety() != SchemaType.UNION);
+    protected void set_boolean(boolean v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"boolean", getPrimitiveTypeName()});
+    }
 
-        if (!t1.isSimpleType() && !t2.isSimpleType())
+    protected void set_byte(byte v) {
+        set_int(v);
+    }
+
+    protected void set_short(short v) {
+        set_int(v);
+    }
+
+    protected void set_int(int v) {
+        set_long(v);
+    }
+
+    protected void set_long(long v) {
+        set_BigInteger(BigInteger.valueOf(v));
+    }
+
+    protected void set_char(char v) {
+        set_String(Character.toString(v));
+    }
+
+    protected void set_float(float v) {
+        set_BigDecimal(new BigDecimal(v));
+    }
+
+    protected void set_double(double v) {
+        set_BigDecimal(new BigDecimal(v));
+    }
+
+    protected void set_enum(StringEnumAbstractBase e) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"enum", getPrimitiveTypeName()});
+    }
+
+    protected void set_ByteArray(byte[] b) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"byte[]", getPrimitiveTypeName()});
+    }
+
+    protected void set_b64(byte[] b) {
+        set_ByteArray(b);
+    }
+
+    protected void set_hex(byte[] b) {
+        set_ByteArray(b);
+    }
+
+    protected void set_BigInteger(BigInteger v) {
+        set_BigDecimal(new BigDecimal(v));
+    }
+
+    protected void set_BigDecimal(BigDecimal v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"numeric", getPrimitiveTypeName()});
+    }
+
+    protected void set_Date(Date v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"Date", getPrimitiveTypeName()});
+    }
+
+    protected void set_Calendar(Calendar v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"Calendar", getPrimitiveTypeName()});
+    }
+
+    protected void set_GDate(GDateSpecification v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"Date", getPrimitiveTypeName()});
+    }
+
+    protected void set_GDuration(GDurationSpecification v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"Duration", getPrimitiveTypeName()});
+    }
+
+    protected void set_ComplexXml(XmlObject v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"complex content", getPrimitiveTypeName()});
+    }
+
+    protected void set_QName(QName v) {
+        throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S,
+            new Object[]{"QName", getPrimitiveTypeName()});
+    }
+
+    protected void set_notation(String v) {
+        throw new XmlValueNotSupportedException();
+    }
+
+    protected void set_xmlanysimple(XmlAnySimpleType v) {
+        set_String(v.getStringValue());
+    }
+
+    private String getPrimitiveTypeName() {
+        SchemaType type = schemaType();
+        if (type.isNoType()) {
+            return "unknown";
+        }
+        SchemaType t = type.getPrimitiveType();
+        if (t == null) {
+            return "complex";
+        } else {
+            return t.getName().getLocalPart();
+        }
+    }
+
+    private boolean comparable_value_spaces(SchemaType t1, SchemaType t2) {
+        assert (t1.getSimpleVariety() != SchemaType.UNION && t2.getSimpleVariety() != SchemaType.UNION);
+
+        if (!t1.isSimpleType() && !t2.isSimpleType()) {
             return (t1.getContentType() == t2.getContentType());
+        }
 
-        if (!t1.isSimpleType() || !t2.isSimpleType())
+        if (!t1.isSimpleType() || !t2.isSimpleType()) {
             return false;
+        }
 
-        if (t1.getSimpleVariety() == SchemaType.LIST && t2.getSimpleVariety() == SchemaType.LIST)
+        if (t1.getSimpleVariety() == SchemaType.LIST && t2.getSimpleVariety() == SchemaType.LIST) {
             return true;
+        }
 
-        if (t1.getSimpleVariety() == SchemaType.LIST || t2.getSimpleVariety() == SchemaType.LIST)
+        if (t1.getSimpleVariety() == SchemaType.LIST || t2.getSimpleVariety() == SchemaType.LIST) {
             return false;
+        }
 
         return (t1.getPrimitiveType().equals(t2.getPrimitiveType()));
     }
 
-    private final boolean valueEqualsImpl(XmlObject xmlobj)
-    {
+    private boolean valueEqualsImpl(XmlObject xmlobj) {
         check_dated();
 
         SchemaType typethis = instanceType();
-        SchemaType typeother = ((SimpleValue)xmlobj).instanceType();
+        SchemaType typeother = ((SimpleValue) xmlobj).instanceType();
 
         if (typethis == null && typeother == null) // detects nil
+        {
             return true;
+        }
 
-        if (typethis == null || typeother == null)
+        if (typethis == null || typeother == null) {
             return false;
+        }
 
-        if (!comparable_value_spaces(typethis, typeother))
+        if (!comparable_value_spaces(typethis, typeother)) {
             return false;
+        }
 
-        if (xmlobj.schemaType().getSimpleVariety() == SchemaType.UNION)
+        if (xmlobj.schemaType().getSimpleVariety() == SchemaType.UNION) {
             return (underlying(xmlobj)).equal_to(this);
+        }
 
         return equal_to(xmlobj);
     }
 
-    public final boolean valueEquals(XmlObject xmlobj)
-    {
+    public final boolean valueEquals(XmlObject xmlobj) {
         boolean acquired = false;
-        try
-        {
-            if (isImmutable())
-            {
-                if (xmlobj.isImmutable())
-                {
+        try {
+            if (isImmutable()) {
+                if (xmlobj.isImmutable()) {
                     return valueEqualsImpl(xmlobj);
-                }
-                else
-                {
-                    synchronized (xmlobj.monitor())
-                    {
+                } else {
+                    synchronized (xmlobj.monitor()) {
                         return valueEqualsImpl(xmlobj);
                     }
                 }
-            }
-            else
-            {
-                if (xmlobj.isImmutable() || monitor() == xmlobj.monitor())
-                {
-                    synchronized (monitor())
-                    {
+            } else {
+                if (xmlobj.isImmutable() || monitor() == xmlobj.monitor()) {
+                    synchronized (monitor()) {
                         return valueEqualsImpl(xmlobj);
                     }
-                }
-                else
-                {
+                } else {
                     GlobalLock.acquire();
                     acquired = true;
-                    synchronized (monitor())
-                    {
-                        synchronized (xmlobj.monitor())
-                        {
+                    synchronized (monitor()) {
+                        synchronized (xmlobj.monitor()) {
                             GlobalLock.release();
                             acquired = false;
                             return valueEqualsImpl(xmlobj);
@@ -2437,15 +2743,12 @@
                 }
             }
 
-        }
-        catch (InterruptedException e)
-        {
+        } catch (InterruptedException e) {
             throw new XmlRuntimeException(e);
-        }
-        finally
-        {
-            if (acquired)
+        } finally {
+            if (acquired) {
                 GlobalLock.release();
+            }
         }
     }
 
@@ -2453,92 +2756,79 @@
      * Implements Comparable. This compareTo is inconsistent with
      * equals unless isImmutable() is true.
      */
-    public final int compareTo(Object obj)
-    {
-        int result = compareValue((XmlObject)obj); // can throw ClassCast
-        if (result == 2)
+    public final int compareTo(Object obj) {
+        int result = compareValue((XmlObject) obj); // can throw ClassCast
+        if (result == 2) {
             throw new ClassCastException();
+        }
         return result;
     }
 
     /**
      * Allowed to return 2 for incomparable.
      */
-    private final int compareValueImpl(XmlObject xmlobj)
-    {
+    private int compareValueImpl(XmlObject xmlobj) {
         SchemaType type1, type2;
 
-        try
-        {
+        try {
             type1 = instanceType();
-            type2 = ((SimpleValue)xmlobj).instanceType();
-        }
-        catch (XmlValueOutOfRangeException e)
-        {
+            type2 = ((SimpleValue) xmlobj).instanceType();
+        } catch (XmlValueOutOfRangeException e) {
             return 2;
         }
 
-        if (type1 == null && type2 == null)
+        if (type1 == null && type2 == null) {
             return 0;
-        if (type1 == null || type2 == null)
+        }
+        if (type1 == null || type2 == null) {
             return 2;
+        }
 
-        if (!type1.isSimpleType() || type1.isURType())
+        if (!type1.isSimpleType() || type1.isURType()) {
             return 2;
+        }
 
-        if (!type2.isSimpleType() || type2.isURType())
+        if (!type2.isSimpleType() || type2.isURType()) {
             return 2;
+        }
 
         type1 = type1.getPrimitiveType();
         type2 = type2.getPrimitiveType();
 
         // Different value spaces: different
-        if (type1.getBuiltinTypeCode() != type2.getBuiltinTypeCode())
+        if (type1.getBuiltinTypeCode() != type2.getBuiltinTypeCode()) {
             return 2;
+        }
 
         // now we'll depend on our impl class to do the work
         return compare_to(xmlobj);
     }
 
-    public final int compareValue(XmlObject xmlobj)
-    {
-        if (xmlobj == null)
+    public final int compareValue(XmlObject xmlobj) {
+        if (xmlobj == null) {
             return 2;
+        }
 
         boolean acquired = false;
-        try
-        {
-            if (isImmutable())
-            {
-                if (xmlobj.isImmutable())
-                {
+        try {
+            if (isImmutable()) {
+                if (xmlobj.isImmutable()) {
                     return compareValueImpl(xmlobj);
-                }
-                else
-                {
-                    synchronized (xmlobj.monitor())
-                    {
+                } else {
+                    synchronized (xmlobj.monitor()) {
                         return compareValueImpl(xmlobj);
                     }
                 }
-            }
-            else
-            {
-                if (xmlobj.isImmutable() || monitor() == xmlobj.monitor())
-                {
-                    synchronized (monitor())
-                    {
+            } else {
+                if (xmlobj.isImmutable() || monitor() == xmlobj.monitor()) {
+                    synchronized (monitor()) {
                         return compareValueImpl(xmlobj);
                     }
-                }
-                else
-                {
+                } else {
                     GlobalLock.acquire();
                     acquired = true;
-                    synchronized (monitor())
-                    {
-                        synchronized (xmlobj.monitor())
-                        {
+                    synchronized (monitor()) {
+                        synchronized (xmlobj.monitor()) {
                             GlobalLock.release();
                             acquired = false;
                             return compareValueImpl(xmlobj);
@@ -2547,30 +2837,28 @@
                 }
             }
 
-        }
-        catch (InterruptedException e)
-        {
+        } catch (InterruptedException e) {
             throw new XmlRuntimeException(e);
-        }
-        finally
-        {
-            if (acquired)
+        } finally {
+            if (acquired) {
                 GlobalLock.release();
+            }
         }
     }
+
     /**
      * This implementation of compare_to is allowed to do two
      * unusual things:
      * (1) it can assume that the xmlobj passed has a primitive
-     *     type underlying the instance type that matches the
-     *     current instance, and that neither is nil.
+     * type underlying the instance type that matches the
+     * current instance, and that neither is nil.
      * (2) it is allowed to return 2 for "incomparable";
-     *     it should not throw an exception.
+     * it should not throw an exception.
      */
-    protected int compare_to(XmlObject xmlobj)
-    {
-        if (equal_to(xmlobj))
+    protected int compare_to(XmlObject xmlobj) {
+        if (equal_to(xmlobj)) {
             return 0;
+        }
         return 2;
     }
 
@@ -2578,60 +2866,59 @@
 
     protected abstract int value_hash_code();
 
-    public int valueHashCode()
-    {
-        synchronized (monitor())
-        {
+    public int valueHashCode() {
+        synchronized (monitor()) {
             return value_hash_code();
         }
     }
 
 
-    public boolean isInstanceOf(SchemaType type)
-    {
+    public boolean isInstanceOf(SchemaType type) {
         SchemaType myType;
 
-        if (type.getSimpleVariety() != SchemaType.UNION)
-        {
-            for (myType = instanceType(); myType != null; myType = myType.getBaseType())
-                if (type == myType)
+        if (type.getSimpleVariety() != SchemaType.UNION) {
+            for (myType = instanceType(); myType != null; myType = myType.getBaseType()) {
+                if (type == myType) {
                     return true;
-            return false;
-        }
-        else
-        {
-            Set ctypes = new HashSet(Arrays.asList(type.getUnionConstituentTypes()));
-            for (myType = instanceType(); myType != null; myType = myType.getBaseType())
-                if (ctypes.contains(myType))
+                }
+            }
+        } else {
+            Set<SchemaType> ctypes = new HashSet<>(Arrays.asList(type.getUnionConstituentTypes()));
+            for (myType = instanceType(); myType != null; myType = myType.getBaseType()) {
+                if (ctypes.contains(myType)) {
                     return true;
-            return false;
+                }
+            }
         }
+        return false;
     }
 
-    public final boolean equals(Object obj)
-    {
-        if (!isImmutable())
+    public final boolean equals(Object obj) {
+        if (!isImmutable()) {
             return super.equals(obj);
+        }
 
-        if (!(obj instanceof XmlObject))
+        if (!(obj instanceof XmlObject)) {
             return false;
+        }
 
-        XmlObject xmlobj = (XmlObject)obj;
-        if (!xmlobj.isImmutable())
+        XmlObject xmlobj = (XmlObject) obj;
+        if (!xmlobj.isImmutable()) {
             return false;
+        }
 
         return valueEquals(xmlobj);
     }
 
-    public final int hashCode()
-    {
-        if (!isImmutable())
+    public final int hashCode() {
+        if (!isImmutable()) {
             return super.hashCode();
+        }
 
-        synchronized (monitor())
-        {
-            if (isNil())
+        synchronized (monitor()) {
+            if (isNil()) {
                 return 0;
+            }
 
             return value_hash_code();
         }
@@ -2642,32 +2929,28 @@
     /**
      * Selects the contents of the children elements with the given name.
      */
-    public XmlObject[] selectChildren(QName elementName)
-    {
+    public XmlObject[] selectChildren(QName elementName) {
         XmlCursor xc = this.newCursor();
-        try
-        {
-            if (!xc.isContainer())
+        try {
+            if (!xc.isContainer()) {
                 return EMPTY_RESULT;
+            }
 
-            List result = new ArrayList();
+            List<XmlObject> result = new ArrayList<>();
 
-            if (xc.toChild(elementName))
-            {
+            if (xc.toChild(elementName)) {
                 // look for elements
-                do
-                {
+                do {
                     result.add(xc.getObject());
                 }
                 while (xc.toNextSibling(elementName));
             }
-            if (result.size() == 0)
+            if (result.size() == 0) {
                 return EMPTY_RESULT;
-            else
-                return (XmlObject[]) result.toArray(EMPTY_RESULT);
-        }
-        finally
-        {
+            } else {
+                return result.toArray(EMPTY_RESULT);
+            }
+        } finally {
             xc.dispose();
         }
     }
@@ -2675,47 +2958,42 @@
     /**
      * Selects the contents of the children elements with the given name.
      */
-    public XmlObject[] selectChildren(String elementUri, String elementLocalName)
-    {
+    public XmlObject[] selectChildren(String elementUri, String elementLocalName) {
         return selectChildren(new QName(elementUri, elementLocalName));
     }
 
     /**
      * Selects the contents of the children elements that are contained in the elementNameSet.
      */
-    public XmlObject[] selectChildren(QNameSet elementNameSet)
-    {
-        if (elementNameSet==null)
+    public XmlObject[] selectChildren(QNameSet elementNameSet) {
+        if (elementNameSet == null) {
             throw new IllegalArgumentException();
+        }
 
         XmlCursor xc = this.newCursor();
-        try
-        {
-            if (!xc.isContainer())
+        try {
+            if (!xc.isContainer()) {
                 return EMPTY_RESULT;
+            }
 
-            List result = new ArrayList();
+            List<XmlObject> result = new ArrayList<>();
 
-            if (xc.toFirstChild())
-            {
+            if (xc.toFirstChild()) {
                 // look for elements
-                do
-                {
+                do {
                     assert xc.isContainer();
-                    if (elementNameSet.contains(xc.getName()))
-                    {
+                    if (elementNameSet.contains(xc.getName())) {
                         result.add(xc.getObject());
                     }
                 }
                 while (xc.toNextSibling());
             }
-            if (result.size() == 0)
+            if (result.size() == 0) {
                 return EMPTY_RESULT;
-            else
-                return (XmlObject[]) result.toArray(EMPTY_RESULT);
-        }
-        finally
-        {
+            } else {
+                return result.toArray(EMPTY_RESULT);
+            }
+        } finally {
             xc.dispose();
         }
     }
@@ -2723,31 +3001,25 @@
     /**
      * Selects the content of the attribute with the given name.
      */
-    public XmlObject selectAttribute(QName attributeName)
-    {
+    public XmlObject selectAttribute(QName attributeName) {
         XmlCursor xc = this.newCursor();
 
-        try
-        {
-            if (!xc.isContainer())
+        try {
+            if (!xc.isContainer()) {
                 return null;
+            }
 
-            if (xc.toFirstAttribute())
-            {
+            if (xc.toFirstAttribute()) {
                 //look for attributes
-                do
-                {
-                    if (xc.getName().equals(attributeName))
-                    {
+                do {
+                    if (xc.getName().equals(attributeName)) {
                         return xc.getObject();
                     }
                 }
                 while (xc.toNextAttribute());
             }
             return null;
-        }
-        finally
-        {
+        } finally {
             xc.dispose();
         }
     }
@@ -2755,47 +3027,42 @@
     /**
      * Selects the content of the attribute with the given name.
      */
-    public XmlObject selectAttribute(String attributeUri, String attributeLocalName)
-    {
+    public XmlObject selectAttribute(String attributeUri, String attributeLocalName) {
         return selectAttribute(new QName(attributeUri, attributeLocalName));
     }
 
     /**
      * Selects the contents of the attributes that are contained in the elementNameSet.
      */
-    public XmlObject[] selectAttributes(QNameSet attributeNameSet)
-    {
-        if (attributeNameSet==null)
+    public XmlObject[] selectAttributes(QNameSet attributeNameSet) {
+        if (attributeNameSet == null) {
             throw new IllegalArgumentException();
+        }
 
         XmlCursor xc = this.newCursor();
-        try
-        {
-            if (!xc.isContainer())
+        try {
+            if (!xc.isContainer()) {
                 return EMPTY_RESULT;
+            }
 
-            List result = new ArrayList();
+            List<XmlObject> result = new ArrayList<>();
 
-            if (xc.toFirstAttribute())
-            {
+            if (xc.toFirstAttribute()) {
                 //look for attributes
-                do
-                {
-                    if (attributeNameSet.contains(xc.getName()))
-                    {
+                do {
+                    if (attributeNameSet.contains(xc.getName())) {
                         result.add(xc.getObject());
                     }
                 }
                 while (xc.toNextAttribute());
             }
 
-            if (result.size() == 0)
+            if (result.size() == 0) {
                 return EMPTY_RESULT;
-            else
-                return (XmlObject[]) result.toArray(EMPTY_RESULT);
-        }
-        finally
-        {
+            } else {
+                return result.toArray(EMPTY_RESULT);
+            }
+        } finally {
             xc.dispose();
         }
     }
@@ -2803,28 +3070,27 @@
     /**
      * This method can writeReplace either an unwrapped XmlObjectBase
      * or an XBean proxy.  A "true" argument means unwrapped.
-     *
+     * <p>
      * The serialization strategy for XmlObjects is this:
-     *
+     * <p>
      * (1) Only the root XmlObject for a document actually gets
-     *     fully serialized; it is serialized as a SerializedRootObject,
-     *     which simply saves itself as XML text.
-     *
+     * fully serialized; it is serialized as a SerializedRootObject,
+     * which simply saves itself as XML text.
+     * <p>
      * (2) Interior XmlObjects get serialized as a reference to the
-     *     root XmlObject for their document, plus an integer which
-     *     indicates the position of the XmlObject within the owner
-     *     document. This pair is stored as a SerializedInteriorObject.
-     *
+     * root XmlObject for their document, plus an integer which
+     * indicates the position of the XmlObject within the owner
+     * document. This pair is stored as a SerializedInteriorObject.
+     * <p>
      * Both objects can be maked as wrapped or unwrapped. If wrapped,
      * then the proxy is returned when deserializing; if unwrapped, then
      * the proxy is stripped when deserializing.
      */
-    public Object writeReplace()
-    {
-        synchronized (monitor())
-        {
-            if (isRootXmlObject())
+    public Object writeReplace() {
+        synchronized (monitor()) {
+            if (isRootXmlObject()) {
                 return new SerializedRootObject(this);
+            }
 
             return new SerializedInteriorObject(this, getRootXmlObject());
         }
@@ -2833,11 +3099,11 @@
     /**
      * True if the object is at the root of the document.
      */
-    private boolean isRootXmlObject()
-    {
+    private boolean isRootXmlObject() {
         XmlCursor cur = newCursor();
-        if (cur == null)
+        if (cur == null) {
             return false;
+        }
 
         boolean result = !cur.toParent();
         cur.dispose();
@@ -2847,11 +3113,11 @@
     /**
      * Gets the root XmlObject for this document.
      */
-    private XmlObject getRootXmlObject()
-    {
+    private XmlObject getRootXmlObject() {
         XmlCursor cur = newCursor();
-        if (cur == null)
+        if (cur == null) {
             return this;
+        }
         cur.toStartDoc();
         XmlObject result = cur.getObject();
         cur.dispose();
@@ -2863,31 +3129,24 @@
      * to an XmlObjectBase or a proxy for the root object of
      * a document.
      */
-    private static class SerializedRootObject implements Serializable
-    {
+    private static class SerializedRootObject implements Serializable {
         private static final long serialVersionUID = 1;
 
-        transient Class _xbeanClass;
+        transient Class<?> _xbeanClass;
         transient XmlObject _impl;
 
-        private SerializedRootObject()
-        {
-        }
-
-        private SerializedRootObject(XmlObject impl)
-        {
+        private SerializedRootObject(XmlObject impl) {
             _xbeanClass = impl.schemaType().getJavaClass();
             _impl = impl;
         }
 
-        private void writeObject(ObjectOutputStream out) throws IOException
-        {
+        private void writeObject(ObjectOutputStream out) throws IOException {
             out.writeObject(_xbeanClass);
             // the first short is written out for backwards compatibility
             // it will always be zero for objects written with
             // this code, but it used to be the first 2 bytes of the
             // writeUTF() method
-            out.writeShort((short)0);
+            out.writeShort((short) 0);
             out.writeShort(MAJOR_VERSION_NUMBER);
             out.writeShort(MINOR_VERSION_NUMBER);
             // CR122401 - need to use writeObject instead of writeUTF
@@ -2898,15 +3157,13 @@
             out.writeBoolean(false);
         }
 
-        private void readObject(ObjectInputStream in) throws IOException
-        {
-            try
-            {
+        private void readObject(ObjectInputStream in) throws IOException {
+            try {
                 // read class object first - this is
                 // first just for historical reasons - really
                 // it would be better to have the version numbers
                 // first
-                _xbeanClass = (Class)in.readObject();
+                _xbeanClass = (Class<?>) in.readObject();
 
                 int utfBytes = in.readUnsignedShort();
 
@@ -2916,48 +3173,43 @@
                 // to be next entries in stream
                 int majorVersionNum = 0;
                 int minorVersionNum = 0;
-                if (utfBytes == 0)
-                {
+                if (utfBytes == 0) {
                     majorVersionNum = in.readUnsignedShort();
                     minorVersionNum = in.readUnsignedShort();
                 }
 
-                String xmlText = null;
-                switch (majorVersionNum)
-                {
+                String xmlText;
+                switch (majorVersionNum) {
                     case 0: // original, unnumbered version
-                            // minorVersionNum is always zero
+                        // minorVersionNum is always zero
                         xmlText = readObjectV0(in, utfBytes);
                         in.readBoolean(); // ignored
                         break;
 
                     case 1:
-                        switch (minorVersionNum)
-                        {
+                        switch (minorVersionNum) {
                             case 1:
-                                xmlText = (String)in.readObject();
+                                xmlText = (String) in.readObject();
                                 in.readBoolean(); // ignored
                                 break;
 
                             default:
                                 throw new IOException("Deserialization error: " +
-                                        "version number " + majorVersionNum + "." +
-                                        minorVersionNum + " not supported.");
+                                                      "version number " + majorVersionNum + "." +
+                                                      minorVersionNum + " not supported.");
                         }
                         break;
 
                     default:
                         throw new IOException("Deserialization error: " +
-                                "version number " + majorVersionNum + "." +
-                                minorVersionNum + " not supported.");
+                                              "version number " + majorVersionNum + "." +
+                                              minorVersionNum + " not supported.");
                 }
 
                 XmlOptions opts = new XmlOptions().setDocumentType(XmlBeans.typeForClass(_xbeanClass));
                 _impl = XmlBeans.getContextTypeLoader().parse(xmlText, null, opts);
-            }
-            catch (Exception e)
-            {
-                throw (IOException)(new IOException(e.getMessage()).initCause(e));
+            } catch (Exception e) {
+                throw new IOException(e.getMessage(), e);
             }
         }
 
@@ -2976,59 +3228,55 @@
         // bytes there are representing the bytes of the UTF-8-formatted String;
         // this value is passed in as the argument utfBytes
         private String readObjectV0(ObjectInputStream in, int utfBytes)
-                throws IOException
-        {
+            throws IOException {
             // allow an extra 2 bytes up front for the unsigned short
-            byte[] bArray = new byte[utfBytes+2];
+            byte[] bArray = new byte[utfBytes + 2];
 
             // for format of these first 2 bytes see
             // Java API docs - DataOutputStream.writeShort()
-            bArray[0] = (byte)( 0xff & (utfBytes >> 8) );
-            bArray[1] = (byte)( 0xff & utfBytes );
+            bArray[0] = (byte) (0xff & (utfBytes >> 8));
+            bArray[1] = (byte) (0xff & utfBytes);
 
             // read the next numBytes bytes from the input stream
             // into the byte array starting at offset 2; this may
             // take multiple calls to read()
             int totalBytesRead = 0;
             int numRead;
-            while (totalBytesRead < utfBytes)
-            {
+            while (totalBytesRead < utfBytes) {
                 numRead =
-                    in.read(bArray, 2+totalBytesRead, utfBytes-totalBytesRead);
+                    in.read(bArray, 2 + totalBytesRead, utfBytes - totalBytesRead);
                 if (numRead == -1) // reached end of stream
+                {
                     break;
+                }
 
                 totalBytesRead += numRead;
             }
 
-            if (totalBytesRead != utfBytes)
-            {
+            if (totalBytesRead != utfBytes) {
                 throw new IOException("Error reading backwards compatible " +
-                        "XmlObject: number of bytes read (" + totalBytesRead +
-                        ") != number expected (" + utfBytes + ")" );
+                                      "XmlObject: number of bytes read (" + totalBytesRead +
+                                      ") != number expected (" + utfBytes + ")");
             }
 
             // now set up a DataInputStream to read those
             // bytes as a UTF-8 String i.e. as though we'd never
             // read the first 2 bytes from the original stream
             DataInputStream dis = null;
-            String str = null;
-            try
-            {
+            String str;
+            try {
                 dis = new DataInputStream(new ByteArrayInputStream(bArray));
                 str = dis.readUTF();
-            }
-            finally
-            {
-                if (dis != null)
+            } finally {
+                if (dis != null) {
                     dis.close();
+                }
             }
 
             return str;
         }
 
-        private Object readResolve() throws ObjectStreamException
-        {
+        private Object readResolve() throws ObjectStreamException {
             return _impl;
         }
     }
@@ -3038,50 +3286,38 @@
      * to an XmlObjectBase or a proxy for an interior position
      * within a document.
      */
-    private static class SerializedInteriorObject implements Serializable
-    {
+    private static class SerializedInteriorObject implements Serializable {
         private static final long serialVersionUID = 1;
 
         transient XmlObject _impl;
         transient XmlObject _root;
 
-        private SerializedInteriorObject()
-        {
-        }
-
-        private SerializedInteriorObject(XmlObject impl, XmlObject root)
-        {
+        private SerializedInteriorObject(XmlObject impl, XmlObject root) {
             _impl = impl;
             _root = root;
         }
 
-        private void writeObject(ObjectOutputStream out) throws IOException
-        {
+        private void writeObject(ObjectOutputStream out) throws IOException {
             out.writeObject(_root);
             out.writeBoolean(false);
             out.writeInt(distanceToRoot());
         }
 
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
-        {
-            _root = (XmlObject)in.readObject();
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            _root = (XmlObject) in.readObject();
             in.readBoolean();
             _impl = objectAtDistance(in.readInt());
         }
 
-        private Object readResolve() throws ObjectStreamException
-        {
+        private Object readResolve() throws ObjectStreamException {
             return _impl;
         }
 
-        private int distanceToRoot()
-        {
+        private int distanceToRoot() {
             XmlCursor cur = _impl.newCursor();
             int count = 0;
-            while (!cur.toPrevToken().isNone())
-            {
-                if (!cur.currentTokenType().isNamespace())
-                {
+            while (!cur.toPrevToken().isNone()) {
+                if (!cur.currentTokenType().isNamespace()) {
                     count += 1;
                     // System.out.println("Count: " + count + " " + cur.currentTokenType().toString() + " " + QName.pretty(cur.getName()));
                 }
@@ -3090,14 +3326,11 @@
             return count;
         }
 
-        private XmlObject objectAtDistance(int count)
-        {
+        private XmlObject objectAtDistance(int count) {
             XmlCursor cur = _root.newCursor();
-            while (count > 0)
-            {
+            while (count > 0) {
                 cur.toNextToken();
-                if (!cur.currentTokenType().isNamespace())
-                {
+                if (!cur.currentTokenType().isNamespace()) {
                     count -= 1;
                     // System.out.println("Count: " + count + " " + cur.currentTokenType().toString() + " " + QName.pretty(cur.getName()));
                 }
@@ -3108,25 +3341,26 @@
         }
     }
 
-    protected static Object java_value(XmlObject obj)
-    {
-        if (obj.isNil())
+    protected static Object java_value(XmlObject obj) {
+        if (obj.isNil()) {
             return null;
+        }
 
-        if (!(obj instanceof XmlAnySimpleType))
+        if (!(obj instanceof XmlAnySimpleType)) {
             return obj;
+        }
 
-        SchemaType instanceType = ((SimpleValue)obj).instanceType();
-        assert(instanceType != null) : "Nil case should have been handled above";
+        SchemaType instanceType = ((SimpleValue) obj).instanceType();
+        assert (instanceType != null) : "Nil case should have been handled above";
 
         // handle lists
-        if (instanceType.getSimpleVariety() == SchemaType.LIST)
-            return ((SimpleValue)obj).getListValue();
+        if (instanceType.getSimpleVariety() == SchemaType.LIST) {
+            return ((SimpleValue) obj).getListValue();
+        }
 
-        SimpleValue base = (SimpleValue)obj;
+        SimpleValue base = (SimpleValue) obj;
 
-        switch (instanceType.getPrimitiveType().getBuiltinTypeCode())
-        {
+        switch (instanceType.getPrimitiveType().getBuiltinTypeCode()) {
             case SchemaType.BTC_BOOLEAN:
                 return base.getBooleanValue() ? Boolean.TRUE : Boolean.FALSE;
 
@@ -3138,32 +3372,30 @@
                 return base.getQNameValue();
 
             case SchemaType.BTC_FLOAT:
-                return new Float(base.getFloatValue());
+                return base.getFloatValue();
 
             case SchemaType.BTC_DOUBLE:
-                return new Double(base.getDoubleValue());
+                return base.getDoubleValue();
 
-            case SchemaType.BTC_DECIMAL:
-            {
-                switch (instanceType.getDecimalSize())
-                {
+            case SchemaType.BTC_DECIMAL: {
+                switch (instanceType.getDecimalSize()) {
                     case SchemaType.SIZE_BYTE:
-                        return new Byte(base.getByteValue());
+                        return base.getByteValue();
 
                     case SchemaType.SIZE_SHORT:
-                        return new Short(base.getShortValue());
+                        return base.getShortValue();
 
                     case SchemaType.SIZE_INT:
-                        return new Integer(base.getIntValue());
+                        return base.getIntValue();
 
                     case SchemaType.SIZE_LONG:
-                        return new Long(base.getLongValue());
+                        return base.getLongValue();
 
                     case SchemaType.SIZE_BIG_INTEGER:
                         return base.getBigIntegerValue();
 
                     default:
-                        assert(false) : "invalid numeric bit count";
+                        assert (false) : "invalid numeric bit count";
                         // fallthrough
                     case SchemaType.SIZE_BIG_DECIMAL:
                         return base.getBigDecimalValue();
@@ -3186,16 +3418,16 @@
                 return base.getCalendarValue();
 
             default:
-                assert(false) : "encountered nonprimitive type.";
+                assert (false) : "encountered nonprimitive type.";
                 // fallthrough
 
-            // NB: for string enums we just do java.lang.String
-            // when in the context of unions. It's easier on users.
+                // NB: for string enums we just do java.lang.String
+                // when in the context of unions. It's easier on users.
             case SchemaType.BTC_NOTATION:
             case SchemaType.BTC_STRING:
             case SchemaType.BTC_ANY_SIMPLE:
                 // return base.getStringValue();
-            return base.getStringValue();
+                return base.getStringValue();
         }
     }
 
@@ -3203,15 +3435,16 @@
      * Called by code generated code to get the default attribute value
      * for a given attribute name, or null if none.
      */
-    protected XmlAnySimpleType get_default_attribute_value(QName name)
-    {
+    protected XmlAnySimpleType get_default_attribute_value(QName name) {
         SchemaType sType = schemaType();
         SchemaAttributeModel aModel = sType.getAttributeModel();
-        if (aModel == null)
+        if (aModel == null) {
             return null;
+        }
         SchemaLocalAttribute sAttr = aModel.getAttribute(name);
-        if (sAttr == null)
+        if (sAttr == null) {
             return null;
+        }
         return sAttr.getDefaultValue();
     }
 }
diff --git a/src/main/java/org/apache/xmlbeans/impl/xquery/saxon/XBeansXQuery.java b/src/main/java/org/apache/xmlbeans/impl/xquery/saxon/XBeansXQuery.java
index ceca343..bfce95c 100644
--- a/src/main/java/org/apache/xmlbeans/impl/xquery/saxon/XBeansXQuery.java
+++ b/src/main/java/org/apache/xmlbeans/impl/xquery/saxon/XBeansXQuery.java
@@ -63,8 +63,7 @@
     public XBeansXQuery(final String query, String contextVar, Integer boundary, XmlOptions xmlOptions) {
         config = new Configuration();
         StaticQueryContext sc = config.newStaticQueryContext();
-        @SuppressWarnings("unchecked")
-        Map<String,String> nsMap = (Map<String,String>)xmlOptions.get(XmlOptions.LOAD_ADDITIONAL_NAMESPACES);
+        Map<String, String> nsMap = xmlOptions.getLoadAdditionalNamespaces();
         if (nsMap != null) {
             nsMap.forEach(sc::declareNamespace);
         }
@@ -87,14 +86,14 @@
                 ? (Document) contextNode : contextNode.getOwnerDocument();
 
             DocumentWrapper docWrapper = new DocumentWrapper(dom, null, config);
-            NodeInfo root =  docWrapper.wrap(contextNode);
+            NodeInfo root = docWrapper.wrap(contextNode);
 
             DynamicQueryContext dc = new DynamicQueryContext(config);
             dc.setContextItem(root);
             dc.setParameter(new StructuredQName("", null, contextVar), root);
             // Set the other variables
             if (variableBindings != null) {
-                for (Map.Entry<String, Object> me : ((Map<String,Object>)variableBindings).entrySet()) {
+                for (Map.Entry<String, Object> me : ((Map<String, Object>) variableBindings).entrySet()) {
                     StructuredQName key = new StructuredQName("", null, me.getKey());
                     Object value = me.getValue();
                     if (value instanceof XmlTokenSource) {
@@ -134,7 +133,7 @@
         if (value instanceof Boolean) {
             return BooleanValue.get((Boolean) value);
         } else if (value instanceof byte[]) {
-            return new HexBinaryValue((byte[])value);
+            return new HexBinaryValue((byte[]) value);
         } else if (value instanceof Byte) {
             return new Int64Value((Byte) value, BuiltInAtomicType.BYTE, false);
         } else if (value instanceof Float) {
@@ -148,13 +147,13 @@
         } else if (value instanceof Short) {
             return new Int64Value((Short) value, BuiltInAtomicType.SHORT, false);
         } else if (value instanceof String) {
-            return new StringValue((String)value);
+            return new StringValue((String) value);
         } else if (value instanceof BigDecimal) {
-            return new BigDecimalValue((BigDecimal)value);
+            return new BigDecimalValue((BigDecimal) value);
         } else if (value instanceof BigInteger) {
-            return new BigIntegerValue((BigInteger)value);
+            return new BigIntegerValue((BigInteger) value);
         } else if (value instanceof SaxonDuration) {
-            return ((SaxonDuration)value).getDurationValue();
+            return ((SaxonDuration) value).getDurationValue();
         } else if (value instanceof Duration) {
             // this is simpler and safer (but perhaps slower) than extracting all the components
             //return DurationValue.makeDuration(value.toString()).asAtomic();
@@ -162,9 +161,9 @@
             return new DurationValue(dv.getSign() >= 0, dv.getYears(), dv.getMonths(), dv.getDays(),
                 dv.getHours(), dv.getMinutes(), dv.getSeconds(), 0); // take correct millis..
         } else if (value instanceof SaxonXMLGregorianCalendar) {
-            return ((SaxonXMLGregorianCalendar)value).toCalendarValue();
+            return ((SaxonXMLGregorianCalendar) value).toCalendarValue();
         } else if (value instanceof XMLGregorianCalendar) {
-            XMLGregorianCalendar g = (XMLGregorianCalendar)value;
+            XMLGregorianCalendar g = (XMLGregorianCalendar) value;
             QName gtype = g.getXMLSchemaType();
             if (gtype.equals(DatatypeConstants.DATETIME)) {
                 return DateTimeValue.makeDateTimeValue(value.toString(), config.getConversionRules()).asAtomic();
@@ -191,19 +190,20 @@
                 throw new AssertionError("Unknown Gregorian date type");
             }
         } else if (value instanceof QName) {
-            QName q = (QName)value;
+            QName q = (QName) value;
             return new QNameValue(q.getPrefix(), q.getNamespaceURI(), q.getLocalPart()); //BuiltInAtomicType.QNAME, null);
         } else if (value instanceof URI) {
             return new AnyURIValue(value.toString());
         } else if (value instanceof Map) {
             HashTrieMap htm = new HashTrieMap();
-            for (Map.Entry<?,?> me : ((Map<?,?>)value).entrySet()) {
+            for (Map.Entry<?, ?> me : ((Map<?, ?>) value).entrySet()) {
                 htm.initialPut(
-                    (AtomicValue)objectToItem(me.getKey(), config),
+                    (AtomicValue) objectToItem(me.getKey(), config),
                     objectToItem(me.getValue(), config));
             }
             return htm;
         } else {
             return new ObjectValue(value);
         }
-    }}
+    }
+}
diff --git a/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java b/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java
index a842dbe..0c1b76a 100644
--- a/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java
+++ b/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java
@@ -36,7 +36,7 @@
 import java.util.*;
 
 public class SampleXmlUtil {
-    private boolean _soapEnc;
+    private final boolean _soapEnc;
     private static final int MAX_ELEMENTS = 1000;
     private int _nElements;
 
@@ -57,11 +57,10 @@
         // end of the doc so we use the original xml object that the cursor was
         // created upon to do the xmlText() against.
         XmlOptions options = new XmlOptions();
-        options.put(XmlOptions.SAVE_PRETTY_PRINT);
-        options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 2);
-        options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
-        String result = object.xmlText(options);
-        return result;
+        options.setSavePrettyPrint();
+        options.setSavePrettyPrintIndent(2);
+        options.setSaveAggressiveNamespaces();
+        return object.xmlText(options);
     }
 
     Random _picker = new Random(1);
@@ -226,21 +225,7 @@
                 }
 
             case SchemaType.BTC_STRING: {
-                String result;
-                switch (closestBuiltin(sType).getBuiltinTypeCode()) {
-                    case SchemaType.BTC_STRING:
-                    case SchemaType.BTC_NORMALIZED_STRING:
-                        result = "string";
-                        break;
-
-                    case SchemaType.BTC_TOKEN:
-                        result = "token";
-                        break;
-
-                    default:
-                        result = "string";
-                        break;
-                }
+                String result = closestBuiltin(sType).getBuiltinTypeCode() == SchemaType.BTC_TOKEN ? "token" : "string";
 
                 return formatToLength(result, sType);
             }
@@ -299,32 +284,6 @@
         return a[pick(a.length)];
     }
 
-    private String pick(String[] a, int count) {
-        if (count <= 0) {
-            return "";
-        }
-
-        int i = pick(a.length);
-        StringBuilder sb = new StringBuilder(a[i]);
-        while (count-- > 0) {
-            i += 1;
-            if (i >= a.length) {
-                i = 0;
-            }
-            sb.append(' ');
-            sb.append(a[i]);
-        }
-        return sb.toString();
-    }
-
-    private String pickDigits(int digits) {
-        StringBuilder sb = new StringBuilder();
-        while (digits-- > 0) {
-            sb.append(Integer.toString(pick(10)));
-        }
-        return sb.toString();
-    }
-
     private int pickLength(SchemaType sType) {
         XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH);
         if (length != null) {
@@ -385,8 +344,8 @@
                     result = result.substring(0, len);
                 }
             }
-        } catch (Exception e) // intValue can be out of range
-        {
+        } catch (Exception ignored) {
+            // intValue can be out of range
         }
         return result;
     }
@@ -457,10 +416,11 @@
                 sb.append('1');
                 increment = new BigDecimal(sb.toString());
             } else {
-                increment = new BigDecimal(1.0);
+                increment = BigDecimal.ONE;
             }
         }
 
+        //noinspection StatementWithEmptyBody
         if (minOk && maxOk) {
             // OK
         } else if (minOk && !maxOk) {
@@ -529,7 +489,6 @@
         }
 
         GDurationBuilder gdurb = new GDurationBuilder();
-        BigInteger min, max;
 
         gdurb.setSecond(pick(800000));
         gdurb.setMonth(pick(20));
@@ -609,7 +568,7 @@
                 gdurb.setSecond(minExclusive.getSecond() + 1);
             }
             if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0) {
-                gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001)));
+                gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal("0.001")));
             }
         }
 
@@ -644,7 +603,6 @@
     private String formatDate(SchemaType sType) {
         GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000));
         GDate min = null, max = null;
-        GDate temp;
 
         // Find the min and the max according to the type
         switch (sType.getPrimitiveType().getBuiltinTypeCode()) {
@@ -853,7 +811,7 @@
             if (max.compareToGDate(gdateb) <= 0) {
                 // Reset the date to max - (1-8) hours
                 Calendar c = gdateb.getCalendar();
-                c.add(Calendar.HOUR_OF_DAY, 0 - pick(8));
+                c.add(Calendar.HOUR_OF_DAY, -pick(8));
                 gdateb = new GDateBuilder(c);
             }
         } else if (min != null && max != null) {
@@ -975,26 +933,13 @@
                 xmlc.insertComment(minOccurs + " or more repetitions:");
             }
         } else if (sp.getIntMaxOccurs() > 1) {
-            xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:");
+            xmlc.insertComment(minOccurs + " to " + sp.getMaxOccurs() + " repetitions:");
         } else {
             xmlc.insertComment("Optional:");
         }
         return result;
     }
 
-    /*
-     Return a name for the element or the particle type to use in the comment for minoccurs, max occurs
-    */
-    private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc) {
-        String elementOrTypeName = null;
-        if (sp.getParticleType() == SchemaParticle.ELEMENT) {
-            elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")";
-        } else {
-            elementOrTypeName = printParticleType(sp.getParticleType());
-        }
-        return elementOrTypeName;
-    }
-
     private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed) {
         // cast as schema local element
         SchemaLocalElement element = (SchemaLocalElement) sp;
@@ -1015,17 +960,7 @@
 
     }
 
-    private void moveToken(int numToMove, XmlCursor xmlc) {
-        for (int i = 0; i < Math.abs(numToMove); i++) {
-            if (numToMove < 0) {
-                xmlc.toPrevToken();
-            } else {
-                xmlc.toNextToken();
-            }
-        }
-    }
-
-    private static final String formatQName(XmlCursor xmlc, QName qName) {
+    private static String formatQName(XmlCursor xmlc, QName qName) {
         XmlCursor parent = xmlc.newCursor();
         parent.toParent();
         String prefix = parent.prefixForNamespace(qName.getNamespaceURI());
@@ -1045,7 +980,7 @@
     private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType");
     private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset");
 
-    private static final Set SKIPPED_SOAP_ATTRS = new HashSet(Arrays.asList(new QName[]{HREF, ID, ENC_OFFSET}));
+    private static final Set<QName> SKIPPED_SOAP_ATTRS = new HashSet<>(Arrays.asList(HREF, ID, ENC_OFFSET));
 
     private void processAttributes(SchemaType stype, XmlCursor xmlc) {
         if (_soapEnc) {
@@ -1056,8 +991,7 @@
         }
 
         SchemaProperty[] attrProps = stype.getAttributeProperties();
-        for (int i = 0; i < attrProps.length; i++) {
-            SchemaProperty attr = attrProps[i];
+        for (SchemaProperty attr : attrProps) {
             if (_soapEnc) {
                 if (SKIPPED_SOAP_ATTRS.contains(attr.getName())) {
                     continue;
@@ -1090,9 +1024,9 @@
 
     private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed) {
         SchemaParticle[] spc = sp.getParticleChildren();
-        xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level");
-        for (int i = 0; i < spc.length; i++) {
-            processParticle(spc[i], xmlc, mixed);
+        xmlc.insertComment("You have a CHOICE of the next " + spc.length + " items at this level");
+        for (SchemaParticle schemaParticle : spc) {
+            processParticle(schemaParticle, xmlc, mixed);
         }
     }
 
@@ -1112,45 +1046,5 @@
         xmlc.insertElement("AnyElement");
     }
 
-    /**
-     * This method will get the base type for the schema type
-     */
-
-    private static QName getClosestName(SchemaType sType) {
-        while (sType.getName() == null) {
-            sType = sType.getBaseType();
-        }
-
-        return sType.getName();
-    }
-
-    private String printParticleType(int particleType) {
-        StringBuilder returnParticleType = new StringBuilder();
-        returnParticleType.append("Schema Particle Type: ");
-
-        switch (particleType) {
-            case SchemaParticle.ALL:
-                returnParticleType.append("ALL\n");
-                break;
-            case SchemaParticle.CHOICE:
-                returnParticleType.append("CHOICE\n");
-                break;
-            case SchemaParticle.ELEMENT:
-                returnParticleType.append("ELEMENT\n");
-                break;
-            case SchemaParticle.SEQUENCE:
-                returnParticleType.append("SEQUENCE\n");
-                break;
-            case SchemaParticle.WILDCARD:
-                returnParticleType.append("WILDCARD\n");
-                break;
-            default:
-                returnParticleType.append("Schema Particle Type Unknown");
-                break;
-        }
-
-        return returnParticleType.toString();
-    }
-
-    private ArrayList _typeStack = new ArrayList();
+    private final ArrayList<SchemaType> _typeStack = new ArrayList<>();
 }
diff --git a/src/main/java/org/apache/xmlbeans/xml/stream/StartElement.java b/src/main/java/org/apache/xmlbeans/xml/stream/StartElement.java
index 14d904d..a450f6d 100755
--- a/src/main/java/org/apache/xmlbeans/xml/stream/StartElement.java
+++ b/src/main/java/org/apache/xmlbeans/xml/stream/StartElement.java
@@ -16,41 +16,47 @@
 package org.apache.xmlbeans.xml.stream;
 
 import java.util.Map;
+
 /**
  * The StartElement interface provides access to information about
  * start elements
  *
- * @since Weblogic XML Input Stream 1.0
  * @version 1.0
  * @see org.apache.xmlbeans.xml.stream.AttributeIterator
+ * @since Weblogic XML Input Stream 1.0
  */
 
 public interface StartElement extends XMLEvent {
-  /**
-   * Returns an AttributeIterator of non-namespace declared attributes
-   */
-  public AttributeIterator getAttributes();
-  /**
-   * Returns an AttributeIterator of namespaces declared in this element
-   */
-  public AttributeIterator getNamespaces();
-  /**
-   * Returns the union of declared attributes and namespaces
-   */
-  public AttributeIterator getAttributesAndNamespaces();
-  /**
-   * Returns the attribute referred to by this name
-   */
-  public Attribute getAttributeByName(XMLName name);
-  /**
-   * Gets the value that the prefix is bound to in the
-   * context of this element.  Returns null if 
-   * the prefix is not bound in this context
-   */
-  public String getNamespaceUri(String prefix);
-  /**
-   * Gets a java.util.Map from prefixes to URIs in scope for this
-   * element.
-   */
-  public Map getNamespaceMap();
+    /**
+     * Returns an AttributeIterator of non-namespace declared attributes
+     */
+    AttributeIterator getAttributes();
+
+    /**
+     * Returns an AttributeIterator of namespaces declared in this element
+     */
+    AttributeIterator getNamespaces();
+
+    /**
+     * Returns the union of declared attributes and namespaces
+     */
+    AttributeIterator getAttributesAndNamespaces();
+
+    /**
+     * Returns the attribute referred to by this name
+     */
+    Attribute getAttributeByName(XMLName name);
+
+    /**
+     * Gets the value that the prefix is bound to in the
+     * context of this element.  Returns null if
+     * the prefix is not bound in this context
+     */
+    String getNamespaceUri(String prefix);
+
+    /**
+     * Gets a java.util.Map from prefixes to URIs in scope for this
+     * element.
+     */
+    Map<String, String> getNamespaceMap();
 }
diff --git a/src/test/java/common/Common.java b/src/test/java/common/Common.java
index f417af2..a19bbb8 100644
--- a/src/test/java/common/Common.java
+++ b/src/test/java/common/Common.java
@@ -24,8 +24,7 @@
 
 import static org.junit.Assert.assertNotNull;
 
-public class Common
-{
+public class Common {
     public static final String NEWLINE = System.getProperty("line.separator");
     public static final String P = File.separator;
 
@@ -34,7 +33,7 @@
     public static String XBEAN_CASE_ROOT = getCaseLocation() + P + "xbean";
 
     //location of files under "cases folder"
-    public static String OUTPUTROOT = FWROOT+P+"build" + P + "test" + P + "output";
+    public static String OUTPUTROOT = FWROOT + P + "build" + P + "test" + P + "output";
 
 
     public final LinkedList errorList = new LinkedList();
@@ -52,13 +51,13 @@
      * @return
      * @throws IllegalStateException
      */
-    public static String getRootFile() throws IllegalStateException
-    {
+    public static String getRootFile() throws IllegalStateException {
         String baseDir = System.getProperty("xbean.rootdir");
-        if (baseDir == null)
+        if (baseDir == null) {
             return new File(".").getAbsolutePath();
-        else
+        } else {
             return new File(baseDir).getAbsolutePath();
+        }
     }
 
     /**
@@ -68,8 +67,7 @@
      *
      * @throws IllegalStateException
      */
-    public static String getCaseLocation() throws IllegalStateException
-    {
+    public static String getCaseLocation() throws IllegalStateException {
         String baseDir = System.getProperty("cases.location");
         if (baseDir == null) {
             return new File("." + P + "src" + P + "test" + P + "resources").getAbsolutePath();
@@ -84,8 +82,7 @@
      * @param strPath
      * @return file Object for references location
      */
-    public static File xbeanCase(String strPath)
-    {
+    public static File xbeanCase(String strPath) {
         return (new File(CASEROOT, strPath));
     }
 
@@ -95,8 +92,7 @@
      * @param strPath
      * @return File Object specified by strPath
      */
-    public static File xbeanOutput(String strPath)
-    {
+    public static File xbeanOutput(String strPath) {
         File result = (new File(OUTPUTROOT, strPath));
         File parentdir = result.getParentFile();
         parentdir.mkdirs();
@@ -108,16 +104,17 @@
      *
      * @param dir
      */
-    public static void deltree(File dir)
-    {
+    public static void deltree(File dir) {
         if (dir.exists()) {
             if (dir.isDirectory()) {
                 String[] list = dir.list();
-                for (int i = 0; i < list.length; i++)
+                for (int i = 0; i < list.length; i++) {
                     deltree(new File(dir, list[i]));
+                }
             }
-            if (!dir.delete())
+            if (!dir.delete()) {
                 System.out.println("Could not delete " + dir);
+            }
             //throw new IllegalStateException("Could not delete " + dir);
         }
     }
@@ -127,25 +124,25 @@
      *
      * @param errors
      */
-    public static void listErrors(List errors)
-    {
+    public static void listErrors(List errors) {
         for (int i = 0; i < errors.size(); i++) {
             XmlError error = (XmlError) errors.get(i);
-            if (error.getSeverity() == XmlError.SEVERITY_ERROR)
+            if (error.getSeverity() == XmlError.SEVERITY_ERROR) {
                 System.out.println(error.toString());
+            }
         }
     }
 
     /**
      * check list of errors/warnings/msgs and print them. Return true if errors found
+     *
      * @param errors
      * @return
      */
-    public static boolean printOptionErrMsgs(Collection errors)
-    {
+    public static boolean printOptionErrMsgs(Collection errors) {
         boolean errFound = false;
         if (!errors.isEmpty()) {
-            for (Iterator i = errors.iterator(); i.hasNext();) {
+            for (Iterator i = errors.iterator(); i.hasNext(); ) {
                 XmlError eacherr = (XmlError) i.next();
                 int errSeverity = eacherr.getSeverity();
                 if (errSeverity == XmlError.SEVERITY_ERROR) {
@@ -164,25 +161,25 @@
 
     /**
      * Validate schemas to instance based on the docType
+     *
      * @param schemas
      * @param instances
      * @param docType
      * @throws Exception
      */
-    public static void validateInstance(String[] schemas, String[] instances, QName docType) throws Exception
-    {
+    public static void validateInstance(String[] schemas, String[] instances, QName docType) throws Exception {
         SchemaTypeLoader stl = makeSchemaTypeLoader(schemas);
         XmlOptions options = new XmlOptions();
 
         if (docType != null) {
             SchemaType docSchema = stl.findDocumentType(docType);
             Assert.assertTrue(docSchema != null);
-            options.put(XmlOptions.DOCUMENT_TYPE, docSchema);
+            options.setDocumentType(docSchema);
         }
 
         for (int i = 0; i < instances.length; i++) {
             XmlObject x =
-                    stl.parse((String) instances[i], null, options);
+                stl.parse((String) instances[i], null, options);
 
             //if (!startOnDocument) {
             //    XmlCursor c = x.newCursor();
@@ -191,9 +188,9 @@
             //    c.dispose();
             //}
 
-            List xel = new ArrayList();
+            List<XmlError> xel = new ArrayList<>();
 
-            options.put(XmlOptions.ERROR_LISTENER, xel);
+            options.setErrorListener(xel);
 
             boolean isValid = x.validate(options);
 
@@ -202,8 +199,9 @@
                 errorTxt.append("Instance(" + i + "): ");
                 errorTxt.append(x.xmlText());
                 errorTxt.append("Errors: ");
-                for (int j = 0; j < xel.size(); j++)
-                    errorTxt.append(xel.get(j) + "\n");
+                for (XmlError xmlError : xel) {
+                    errorTxt.append(xmlError + "\n");
+                }
                 System.err.println(errorTxt.toString());
                 throw new Exception("Instance not valid\n" + errorTxt.toString());
             }
@@ -217,14 +215,13 @@
      * @param XsdAsString
      * @return
      */
-    public static XmlObject compileXsdString(String XsdAsString)
-    {
+    public static XmlObject compileXsdString(String XsdAsString) {
         XmlObject xobj = null;
         try {
             xobj = XmlObject.Factory.parse(XsdAsString);
         } catch (XmlException xme) {
             if (!xme.getErrors().isEmpty()) {
-                for (Iterator itr = xme.getErrors().iterator(); itr.hasNext();) {
+                for (Iterator itr = xme.getErrors().iterator(); itr.hasNext(); ) {
                     System.out.println("Parse Errors :" + itr.next());
                 }
             }
@@ -241,14 +238,13 @@
      * @param XsdFilePath
      * @return
      */
-    public static XmlObject compileXsdFile(String XsdFilePath)
-    {
+    public static XmlObject compileXsdFile(String XsdFilePath) {
         XmlObject xobj = null;
         try {
             xobj = XmlObject.Factory.parse(new File(XsdFilePath));
         } catch (XmlException xme) {
             if (!xme.getErrors().isEmpty()) {
-                for (Iterator itr = xme.getErrors().iterator(); itr.hasNext();) {
+                for (Iterator itr = xme.getErrors().iterator(); itr.hasNext(); ) {
                     System.out.println("Parse Errors :" + itr.next());
                 }
             }
@@ -269,13 +265,12 @@
      * @throws Exception
      */
     public static SchemaTypeLoader makeSchemaTypeLoader(String[] schemas)
-            throws Exception
-    {
+        throws Exception {
         XmlObject[] schemaDocs = new XmlObject[schemas.length];
 
         for (int i = 0; i < schemas.length; i++) {
             schemaDocs[i] =
-                    XmlObject.Factory.parse(schemas[i]);
+                XmlObject.Factory.parse(schemas[i]);
         }
 
         return XmlBeans.loadXsd(schemaDocs);
@@ -287,36 +282,31 @@
      *
      * @return true if java.version starts with 1.4
      */
-    public static boolean isJDK14()
-    {
+    public static boolean isJDK14() {
         return System.getProperty("java.version").startsWith("1.4");
     }
 
     /**
      * Convenience class for creating tests in a multithreaded env
      */
-    public static abstract class TestThread extends Thread
-    {
+    public static abstract class TestThread extends Thread {
         protected Throwable _throwable;
         protected boolean _result;
         protected XmlOptions xm;
         protected ArrayList errors;
 
-        public TestThread()
-        {
+        public TestThread() {
             xm = new XmlOptions();
             ArrayList errors = new ArrayList();
             xm.setErrorListener(errors);
             xm.setValidateOnSet();
         }
 
-        public Throwable getException()
-        {
+        public Throwable getException() {
             return _throwable;
         }
 
-        public boolean getResult()
-        {
+        public boolean getResult() {
             return _result;
         }
 
diff --git a/src/test/java/compile/scomp/detailed/XmlBeanCompilationTests.java b/src/test/java/compile/scomp/detailed/XmlBeanCompilationTests.java
index 473ea46..795d4b9 100644
--- a/src/test/java/compile/scomp/detailed/XmlBeanCompilationTests.java
+++ b/src/test/java/compile/scomp/detailed/XmlBeanCompilationTests.java
@@ -37,7 +37,7 @@
  * the same schematypesystem
  */
 public class XmlBeanCompilationTests extends CompileTestBase {
-    private final List<String> xm_errors = new ArrayList<String>();
+    private final List<XmlError> xm_errors = new ArrayList<>();
     private final XmlOptions xm_opts = new XmlOptions();
 
     public XmlBeanCompilationTests() {
@@ -47,8 +47,9 @@
 
     @After
     public void tearDown() throws Exception {
-        if (xm_errors.size() > 0)
+        if (xm_errors.size() > 0) {
             xm_errors.clear();
+        }
     }
 
     /**
@@ -109,22 +110,30 @@
         SchemaTypeSystem apiSts = XmlBeans.compileXmlBeans("apiCompile", null,
             schemas, bind, XmlBeans.getBuiltinTypeSystem(), f, xm_opts);
 
-        if (!bind.isIslookupPrefixForNamespace())
+        if (!bind.isIslookupPrefixForNamespace()) {
             throw new Exception("isIslookupPrefixForNamespace not invoked");
-        if (!bind.isIslookupPackageForNamespace())
+        }
+        if (!bind.isIslookupPackageForNamespace()) {
             throw new Exception("isIslookupPackageForNamespace not invoked");
-        if (!bind.isIslookupSuffixForNamespace())
+        }
+        if (!bind.isIslookupSuffixForNamespace()) {
             throw new Exception("isIslookupSuffixForNamespace not invoked");
-        if (!bind.isIslookupJavanameForQName())
+        }
+        if (!bind.isIslookupJavanameForQName()) {
             throw new Exception("isIslookupJavanameForQName not invoked");
-        if (!bind.isIsgetInterfaceExtensionsString())
+        }
+        if (!bind.isIsgetInterfaceExtensionsString()) {
             throw new Exception("isIsgetInterfaceExtensionsString not invoked");
-        if (!bind.isIsgetInterfaceExtensions())
+        }
+        if (!bind.isIsgetInterfaceExtensions()) {
             throw new Exception("isIsgetInterfaceExtensions not invoked");
-        if (!bind.isIsgetPrePostExtensions())
+        }
+        if (!bind.isIsgetPrePostExtensions()) {
             throw new Exception("isIsgetPrePostExtensions not invoked");
-        if (!bind.isIsgetPrePostExtensionsString())
+        }
+        if (!bind.isIsgetPrePostExtensionsString()) {
             throw new Exception("isIsgetPrePostExtensionsString not invoked");
+        }
     }
 
     /**
@@ -160,9 +169,10 @@
 
         assertTrue("Errors should have been empty", err.isEmpty());
         // find element in the type System
-        if (!findGlobalElement(sts.globalElements(), sts1))
+        if (!findGlobalElement(sts.globalElements(), sts1)) {
             throw new Exception(
                 "Could Not find Type from first Type System: " + sts1);
+        }
 
         //SIMPLE INCR COMPILATION
         sts = XmlBeans.compileXmlBeans(null,
@@ -171,13 +181,15 @@
         assertTrue("Errors should have been empty", err.isEmpty());
         // find element in the type System
 
-        if (!findGlobalElement(sts.globalElements(), sts1))
+        if (!findGlobalElement(sts.globalElements(), sts1)) {
             throw new Exception("Could Not find Type from first Type System: " +
                                 sts1);
+        }
 
-        if (!findGlobalElement(sts.globalElements(), sts2))
+        if (!findGlobalElement(sts.globalElements(), sts2)) {
             throw new Exception("Could Not find Type from 2nd Type System: " +
                                 sts2);
+        }
 
         System.out.println("Building over Existing");
         //BUILDING OFF BASE SIMPLE INCR COMPILATION
@@ -187,13 +199,15 @@
         assertTrue("Errors should have been empty", err.isEmpty());
         // find element in the type System
 
-        if (!findGlobalElement(sts.globalElements(), sts1))
+        if (!findGlobalElement(sts.globalElements(), sts1)) {
             throw new Exception("Could Not find Type from first Type System: " +
                                 sts1);
+        }
 
-        if (!findGlobalElement(sts.globalElements(), sts2))
+        if (!findGlobalElement(sts.globalElements(), sts2)) {
             throw new Exception("Could Not find Type from 2nd Type System: " +
                                 sts2);
+        }
 
         //INCR COMPILATION WITH RECOVERABLE ERROR
         err.clear();
@@ -201,17 +215,20 @@
             sts, schemas3, null,
             XmlBeans.getBuiltinTypeSystem(), null, opt);
         // find element in the type System
-        if (!findGlobalElement(b.globalElements(), sts1))
+        if (!findGlobalElement(b.globalElements(), sts1)) {
             throw new Exception("Could Not find Type from first Type System: " +
                                 sts1);
+        }
 
-        if (!findGlobalElement(b.globalElements(), sts2))
+        if (!findGlobalElement(b.globalElements(), sts2)) {
             throw new Exception("Could Not find Type from 2nd Type System: " +
                                 sts2);
+        }
 
-        if (!findGlobalElement(b.globalElements(), sts3))
+        if (!findGlobalElement(b.globalElements(), sts3)) {
             throw new Exception("Could Not find Type from 3rd Type System: " +
                                 sts3);
+        }
 
         printSTS(b);
 
@@ -228,12 +245,14 @@
                 if ((xErr.getErrorCode().compareTo("src-resolve") == 0) &&
                     (xErr.getMessage().compareTo(
                         "type 'bType@http://baz' not found.") ==
-                     0))
+                     0)) {
                     psom_expError = true;
+                }
             }
         }
-        if (!psom_expError)
+        if (!psom_expError) {
             throw new Exception("Error Code was not as Expected");
+        }
 
 
     }
diff --git a/src/test/java/xmlcursor/checkin/StoreTests.java b/src/test/java/xmlcursor/checkin/StoreTests.java
index 3e074aa..61afdd1 100755
--- a/src/test/java/xmlcursor/checkin/StoreTests.java
+++ b/src/test/java/xmlcursor/checkin/StoreTests.java
@@ -142,14 +142,14 @@
     }
 
     @Test
-    public void testImplicitNamespaces() throws Exception {
-        Map<String,String> namespaces = new HashMap<String,String>();
+    public void testImplicitNamespaces() {
+        Map<String, String> namespaces = new HashMap<>();
         namespaces.put("foo", "foo.com");
         namespaces.put("bar", "bar.com");
         namespaces.put("", "default.com");
 
         XmlOptions options = new XmlOptions();
-        options.put(XmlOptions.SAVE_IMPLICIT_NAMESPACES, namespaces);
+        options.setSaveImplicitNamespaces(namespaces);
 
         XmlObject x = XmlObject.Factory.newInstance();
         XmlCursor c = x.newCursor();
@@ -178,19 +178,21 @@
             add("START_ELEMENT");
             add("  namespaceURI: " + namespaceURI);
             add("  localName: " + localName);
-//            add( "  qName: " + qName ); 
+//            add( "  qName: " + qName );
 
-            TreeSet sortedAttrs = new TreeSet();
+            TreeSet<String> sortedAttrs = new TreeSet<>();
 
             for (int i = 0; i < atts.getLength(); i++) {
                 String ln = atts.getLocalName(i);
                 String uri = atts.getURI(i);
                 String qname = atts.getQName(i);
 
-                if (ln.equals("xmlns"))
+                if (ln.equals("xmlns")) {
                     continue;
-                if (qname.startsWith("xmlns"))
+                }
+                if (qname.startsWith("xmlns")) {
                     continue;
+                }
 
 //                if (ln.equals( "xmlns" ))
 //                    ln = "";
@@ -204,8 +206,9 @@
                     atts.getValue(i));
             }
 
-            for (Iterator i = sortedAttrs.iterator(); i.hasNext(); )
-                add("  Attr: " + i.next());
+            for (String sortedAttr : sortedAttrs) {
+                add("  Attr: " + sortedAttr);
+            }
         }
 
         public void endElement(
@@ -297,8 +300,9 @@
 
         private void add(String s, char[] buf, int off, int cch) {
             _sb.append(s);
-            if (buf != null)
+            if (buf != null) {
                 _sb.append(buf, off, cch);
+            }
             _sb.append("\n");
         }
 
@@ -315,7 +319,7 @@
             return _sb.toString();
         }
 
-        private StringBuilder _sb = new StringBuilder();
+        private final StringBuilder _sb = new StringBuilder();
     }
 
     private void doTestSaxSaver(String xml)
@@ -388,8 +392,9 @@
             char ch = xml.charAt(i);
 
             if (ch == '<' && Character.isLetter(xml.charAt(i + 1))) {
-                while (!c.currentTokenType().isStart())
+                while (!c.currentTokenType().isStart()) {
                     c.toNextToken();
+                }
 
                 assertTrue(c.currentTokenType().isStart());
 
@@ -409,8 +414,9 @@
             if (ch == '\n') {
                 line++;
                 col = 1;
-            } else
+            } else {
                 col++;
+            }
         }
     }
 
@@ -445,17 +451,19 @@
         public void whitespace() {
             int p = r.nextInt(100);
 
-            if (p < 20)
+            if (p < 20) {
                 append('\t');
-            else if (p < 40)
+            } else if (p < 40) {
                 append('\n');
-            else
+            } else {
                 append(' ');
+            }
         }
 
         void whitespaces() {
-            for (int i = r.nextInt(8); i > 0; i--)
+            for (int i = r.nextInt(8); i > 0; i--) {
                 whitespace();
+            }
         }
 
         char makeLetter() {
@@ -490,12 +498,13 @@
             for (int i = r.nextInt(20); i > 0; i--) {
                 int p = r.nextInt(100);
 
-                if (p < 70)
+                if (p < 70) {
                     letter();
-                else if (p < 74)
+                } else if (p < 74) {
                     charEntity();
-                else
+                } else {
                     whitespace();
+                }
             }
         }
 
@@ -505,16 +514,18 @@
             for (; ; ) {
                 char ch = makeLetter();
 
-                if (ch == 'x' || ch == 'X')
+                if (ch == 'x' || ch == 'X') {
                     continue;
+                }
 
                 name.append(ch);
 
                 break;
             }
 
-            for (int i = r.nextInt(20); i > 0; i--)
+            for (int i = r.nextInt(20); i > 0; i--) {
                 name.append(makeLetter());
+            }
 
             return name.toString();
         }
@@ -545,14 +556,15 @@
             for (; ; ) {
                 int p = r.nextInt(100);
 
-                if (p < 20)
+                if (p < 20) {
                     break;
-                else if (p < 50)
+                } else if (p < 50) {
                     whitespaces();
-                else if (p < 70)
+                } else if (p < 70) {
                     comment();
-                else
+                } else {
                     procinst();
+                }
             }
         }
 
@@ -583,13 +595,15 @@
         public void attribute() {
             ncName();
 
-            if (r.nextInt(100) == 0)
+            if (r.nextInt(100) == 0) {
                 whitespaces();
+            }
 
             append('=');
 
-            if (r.nextInt(100) == 0)
+            if (r.nextInt(100) == 0) {
                 whitespaces();
+            }
 
             char q = r.nextInt(2) == 0 ? '\'' : '"';
 
@@ -611,34 +625,35 @@
                 append('<');
                 append(name);
 
-                if (r.nextInt(100) == 0)
+                if (r.nextInt(100) == 0) {
                     whitespaces();
+                }
 
-                HashMap attrs = new HashMap();
+                HashMap<String,Object> attrs = new HashMap<>();
 
                 for (int i = r.nextInt(3); i > 0; i--) {
                     append(' ');
 
                     String aname;
 
-                    for (; ; ) {
+                    do {
                         aname = makeNcName();
 
-                        if (!attrs.containsKey(aname))
-                            break;
-                    }
+                    } while (attrs.containsKey(aname));
 
                     attrs.put(aname, null);
 
                     append(aname);
 
-                    if (r.nextInt(100) == 0)
+                    if (r.nextInt(100) == 0) {
                         whitespaces();
+                    }
 
                     append('=');
 
-                    if (r.nextInt(100) == 0)
+                    if (r.nextInt(100) == 0) {
                         whitespaces();
+                    }
 
                     char q = r.nextInt(2) == 0 ? '\'' : '"';
 
@@ -648,8 +663,9 @@
 
                     append(q);
 
-                    if (r.nextInt(10) == 0)
+                    if (r.nextInt(10) == 0) {
                         whitespaces();
+                    }
                 }
 
                 append('>');
@@ -659,16 +675,18 @@
                 append("</");
                 append(name);
 
-                if (r.nextInt(100) == 0)
+                if (r.nextInt(100) == 0) {
                     whitespaces();
+                }
 
                 append('>');
             }
         }
 
         public void document() {
-            if (r.nextInt(2) == 0)
+            if (r.nextInt(2) == 0) {
                 xmlDecl();
+            }
 
             whiteContent();
 
@@ -783,8 +801,9 @@
 
             n++;
 
-            if (t == TokenType.NONE)
+            if (t == TokenType.NONE) {
                 break;
+            }
         }
 
         assertEquals(6, n);
@@ -797,18 +816,16 @@
     @Test
     public void testConsistentTokenOrder()
         throws Exception {
-        ArrayList<TokenType> l = new ArrayList<TokenType>();
+        ArrayList<TokenType> l = new ArrayList<>();
 
         XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor();
 
 
-        for (; ; ) {
+        do {
             // System.err.println(c.currentTokenType());
             l.add(c.currentTokenType());
 
-            if (c.toNextToken() == TokenType.NONE)
-                break;
-        }
+        } while (c.toNextToken() != TokenType.NONE);
 
         c.toEndDoc();
         // System.err.println("Reversing");
@@ -817,8 +834,9 @@
             // System.err.println(c.currentTokenType());
             assertEquals(l.get(i), c.currentTokenType());
 
-            if (c.toPrevToken() == TokenType.NONE)
+            if (c.toPrevToken() == TokenType.NONE) {
                 break;
+            }
         }
     }
 
@@ -954,48 +972,54 @@
                 continue;
             }
 
-            if (n == 0)
+            if (n == 0) {
                 n = 1;
+            }
 
             if (ch == 'c') {
-                if (prev)
+                if (prev) {
                     assertEquals(c.toPrevChar(n), n);
-                else
+                } else {
                     assertEquals(c.toNextChar(n), n);
+                }
             } else if (ch == 't') {
                 while (n-- > 0) {
-                    if (prev)
+                    if (prev) {
                         assertNotSame(c.toPrevToken(), TokenType.NONE);
-                    else
+                    } else {
                         assertNotSame(c.toNextToken(), TokenType.NONE);
+                    }
                 }
             } else if (ch == 'p') {
-                assertTrue(!prev);
+                assertFalse(prev);
 
-                while (n-- > 0)
+                while (n-- > 0) {
                     assertTrue(c.toParent());
+                }
             } else if (ch == 'r') {
-                assertTrue(!prev);
+                assertFalse(prev);
                 assertEquals(1, n);
 
                 c.toEndDoc();
             } else if (ch == 'b') {
-                assertTrue(!prev);
+                assertFalse(prev);
                 assertEquals(1, n);
 
                 c.toStartDoc();
             } else if (ch == 's') {
                 while (n-- > 0) {
-                    if (prev)
+                    if (prev) {
                         assertTrue(c.toPrevSibling());
-                    else
+                    } else {
                         assertTrue(c.toNextSibling());
+                    }
                 }
             } else if (ch == 'd') {
-                assertTrue(!prev);
+                assertFalse(prev);
 
-                while (n-- > 0)
+                while (n-- > 0) {
                     assertTrue(c.toFirstChild());
+                }
             } else {
                 fail();
             }
@@ -1025,9 +1049,7 @@
 
         XmlOptions options = new XmlOptions();
 
-        options.put(
-            XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT,
-            new QName(null, "bar"));
+        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));
 
         assertTrue(
             x.xmlText(options).equals("<bar>[TO]<foo>abcdef</foo>[FROM]</bar>") ||
@@ -1053,7 +1075,7 @@
 
         cFrom = navDoc(x, "d");
         cTo = navNewCursor(cFrom, "t3c");
-        assertTrue(!cFrom.moveXml(cTo));
+        assertFalse(cFrom.moveXml(cTo));
         cFrom.insertChars("[FROM]");
         cTo.insertChars("[TO]");
 
@@ -1433,9 +1455,7 @@
 
         XmlOptions options = new XmlOptions();
 
-        options.put(
-            XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT,
-            new QName(null, "bar"));
+        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));
 
         x = XmlObject.Factory.parse(cTo.xmlText(options));
 
@@ -1451,9 +1471,7 @@
 
         options = new XmlOptions();
 
-        options.put(
-            XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT,
-            new QName(null, "bar"));
+        options.setSaveSyntheticDocumentElement(new QName(null, "bar"));
 
         x = XmlObject.Factory.parse(cTo.xmlText(options));
 
@@ -1556,8 +1574,7 @@
         XmlObject x;
 
         XmlOptions options = new XmlOptions();
-
-        options.put(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT, null);
+        options.setLoadReplaceDocumentElement(null);
 
         x =
             XmlObject.Factory.parse(
@@ -1584,7 +1601,7 @@
         XmlObject x;
         XmlCursor cFrom, cTo;
 
-        // Forward navigation 
+        // Forward navigation
 
         x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>");
 
@@ -1608,7 +1625,7 @@
             }
         }
 
-        // Backward navigation 
+        // Backward navigation
 
         x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>");
 
@@ -1619,12 +1636,13 @@
             assertEquals(0, cFrom.comparePosition(cTo));
             assertTrue(cFrom.isAtSamePositionAs(cTo));
 
-            if (cFrom.toPrevChar(1) == 1)
+            if (cFrom.toPrevChar(1) == 1) {
                 cTo.toPrevChar(1);
-            else if (cFrom.toPrevToken() != TokenType.NONE)
+            } else if (cFrom.toPrevToken() != TokenType.NONE) {
                 cTo.toPrevToken();
-            else
+            } else {
                 break;
+            }
         }
 
         //
@@ -1641,23 +1659,27 @@
 
             for (; ; ) {
                 if (cTo.isAtSamePositionAs(cFrom)) {
-                    assertTrue(!passed);
+                    assertFalse(passed);
                     passed = true;
                 } else if (cTo.isLeftOf(cFrom)) {
-                    assertTrue(!passed);
+                    assertFalse(passed);
                 } else {
                     assertTrue(passed);
                     assertTrue(cTo.isRightOf(cFrom));
                 }
 
-                if (cTo.toNextChar(1) != 1)
-                    if (cTo.toNextToken() == TokenType.ENDDOC)
+                if (cTo.toNextChar(1) != 1) {
+                    if (cTo.toNextToken() == TokenType.ENDDOC) {
                         break;
+                    }
+                }
             }
 
-            if (cFrom.toNextChar(1) != 1)
-                if (cFrom.toNextToken() == TokenType.ENDDOC)
+            if (cFrom.toNextChar(1) != 1) {
+                if (cFrom.toNextToken() == TokenType.ENDDOC) {
                     break;
+                }
+            }
         }
     }
 
@@ -1757,22 +1779,22 @@
         XmlObject x = XmlObject.Factory.parse("<a x='y'>eric<!----><?moo?></a>");
         XmlCursor c = x.newCursor();
         assertNull(c.getName());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertEquals("a", c.getName().getLocalPart());
         assertEquals(0, c.getName().getNamespaceURI().length());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertEquals("x", c.getName().getLocalPart());
         assertEquals(0, c.getName().getNamespaceURI().length());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertNull(c.getName());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertNull(c.getName());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertEquals("moo", c.getName().getLocalPart());
         assertEquals(0, c.getName().getNamespaceURI().length());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertNull(c.getName());
-        assertTrue(!c.toNextToken().isNone());
+        assertFalse(c.toNextToken().isNone());
         assertNull(c.getName());
         assertTrue(c.toNextToken().isNone());
     }
@@ -1798,17 +1820,14 @@
     @Test
     public void testNamespaceSubstitution()
         throws Exception {
-        HashMap<String, String> subs = new HashMap<String, String>();
+        HashMap<String, String> subs = new HashMap<>();
         subs.put("foo", "moo");
         subs.put("a", "b");
 
         XmlOptions options = new XmlOptions();
-        options.put(XmlOptions.LOAD_SUBSTITUTE_NAMESPACES, subs);
+        options.setLoadSubstituteNamespaces(subs);
 
-        XmlObject x =
-            XmlObject.Factory.parse(
-                "<a xmlns='foo' xmlns:a='a' a:x='y'/>",
-                options);
+        XmlObject x = XmlObject.Factory.parse("<a xmlns='foo' xmlns:a='a' a:x='y'/>", options);
 
         XmlCursor c = x.newCursor();
 
@@ -1826,8 +1845,7 @@
     }
 
     @Test
-    public void testNamespaceInsertion()
-        throws Exception {
+    public void testNamespaceInsertion() {
         XmlObject x = XmlObject.Factory.newInstance();
 
         XmlCursor c = x.newCursor();
@@ -1864,7 +1882,7 @@
         XmlCursor c = x.newCursor();
         c.toFirstChild();
         XmlObject fc = c.getObject();
-        assertTrue(!fc.isNil());
+        assertFalse(fc.isNil());
         fc.setNil();
         assertTrue(fc.isNil());
         assertEquals("<canBeNil xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>", x.xmlText());
@@ -1872,7 +1890,7 @@
         assertTrue(c.isAttr());
         c.removeXml();
         assertEquals("<canBeNil/>", x.xmlText());
-        assertTrue(!fc.isNil());
+        assertFalse(fc.isNil());
     }
 
     @Test
@@ -1893,8 +1911,8 @@
         dotestParserErrors("<foo a></foo>");
         dotestParserErrors("<foo>");
         dotestParserErrors("</foo>");
-        dotestParserErrors( "<foo><!-- -- --></foo>" );
-        dotestParserErrors( "<foo><!-- ---></foo>" );
+        dotestParserErrors("<foo><!-- -- --></foo>");
+        dotestParserErrors("<foo><!-- ---></foo>");
 
         dotestParser("<a b=\"x\n\ny\"/>", "<a b=\"x  y\"/>");
     }
@@ -1940,7 +1958,7 @@
         throws Exception {
         String xml = "<a xmlns:a='aNS'><a:b/></a>";
 
-        Map<String, String> map = new java.util.LinkedHashMap<String, String>();
+        Map<String, String> map = new LinkedHashMap<>();
         map.put("b", "bNS");
         map.put("c", "cNS");
         map.put("a", "not-aNS");
@@ -1954,7 +1972,7 @@
 
         xml = "<a xmlns='aNS'><b/></a>";
 
-        map = new java.util.LinkedHashMap<String, String>();
+        map = new LinkedHashMap<>();
         map.put("b", "bNS");
         map.put("c", "cNS");
         map.put("", "not-aNS");
diff --git a/src/test/java/xmlcursor/detailed/CursorVsObjectAttributeTest.java b/src/test/java/xmlcursor/detailed/CursorVsObjectAttributeTest.java
index a3e6c8f..6b0ace6 100755
--- a/src/test/java/xmlcursor/detailed/CursorVsObjectAttributeTest.java
+++ b/src/test/java/xmlcursor/detailed/CursorVsObjectAttributeTest.java
@@ -14,7 +14,7 @@
  */
 
 
-package  xmlcursor.detailed;
+package xmlcursor.detailed;
 
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlCursor.TokenType;
@@ -28,14 +28,15 @@
 
 import javax.xml.namespace.QName;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 
 public class CursorVsObjectAttributeTest {
     @Test
     public void testAttributeSet() throws Exception {
         CarLocationMessageDocument clmDoc = CarLocationMessageDocument.Factory.parse(
-                JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
+            JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
         XmlCursor xc = clmDoc.newCursor();
         xc.toFirstChild();
         CarLocationMessage clm = (CarLocationMessage) xc.getObject();
@@ -50,8 +51,8 @@
     @Test
     public void testAttributeUnsetRemove() throws Exception {
         CarLocationMessageDocument clmDoc =
-                (CarLocationMessageDocument) XmlObject.Factory.parse(
-                        JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
+            (CarLocationMessageDocument) XmlObject.Factory.parse(
+                JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
         XmlCursor xc = clmDoc.newCursor();
         xc.toFirstChild();
         CarLocationMessage clm = (CarLocationMessage) xc.getObject();
@@ -68,11 +69,11 @@
     @Test
     public void testAttributeInsert() throws Exception {
         XmlOptions map = new XmlOptions();
-        map.put(XmlOptions.LOAD_STRIP_WHITESPACE, "");
+        map.setLoadStripWhitespace();
 
         CarLocationMessageDocument clmDoc =
-                (CarLocationMessageDocument) XmlObject.Factory.parse(
-                        JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM), map);
+            (CarLocationMessageDocument) XmlObject.Factory.parse(
+                JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM), map);
         XmlCursor xc = clmDoc.newCursor();
         xc.toFirstChild();
         CarLocationMessage clm = (CarLocationMessage) xc.getObject();
diff --git a/src/test/java/xmlcursor/detailed/InsertNamespaceTest.java b/src/test/java/xmlcursor/detailed/InsertNamespaceTest.java
index 814e352..825d013 100755
--- a/src/test/java/xmlcursor/detailed/InsertNamespaceTest.java
+++ b/src/test/java/xmlcursor/detailed/InsertNamespaceTest.java
@@ -24,7 +24,7 @@
 import xmlcursor.common.BasicCursorTestCase;
 import xmlcursor.common.Common;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 
 public class InsertNamespaceTest extends BasicCursorTestCase {
@@ -36,7 +36,7 @@
         m_xc.insertNamespace("prefix", "value");
         m_xc.toStartDoc();
         XmlOptions map = new XmlOptions();
-        map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        map.setSaveNamespacesFirst(true);
         assertEquals("<foo xmlns:prefix=\"value\" attr0=\"val0\" attr1=\"val1\">text</foo>", m_xc.xmlText(map));
     }
 
@@ -49,7 +49,7 @@
         m_xc.insertNamespace("prefix", "value");
         m_xc.toStartDoc();
         XmlOptions map = new XmlOptions();
-        map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        map.setSaveNamespacesFirst();
         assertEquals("<foo xmlns:prefix=\"value\" attr0=\"val0\" attr1=\"val1\">text</foo>", m_xc.xmlText(map));
     }
 
diff --git a/src/test/java/xmlcursor/detailed/XmlLineNumberTest.java b/src/test/java/xmlcursor/detailed/XmlLineNumberTest.java
index dd1dc1e..ccb682d 100644
--- a/src/test/java/xmlcursor/detailed/XmlLineNumberTest.java
+++ b/src/test/java/xmlcursor/detailed/XmlLineNumberTest.java
@@ -25,8 +25,7 @@
 
 import static org.junit.Assert.*;
 
-public class XmlLineNumberTest extends Common
-{
+public class XmlLineNumberTest extends Common {
     public static final String xml =
         "<people><person born=\"1912\" died=\"1954\" id=\"p342\">\n" +
         "    <name>\n" +
@@ -38,11 +37,12 @@
     public static final String xmlFile =
         XBEAN_CASE_ROOT + P + "xmlcursor" + P + "Employees.xml";
 
-    /** test obtaining XmlLineNumber bookmark with option
-        XmlOptions.setLoadLineNumbers() */
+    /**
+     * test obtaining XmlLineNumber bookmark with option
+     * XmlOptions.setLoadLineNumbers()
+     */
     @Test
-    public void testGetBookmark1() throws Exception
-    {
+    public void testGetBookmark1() throws Exception {
         File f = new File(xmlFile);
         XmlOptions opt = new XmlOptions();
         opt.setLoadLineNumbers();
@@ -58,20 +58,20 @@
         assertEquals(17, ln.getLine());
         c.toEndToken();
         assertEquals(XmlCursor.TokenType.END, c.currentTokenType());
-        ln =(XmlLineNumber) c.getBookmark(XmlLineNumber.class);
+        ln = (XmlLineNumber) c.getBookmark(XmlLineNumber.class);
         // no bookmark at END
         assertNull(ln);
     }
 
-    /** test obtaining XmlLineNumber bookmark with option
-        XmlOptions.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT)
-    */
+    /**
+     * test obtaining XmlLineNumber bookmark with option
+     * XmlOptions.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT)
+     */
     @Test
-    public void testGetBookmark2() throws Exception
-    {
+    public void testGetBookmark2() throws Exception {
         File f = new File(xmlFile);
         XmlOptions opt = new XmlOptions();
-        opt.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT);
+        opt.setLoadLineNumbersEndElement();
         XmlObject xo = XmlObject.Factory.parse(f, opt);
         XmlCursor c = xo.newCursor();
         c.toFirstChild();
@@ -90,11 +90,12 @@
         assertEquals(34, ln.getLine());
     }
 
-    /** test using XmlLineNumber to get line number, column, and offset
-        - parsing xml from string */
+    /**
+     * test using XmlLineNumber to get line number, column, and offset
+     * - parsing xml from string
+     */
     @Test
-    public void testLineNumber1() throws Exception
-    {
+    public void testLineNumber1() throws Exception {
         XmlOptions opt = new XmlOptions().setLoadLineNumbers();
         XmlObject xo = XmlObject.Factory.parse(xml, opt);
         XmlCursor c = xo.newCursor();
@@ -116,13 +117,15 @@
         assertEquals(14, ln.getColumn());
     }
 
-    /** test using XmlLineNumber to get line number, column, and offset
-        - parsing xml from file */
+    /**
+     * test using XmlLineNumber to get line number, column, and offset
+     * - parsing xml from file
+     */
     @Test
     public void testLineNumber2() throws Exception {
         File f = new File(xmlFile);
         XmlOptions opt = new XmlOptions();
-        opt.setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT);
+        opt.setLoadLineNumbersEndElement();
         XmlObject xo = XmlObject.Factory.parse(f, opt);
         XmlCursor c = xo.newCursor();
         c.toFirstContentToken();
diff --git a/src/test/java/xmlobject/checkin/InstanceValidationTests.java b/src/test/java/xmlobject/checkin/InstanceValidationTests.java
index 3eafc21..91730aa 100755
--- a/src/test/java/xmlobject/checkin/InstanceValidationTests.java
+++ b/src/test/java/xmlobject/checkin/InstanceValidationTests.java
@@ -1210,8 +1210,9 @@
         do {
             XmlObject obj = c.getObject();
 
-            if (obj != null)
+            if (obj != null) {
                 obj.validate();
+            }
 
         } while (!c.toNextToken().isNone());
 
@@ -1239,8 +1240,9 @@
         do {
             XmlObject obj = c.getObject();
 
-            if (obj != null)
+            if (obj != null) {
                 obj.validate();
+            }
 
         } while (!c.toNextToken().isNone());
     }
@@ -1862,7 +1864,7 @@
 
             assertNotNull(docSchema);
 
-            options.put(XmlOptions.DOCUMENT_TYPE, docSchema);
+            options.setDocumentType(docSchema);
         }
 
         for (int i = 0; i < validInstances.length; i++) {
@@ -1876,9 +1878,9 @@
                 c.dispose();
             }
 
-            List xel = new ArrayList();
+            List<XmlError> xel = new ArrayList<>();
 
-            options.put(XmlOptions.ERROR_LISTENER, xel);
+            options.setErrorListener(xel);
 
             boolean isValid = x.validate(options);
 
@@ -1887,7 +1889,9 @@
                 System.err.println("Instance(" + i + "): ");
                 System.err.println(x.xmlText());
                 System.err.println("Errors: ");
-                for (Object o : xel) System.err.println(o);
+                for (Object o : xel) {
+                    System.err.println(o);
+                }
                 System.err.println();
             }
 
diff --git a/src/test/java/xmlobject/checkin/ValidateTest.java b/src/test/java/xmlobject/checkin/ValidateTest.java
index e27573c..04106f0 100755
--- a/src/test/java/xmlobject/checkin/ValidateTest.java
+++ b/src/test/java/xmlobject/checkin/ValidateTest.java
@@ -31,31 +31,31 @@
     @Test
     public void testValidateTrue() throws Exception {
         //m_xo = XmlObject.Factory.parse(Common.XML_PURCHASEORDER);
-         m_xo = XmlObject.Factory.parse(
-                JarUtil.getResourceFromJar("xbean/xmlcursor/po.xml"));
+        m_xo = XmlObject.Factory.parse(
+            JarUtil.getResourceFromJar("xbean/xmlcursor/po.xml"));
         assertTrue(m_xo.validate());
     }
 
     @Test
     public void testValidateTrueWithOptionDiscardDocElement() throws Exception {
         XmlOptions map = new XmlOptions();
-        map.put(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT, null);
+        map.setLoadReplaceDocumentElement(null);
         m_xo = XmlObject.Factory.parse(
-                JarUtil.getResourceFromJar(Common.TRANXML_FILE_XMLCURSOR_PO)
-                , map);
+            JarUtil.getResourceFromJar(Common.TRANXML_FILE_XMLCURSOR_PO)
+            , map);
 
         assertFalse(m_xo.validate(map));
     }
 
     @Test
     public void testValidateFalseFixedAttr() throws Exception {
-         m_xo = XmlObject.Factory.parse(
-                JarUtil.getResourceFromJar("xbean/xmlcursor/po.xml"));
-        String ns="declare namespace po=\"http://xbean.test/xmlcursor/PurchaseOrder\";";
-                    String exp_ns="xmlns:po=\"http://xbean.test/xmlcursor/PurchaseOrder\"";
+        m_xo = XmlObject.Factory.parse(
+            JarUtil.getResourceFromJar("xbean/xmlcursor/po.xml"));
+        String ns = "declare namespace po=\"http://xbean.test/xmlcursor/PurchaseOrder\";";
+        String exp_ns = "xmlns:po=\"http://xbean.test/xmlcursor/PurchaseOrder\"";
 
         m_xc = m_xo.newCursor();
-        m_xc.selectPath(ns+" $this//po:shipTo");
+        m_xc.selectPath(ns + " $this//po:shipTo");
         QName name = new QName("country");
         m_xc.setAttributeText(name, "UK");
         XmlObject xo = m_xc.getObject();
diff --git a/src/test/java/xmlobject/xmlloader/detailed/ParseTest.java b/src/test/java/xmlobject/xmlloader/detailed/ParseTest.java
index cb282be..5f33094 100755
--- a/src/test/java/xmlobject/xmlloader/detailed/ParseTest.java
+++ b/src/test/java/xmlobject/xmlloader/detailed/ParseTest.java
@@ -33,11 +33,11 @@
 import static org.junit.Assert.assertNotNull;
 
 public class ParseTest extends BasicCursorTestCase {
-    private XmlOptions m_map = new XmlOptions();
+    private final XmlOptions m_map = new XmlOptions();
 
     @Test
     public void testLoadStripWhitespace() throws Exception {
-        m_map.put(XmlOptions.LOAD_STRIP_WHITESPACE, "");
+        m_map.setLoadStripWhitespace();
         m_xo = XmlObject.Factory.parse("<foo>01234   <bar>text</bar>   chars \r\n</foo>  ",
             m_map);
         m_xc = m_xo.newCursor();
@@ -47,8 +47,7 @@
 
     @Test
     public void testLoadDiscardDocumentElement() throws Exception {
-        QName name = new QName("");
-        m_map.put(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT, name);
+        m_map.setLoadReplaceDocumentElement(new QName(""));
         XmlObject.Factory.parse("<foo>01234   <bar>text</bar>   chars </foo>  ", m_map);
     }
 
@@ -68,8 +67,8 @@
     @Test
     public void testParsingDOMWithDTD() throws Exception {
         final String svgDocumentString = "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" +
-                "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" +
-                "<svg />";
+                                         "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" +
+                                         "<svg />";
         assertNotNull(XmlObject.Factory.parse(svgDocumentString));
         final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
diff --git a/src/test/java/xmltokensource/detailed/NewDomNodeTest.java b/src/test/java/xmltokensource/detailed/NewDomNodeTest.java
index 0155ff5..5607aa8 100755
--- a/src/test/java/xmltokensource/detailed/NewDomNodeTest.java
+++ b/src/test/java/xmltokensource/detailed/NewDomNodeTest.java
@@ -24,6 +24,8 @@
 import org.w3c.dom.NodeList;
 import xmlcursor.common.BasicCursorTestCase;
 
+import javax.xml.namespace.QName;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
@@ -74,9 +76,9 @@
     public void testNewDomNodeWithOptions() throws Exception {
         m_xo = XmlObject.Factory.parse("<foo attr=\"val\" xmlns=\"ns\">01234   <bar>text</bar>   chars </foo>");
         XmlOptions map = new XmlOptions();
-        map.put(XmlOptions.LOAD_STRIP_WHITESPACE, "");
-        map.put(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT, "");
-        map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        map.setLoadStripComments();
+        map.setLoadReplaceDocumentElement(new QName(""));
+        map.setSaveNamespacesFirst();
         Node doc = m_xo.newDomNode(map);
         assertEquals(DOC, doc.getNodeName());
         NodeList nl = doc.getChildNodes();
diff --git a/src/test/java/xmltokensource/detailed/RoundTripLoaderTest.java b/src/test/java/xmltokensource/detailed/RoundTripLoaderTest.java
index c967d2f..383c1f3 100755
--- a/src/test/java/xmltokensource/detailed/RoundTripLoaderTest.java
+++ b/src/test/java/xmltokensource/detailed/RoundTripLoaderTest.java
@@ -38,8 +38,8 @@
 
     @Before
     public void setUp() {
-        m_map.put(XmlOptions.CHARACTER_ENCODING, "Big5");
-        m_map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        m_map.setCharacterEncoding("Big5");
+        m_map.setSaveNamespacesFirst();
     }
 
     private void _newDomNodeRoundTrip(XmlOptions map) throws Exception {
@@ -95,7 +95,7 @@
         m_xo = XmlObject.Factory.parse(Common.XML_FOO_BAR_NESTED_SIBLINGS);
         Reader reader = m_xo.newReader(map);
         assertNotNull(reader);
-         XmlOptions options = new XmlOptions(map);
+        XmlOptions options = new XmlOptions(map);
         XmlObject xo = XmlObject.Factory.parse(reader, options);
         m_xc = m_xo.newCursor();
         XmlCursor xc1 = xo.newCursor();
@@ -111,11 +111,11 @@
      * on this release? Bug? store.Cursor._newXMLInputStream
      * ericvasilik (3:26:01 PM): This is not a v2 feature. ...
      * but otherwise, we should disable XMLInputStream tests
-     *
+     * <p>
      * public void testNewReaderRoundTrip() throws Exception {
      * _newReaderRoundTrip(null);
      * }
-     *
+     * <p>
      * public void testNewReaderWithOptionsRoundTrip() throws Exception {
      * _newReaderRoundTrip(m_map);
      * }
diff --git a/src/test/java/xmltokensource/detailed/XmlTextTest.java b/src/test/java/xmltokensource/detailed/XmlTextTest.java
index 4f48f61..73ed04f 100755
--- a/src/test/java/xmltokensource/detailed/XmlTextTest.java
+++ b/src/test/java/xmltokensource/detailed/XmlTextTest.java
@@ -37,9 +37,9 @@
     public void testSAVENAMESPACESFIRST() throws Exception {
         m_xo = XmlObject.Factory.parse("<foo attr0=\"val0\" xmlns=\"http://www.foo.org\">01234</foo>");
         m_xc = m_xo.newCursor();
-        m_map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        m_map.setSaveNamespacesFirst();
         assertEquals("<foo xmlns=\"http://www.foo.org\" attr0=\"val0\">01234</foo>",
-                     m_xc.xmlText(m_map));
+            m_xc.xmlText(m_map));
     }
 
     @Test
@@ -47,15 +47,14 @@
         m_xo = XmlObject.Factory.parse("<foo attr0=\"val0\" xmlns=\"http://www.foo.org\">01234</foo>");
         m_xc = m_xo.newCursor();
         assertEquals("<foo attr0=\"val0\" xmlns=\"http://www.foo.org\">01234</foo>",
-                     m_xc.xmlText(m_map));
+            m_xc.xmlText(m_map));
     }
 
     @Test
     public void testSaveSyntheticDocumentElement() throws Exception {
         m_xo = XmlObject.Factory.parse("<bar>text</bar>");
         m_xc = m_xo.newCursor();
-        m_map.put(XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT,
-                  new QName("foo"));
+        m_map.setSaveSyntheticDocumentElement(new QName("foo"));
         assertEquals("<foo><bar>text</bar></foo>", m_xc.xmlText(m_map));
     }
 
@@ -63,7 +62,7 @@
     public void testSavePrettyPrint() throws Exception {
         m_xo = XmlObject.Factory.parse("<a><b><c> text </c></b></a>");
         m_xc = m_xo.newCursor();
-        m_map.put(XmlOptions.SAVE_PRETTY_PRINT, "");
+        m_map.setSavePrettyPrint();
         String lnSep = System.getProperty("line.separator");
         assertEquals("<a>" + lnSep + "  <b>" + lnSep + "    <c> text </c>" + lnSep + "  </b>" + lnSep + "</a>", m_xc.xmlText(m_map));
     }
@@ -72,8 +71,8 @@
     public void testSavePrettyPrintIndent3() throws Exception {
         m_xo = XmlObject.Factory.parse("<a><b><c> text </c></b></a>");
         m_xc = m_xo.newCursor();
-        m_map.put(XmlOptions.SAVE_PRETTY_PRINT, "");
-        m_map.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, new Integer(3));
+        m_map.setSavePrettyPrint();
+        m_map.setSavePrettyPrintIndent(3);
         String lnSep = System.getProperty("line.separator");
         assertEquals("<a>" + lnSep + "   <b>" + lnSep + "      <c> text </c>" + lnSep + "   </b>" + lnSep + "</a>", m_xc.xmlText(m_map));
     }
@@ -81,34 +80,34 @@
     @Test
     public void testSavePrettyPrintIndentNeg1() throws Exception {
         m_xc = XmlObject.Factory.parse("<a>  \n  <b>  \n    <c> text   </c>   \n  </b>  \n  </a>").newCursor();
-        m_map.put(XmlOptions.SAVE_PRETTY_PRINT, "");
-        m_map.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, new Integer(-1));
+        m_map.setSavePrettyPrint();
+        m_map.setSavePrettyPrintIndent(-1);
         assertEquals("<a><b><c> text   </c></b></a>", m_xc.xmlText(m_map));
     }
 
     @Test
     public void testDefaultNamespace() throws Exception {
         m_xo = XmlObject.Factory.parse(
-                   JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
+            JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
         m_xc = m_xo.newCursor();
         m_xc.selectPath(Common.CLM_NS_XQUERY_DEFAULT + "$this//FleetID");
         m_xc.toNextSelection();
-        m_map.put(XmlOptions.SAVE_NAMESPACES_FIRST, "");
+        m_map.setSaveNamespacesFirst();
         assertEquals("<FleetID xmlns=\"" + Common.CLM_NS + "\" " +
                      Common.CLM_XSI_NS +
                      ">FLEETNAME</FleetID>",
-                     m_xc.xmlText(m_map));
+            m_xc.xmlText(m_map));
     }
 
     @Test
     public void testSTARTDOCvsFirstChild() throws Exception {
         m_xo = XmlObject.Factory.parse(
-                   JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
+            JarUtil.getResourceFromJar(Common.TRANXML_FILE_CLM));
         m_xc = m_xo.newCursor();
         XmlCursor xc1 = m_xo.newCursor();
         xc1.toFirstChild();
         try {
-            assertEquals(m_xc.xmlText().replaceFirst("(?s)<!--.*-->",""), xc1.xmlText());
+            assertEquals(m_xc.xmlText().replaceFirst("(?s)<!--.*-->", ""), xc1.xmlText());
         } finally {
             xc1.dispose();
         }
