8222743: Xerces 2.12.0: DOM Implementation
authorjoehw
Thu, 25 Apr 2019 15:54:21 -0700
changeset 54628 dcb78d2f07e5
parent 54627 22323f20401b
child 54629 9ebb614d293d
8222743: Xerces 2.12.0: DOM Implementation Reviewed-by: lancea
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java
src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java
test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -110,6 +110,7 @@
  * @author Joe Kesselman, IBM
  * @author Andy Clark, IBM
  * @since PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  *
  */
 public class AttrImpl
@@ -140,8 +141,6 @@
     // REVISIT: we are losing the type information in DOM during serialization
     transient Object type;
 
-    protected TextImpl textNode = null;
-
     //
     // Constructors
     //
@@ -192,14 +191,14 @@
      * NON-DOM
      * set the ownerDocument of this node and its children
      */
-    void setOwnerDocument(CoreDocumentImpl doc) {
+    protected void setOwnerDocument(CoreDocumentImpl doc) {
         if (needsSyncChildren()) {
             synchronizeChildren();
         }
         super.setOwnerDocument(doc);
         if (!hasStringValue()) {
             for (ChildNode child = (ChildNode) value;
-                 child != null; child = child.nextSibling) {
+                child != null; child = child.nextSibling) {
                 child.setOwnerDocument(doc);
             }
         }
@@ -349,6 +348,8 @@
 
         Element ownerElement = getOwnerElement();
         String oldvalue = "";
+        TextImpl textNode = null;
+
         if (needsSyncData()) {
             synchronizeData();
         }
@@ -363,13 +364,7 @@
                     oldvalue = (String) value;
                     // create an actual text node as our child so
                     // that we can use it in the event
-                    if (textNode == null) {
-                        textNode = (TextImpl)
-                            ownerDocument.createTextNode((String) value);
-                    }
-                    else {
-                        textNode.data = (String) value;
-                    }
+                    textNode = (TextImpl) ownerDocument.createTextNode((String) value);
                     value = textNode;
                     textNode.isFirstChild(true);
                     textNode.previousSibling = textNode;
@@ -414,9 +409,16 @@
         // since we need to combine the remove and insert.
         isSpecified(true);
         if (ownerDocument.getMutationEvents()) {
-            // if there are any event handlers create a real node
-            internalInsertBefore(ownerDocument.createTextNode(newvalue),
-                                 null, true);
+            // if there are any event handlers create a real node or
+            // reuse the one we synthesized for the remove notifications
+            // if it exists.
+            if (textNode == null) {
+                textNode = (TextImpl) ownerDocument.createTextNode(newvalue);
+            }
+            else {
+                textNode.data = newvalue;
+            }
+            internalInsertBefore(textNode, null, true);
             hasStringValue(false);
             // notify document
             ownerDocument.modifiedAttrValue(this, oldvalue);
@@ -1034,7 +1036,7 @@
      * NodeList method: Return the Nth immediate child of this node, or
      * null if the index is out of bounds.
      * @return org.w3c.dom.Node
-     * @param Index int
+     * @param index int
      */
     public Node item(int index) {
 
@@ -1076,12 +1078,12 @@
      * Checks if a type is derived from another by restriction. See:
      * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom
      *
-     * @param ancestorNS
+     * @param typeNamespaceArg
      *        The namspace of the ancestor type declaration
-     * @param ancestorName
+     * @param typeNameArg
      *        The name of the ancestor type declaration
-     * @param type
-     *        The reference type definition
+     * @param derivationMethod
+     *        The derivation method
      *
      * @return boolean True if the type is derived by restriciton for the
      *         reference type
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -147,30 +147,6 @@
         setName(namespaceURI, qualifiedName);
     }
 
-    /**
-     * NON-DOM: resets this node and sets specified values for the node
-     *
-     * @param ownerDocument
-     * @param namespaceURI
-     * @param qualifiedName
-     * @param localName
-     */
-    public void setValues (CoreDocumentImpl ownerDocument,
-                         String namespaceURI,
-                         String qualifiedName,
-                         String localName){
-
-        super.textNode = null;
-        super.flags = 0;
-        isSpecified(true);
-        hasStringValue(true);
-        super.setOwnerDocument(ownerDocument);
-        this.localName = localName;
-        this.namespaceURI = namespaceURI;
-        super.name = qualifiedName;
-        super.value = null;
-    }
-
     //
     // DOM2: Namespace methods
     //
@@ -314,14 +290,14 @@
      * Checks if a type is derived from another by restriction. See:
      * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom
      *
-     * @param ancestorNS
+     * @param typeNamespaceArg
      *        The namspace of the ancestor type declaration
-     * @param ancestorName
+     * @param typeNameArg
      *        The name of the ancestor type declaration
-     * @param type
-     *        The reference type definition
+     * @param derivationMethod
+     *        The derivation method
      *
-     * @return boolean True if the type is derived by restriciton for the
+     * @return boolean True if the type is derived by restriction for the
      *         reference type
      */
     public boolean isDerivedFrom(String typeNamespaceArg,
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java	Thu Apr 25 15:54:21 2019 -0700
@@ -40,8 +40,6 @@
     /** Serialization version. */
     static final long serialVersionUID = -6112455738802414002L;
 
-    transient StringBuffer fBufferStr = null;
-
     //
     // Data
     //
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,11 +20,18 @@
 package com.sun.org.apache.xerces.internal.dom;
 
 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
+import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDProcessor;
+import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDValidator;
+import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader;
+import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator;
+import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
 import com.sun.org.apache.xerces.internal.parsers.DOMParserImpl;
 import com.sun.org.apache.xerces.internal.parsers.DTDConfiguration;
 import com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration;
+import com.sun.org.apache.xerces.internal.parsers.XML11DTDConfiguration;
 import com.sun.org.apache.xerces.internal.util.XMLChar;
 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
+import java.lang.ref.SoftReference;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
@@ -51,21 +58,39 @@
  * @xerces.internal
  *
  * @since PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  */
+@SuppressWarnings({"rawtypes", "unchecked"}) //SoftReference array
 public class CoreDOMImplementationImpl
         implements DOMImplementation, DOMImplementationLS {
-        //
-        // Data
-        //
 
-    // validators pool
+    //
+    // Data
+    //
+
+    // validator pools
     private static final int SIZE = 2;
-    private RevalidationHandler validators[] = new RevalidationHandler[SIZE];
+
+    private SoftReference schemaValidators[] = new SoftReference[SIZE];
+    private SoftReference xml10DTDValidators[] = new SoftReference[SIZE];
+    private SoftReference xml11DTDValidators[] = new SoftReference[SIZE];
+
+    private int freeSchemaValidatorIndex = -1;
+    private int freeXML10DTDValidatorIndex = -1;
+    private int freeXML11DTDValidatorIndex = -1;
 
-    private RevalidationHandler dtdValidators[] = new RevalidationHandler[SIZE];
-    private int freeValidatorIndex = -1;
-    private int freeDTDValidatorIndex = -1;
-    private int currentSize = SIZE;
+    private int schemaValidatorsCurrentSize = SIZE;
+    private int xml10DTDValidatorsCurrentSize = SIZE;
+    private int xml11DTDValidatorsCurrentSize = SIZE;
+
+    private SoftReference xml10DTDLoaders[] = new SoftReference[SIZE];
+    private SoftReference xml11DTDLoaders[] = new SoftReference[SIZE];
+
+    private int freeXML10DTDLoaderIndex = -1;
+    private int freeXML11DTDLoaderIndex = -1;
+
+    private int xml10DTDLoaderCurrentSize = SIZE;
+    private int xml11DTDLoaderCurrentSize = SIZE;
 
     // Document and doctype counter.  Used to assign order to documents and
     // doctypes without owners, on an demand basis.   Used for
@@ -74,8 +99,8 @@
 
         // static
         /** Dom implementation singleton. */
-        static CoreDOMImplementationImpl singleton =
-                new CoreDOMImplementationImpl();
+        static final CoreDOMImplementationImpl singleton = new CoreDOMImplementationImpl();
+
         //
         // Public methods
         //
@@ -109,21 +134,25 @@
                 feature = feature.substring(1);
             }
             return (feature.equalsIgnoreCase("Core")
-                        && (anyVersion
-                            || version.equals("1.0")
-                            || version.equals("2.0")
-                            || version.equals("3.0")))
-                    || (feature.equalsIgnoreCase("XML")
-                        && (anyVersion
-                            || version.equals("1.0")
-                            || version.equals("2.0")
-                            || version.equals("3.0")))
-                    || (feature.equalsIgnoreCase("LS")
-                        && (anyVersion
-                            || version.equals("3.0")))
-                    || (feature.equalsIgnoreCase("ElementTraversal")
-                        && (anyVersion
-                            || version.equals("1.0")));
+                    && (anyVersion
+                        || version.equals("1.0")
+                        || version.equals("2.0")
+                        || version.equals("3.0")))
+                        || (feature.equalsIgnoreCase("XML")
+                    && (anyVersion
+                        || version.equals("1.0")
+                        || version.equals("2.0")
+                        || version.equals("3.0")))
+                        || (feature.equalsIgnoreCase("XMLVersion")
+                    && (anyVersion
+                        || version.equals("1.0")
+                        || version.equals("1.1")))
+                        || (feature.equalsIgnoreCase("LS")
+                    && (anyVersion
+                        || version.equals("3.0")))
+                        || (feature.equalsIgnoreCase("ElementTraversal")
+                    && (anyVersion
+                        || version.equals("1.0")));
         } // hasFeature(String,String):boolean
 
 
@@ -244,19 +273,26 @@
                                         null);
                         throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
                 }
-                CoreDocumentImpl doc = new CoreDocumentImpl(doctype);
-                Element e = doc.createElementNS(namespaceURI, qualifiedName);
-                doc.appendChild(e);
+                CoreDocumentImpl doc = createDocument(doctype);
+                // If namespaceURI and qualifiedName are null return a Document with no document element.
+                if (qualifiedName != null || namespaceURI != null) {
+                    Element e = doc.createElementNS(namespaceURI, qualifiedName);
+                    doc.appendChild(e);
+                }
                 return doc;
         }
 
+        protected CoreDocumentImpl createDocument(DocumentType doctype) {
+            return new CoreDocumentImpl(doctype);
+        }
+
         /**
          * DOM Level 3 WD - Experimental.
          */
         public Object getFeature(String feature, String version) {
             if (singleton.hasFeature(feature, version)) {
-                return singleton;
-            }
+                    return singleton;
+                }
             return null;
         }
 
@@ -304,7 +340,7 @@
      *    NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is
      *   not supported.
          */
-        public LSParser createLSParser(short mode, String schemaType)
+    public LSParser createLSParser(short mode, String schemaType)
                 throws DOMException {
                 if (mode != DOMImplementationLS.MODE_SYNCHRONOUS || (schemaType !=null &&
                    !"http://www.w3.org/2001/XMLSchema".equals(schemaType) &&
@@ -318,7 +354,7 @@
                 }
                 if (schemaType != null
                         && schemaType.equals("http://www.w3.org/TR/REC-xml")) {
-                        return new DOMParserImpl(new DTDConfiguration(),
+                        return new DOMParserImpl(new XML11DTDConfiguration(),
                                 schemaType);
                 }
                 else {
@@ -328,20 +364,20 @@
                 }
         }
 
-        /**
-         * DOM Level 3 LS CR - Experimental.
-         * Create a new <code>LSSerializer</code> object.
-         * @return The newly created <code>LSSerializer</code> object.
-         * <p ><b>Note:</b>    By default, the newly created
-         * <code>LSSerializer</code> has no <code>DOMErrorHandler</code>,
-         * i.e. the value of the <code>"error-handler"</code> configuration
-         * parameter is <code>null</code>. However, implementations may
-         * provide a default error handler at creation time. In that case, the
-         * initial value of the <code>"error-handler"</code> configuration
-         * parameter on the new created <code>LSSerializer</code> contains a
-         * reference to the default error handler.
-         */
-        public LSSerializer createLSSerializer() {
+    /**
+     * DOM Level 3 LS CR - Experimental.
+     * Create a new <code>LSSerializer</code> object.
+     * @return The newly created <code>LSSerializer</code> object.
+     * <p ><b>Note:</b>    By default, the newly created
+     * <code>LSSerializer</code> has no <code>DOMErrorHandler</code>,
+     * i.e. the value of the <code>"error-handler"</code> configuration
+     * parameter is <code>null</code>. However, implementations may
+     * provide a default error handler at creation time. In that case, the
+     * initial value of the <code>"error-handler"</code> configuration
+     * parameter on the new created <code>LSSerializer</code> contains a
+     * reference to the default error handler.
+     */
+    public LSSerializer createLSSerializer() {
             return new com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl();
         }
 
@@ -358,68 +394,217 @@
         // Protected methods
         //
         /** NON-DOM: retrieve validator. */
-        synchronized RevalidationHandler getValidator(String schemaType) {
-                // REVISIT: implement retrieving DTD validator
+        synchronized RevalidationHandler getValidator(String schemaType, String xmlVersion) {
         if (schemaType == XMLGrammarDescription.XML_SCHEMA) {
             // create new validator - we should not attempt
             // to restrict the number of validation handlers being
             // requested
-            if(freeValidatorIndex < 0) {
-                return new com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator();
+            while (freeSchemaValidatorIndex >= 0) {
+                // return first available validator
+                SoftReference ref = schemaValidators[freeSchemaValidatorIndex];
+                RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                if (holder != null && holder.handler != null) {
+                    RevalidationHandler val = holder.handler;
+                    holder.handler = null;
+                    --freeSchemaValidatorIndex;
+                    return val;
+                }
+                schemaValidators[freeSchemaValidatorIndex--] = null;
             }
-            // return first available validator
-            RevalidationHandler val = validators[freeValidatorIndex];
-            validators[freeValidatorIndex--] = null;
-            return val;
+            return new XMLSchemaValidator();
         }
         else if(schemaType == XMLGrammarDescription.XML_DTD) {
-            if(freeDTDValidatorIndex < 0) {
-                return new com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator();
+            // return an instance of XML11DTDValidator
+            if ("1.1".equals(xmlVersion)) {
+                while (freeXML11DTDValidatorIndex >= 0) {
+                    // return first available validator
+                    SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex];
+                    RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                    if (holder != null && holder.handler != null) {
+                        RevalidationHandler val = holder.handler;
+                        holder.handler = null;
+                        --freeXML11DTDValidatorIndex;
+                        return val;
+                    }
+                    xml11DTDValidators[freeXML11DTDValidatorIndex--] = null;
+                }
+                return new XML11DTDValidator();
             }
-            // return first available validator
-            RevalidationHandler val = dtdValidators[freeDTDValidatorIndex];
-            dtdValidators[freeDTDValidatorIndex--] = null;
-            return val;
+            // return an instance of XMLDTDValidator
+            else {
+                while (freeXML10DTDValidatorIndex >= 0) {
+                    // return first available validator
+                    SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex];
+                    RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                    if (holder != null && holder.handler != null) {
+                        RevalidationHandler val = holder.handler;
+                        holder.handler = null;
+                        --freeXML10DTDValidatorIndex;
+                        return val;
+                    }
+                    xml10DTDValidators[freeXML10DTDValidatorIndex--] = null;
+                }
+                return new XMLDTDValidator();
+            }
         }
         return null;
         }
 
         /** NON-DOM: release validator */
-        synchronized void releaseValidator(String schemaType,
-                                         RevalidationHandler validator) {
-       // REVISIT: implement support for DTD validators as well
-       if(schemaType == XMLGrammarDescription.XML_SCHEMA) {
-           ++freeValidatorIndex;
-           if (validators.length == freeValidatorIndex ){
-                // resize size of the validators
-                currentSize+=SIZE;
-                RevalidationHandler newarray[] =  new RevalidationHandler[currentSize];
-                System.arraycopy(validators, 0, newarray, 0, validators.length);
-                validators = newarray;
-           }
-           validators[freeValidatorIndex]=validator;
-       }
-       else if(schemaType == XMLGrammarDescription.XML_DTD) {
-           ++freeDTDValidatorIndex;
-           if (dtdValidators.length == freeDTDValidatorIndex ){
-                // resize size of the validators
-                currentSize+=SIZE;
-                RevalidationHandler newarray[] =  new RevalidationHandler[currentSize];
-                System.arraycopy(dtdValidators, 0, newarray, 0, dtdValidators.length);
-                dtdValidators = newarray;
-           }
-           dtdValidators[freeDTDValidatorIndex]=validator;
-       }
+        synchronized void releaseValidator(String schemaType, String xmlVersion,
+                RevalidationHandler validator) {
+            if (schemaType == XMLGrammarDescription.XML_SCHEMA) {
+                ++freeSchemaValidatorIndex;
+                if (schemaValidators.length == freeSchemaValidatorIndex) {
+                    // resize size of the validators
+                    schemaValidatorsCurrentSize += SIZE;
+                    SoftReference newarray[] =  new SoftReference[schemaValidatorsCurrentSize];
+                    System.arraycopy(schemaValidators, 0, newarray, 0, schemaValidators.length);
+                    schemaValidators = newarray;
+                }
+                SoftReference ref = schemaValidators[freeSchemaValidatorIndex];
+                if (ref != null) {
+                    RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                    if (holder != null) {
+                        holder.handler = validator;
+                        return;
+                    }
+                }
+                schemaValidators[freeSchemaValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
+            }
+            else if (schemaType == XMLGrammarDescription.XML_DTD) {
+                // release an instance of XML11DTDValidator
+                if ("1.1".equals(xmlVersion)) {
+                    ++freeXML11DTDValidatorIndex;
+                    if (xml11DTDValidators.length == freeXML11DTDValidatorIndex) {
+                        // resize size of the validators
+                        xml11DTDValidatorsCurrentSize += SIZE;
+                        SoftReference [] newarray = new SoftReference[xml11DTDValidatorsCurrentSize];
+                        System.arraycopy(xml11DTDValidators, 0, newarray, 0, xml11DTDValidators.length);
+                        xml11DTDValidators = newarray;
+                    }
+                    SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex];
+                    if (ref != null) {
+                        RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                        if (holder != null) {
+                            holder.handler = validator;
+                            return;
+                        }
+                    }
+                    xml11DTDValidators[freeXML11DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
+                }
+                // release an instance of XMLDTDValidator
+                else {
+                    ++freeXML10DTDValidatorIndex;
+                    if (xml10DTDValidators.length == freeXML10DTDValidatorIndex) {
+                        // resize size of the validators
+                        xml10DTDValidatorsCurrentSize += SIZE;
+                        SoftReference [] newarray = new SoftReference[xml10DTDValidatorsCurrentSize];
+                        System.arraycopy(xml10DTDValidators, 0, newarray, 0, xml10DTDValidators.length);
+                        xml10DTDValidators = newarray;
+                    }
+                    SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex];
+                    if (ref != null) {
+                        RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
+                        if (holder != null) {
+                            holder.handler = validator;
+                            return;
+                        }
+                    }
+                    xml10DTDValidators[freeXML10DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
+                }
+            }
         }
 
-       /** NON-DOM:  increment document/doctype counter */
-       protected synchronized int assignDocumentNumber() {
-            return ++docAndDoctypeCounter;
-       }
-       /** NON-DOM:  increment document/doctype counter */
-       protected synchronized int assignDocTypeNumber() {
-            return ++docAndDoctypeCounter;
-       }
+    /** NON-DOM: retrieve DTD loader */
+    synchronized final XMLDTDLoader getDTDLoader(String xmlVersion) {
+        // return an instance of XML11DTDProcessor
+        if ("1.1".equals(xmlVersion)) {
+            while (freeXML11DTDLoaderIndex >= 0) {
+                // return first available DTD loader
+                SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex];
+                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
+                if (holder != null && holder.loader != null) {
+                    XMLDTDLoader val = holder.loader;
+                    holder.loader = null;
+                    --freeXML11DTDLoaderIndex;
+                    return val;
+                }
+                xml11DTDLoaders[freeXML11DTDLoaderIndex--] = null;
+            }
+            return new XML11DTDProcessor();
+        }
+        // return an instance of XMLDTDLoader
+        else {
+            while (freeXML10DTDLoaderIndex >= 0) {
+                // return first available DTD loader
+                SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex];
+                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
+                if (holder != null && holder.loader != null) {
+                    XMLDTDLoader val = holder.loader;
+                    holder.loader = null;
+                    --freeXML10DTDLoaderIndex;
+                    return val;
+                }
+                xml10DTDLoaders[freeXML10DTDLoaderIndex--] = null;
+            }
+            return new XMLDTDLoader();
+        }
+    }
+
+    /** NON-DOM: release DTD loader */
+    synchronized final void releaseDTDLoader(String xmlVersion, XMLDTDLoader loader) {
+        // release an instance of XMLDTDLoader
+        if ("1.1".equals(xmlVersion)) {
+            ++freeXML11DTDLoaderIndex;
+            if (xml11DTDLoaders.length == freeXML11DTDLoaderIndex) {
+                // resize size of the DTD loaders
+                xml11DTDLoaderCurrentSize += SIZE;
+                SoftReference [] newarray = new SoftReference[xml11DTDLoaderCurrentSize];
+                System.arraycopy(xml11DTDLoaders, 0, newarray, 0, xml11DTDLoaders.length);
+                xml11DTDLoaders = newarray;
+            }
+            SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex];
+            if (ref != null) {
+                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
+                if (holder != null) {
+                    holder.loader = loader;
+                    return;
+                }
+            }
+            xml11DTDLoaders[freeXML11DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
+        }
+        // release an instance of XMLDTDLoader
+        else {
+            ++freeXML10DTDLoaderIndex;
+            if (xml10DTDLoaders.length == freeXML10DTDLoaderIndex) {
+                // resize size of the DTD loaders
+                xml10DTDLoaderCurrentSize += SIZE;
+                SoftReference [] newarray = new SoftReference[xml10DTDLoaderCurrentSize];
+                System.arraycopy(xml10DTDLoaders, 0, newarray, 0, xml10DTDLoaders.length);
+                xml10DTDLoaders = newarray;
+            }
+            SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex];
+            if (ref != null) {
+                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
+                if (holder != null) {
+                    holder.loader = loader;
+                    return;
+                }
+            }
+            xml10DTDLoaders[freeXML10DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
+        }
+    }
+
+    /** NON-DOM:  increment document/doctype counter */
+    protected synchronized int assignDocumentNumber() {
+        return ++docAndDoctypeCounter;
+    }
+
+    /** NON-DOM:  increment document/doctype counter */
+    protected synchronized int assignDocTypeNumber() {
+        return ++docAndDoctypeCounter;
+    }
 
     /* DOM Level 3 LS CR - Experimental.
      *
@@ -427,11 +612,33 @@
      * <code>LSOutput.characterStream</code>,
      * <code>LSOutput.byteStream</code>, <code>LSOutput.systemId</code>,
      * <code>LSOutput.encoding</code> are null.
+     * @return  The newly created output object.
+    */
+    public LSOutput createLSOutput() {
+        return new DOMOutputImpl();
+    }
 
-     * @return  The newly created output object.
+    /**
+     * A holder for RevalidationHandlers. This allows us to reuse
+     * SoftReferences which haven't yet been cleared by the garbage
+     * collector.
      */
-       public LSOutput createLSOutput() {
-           return new DOMOutputImpl();
-       }
+    static final class RevalidationHandlerHolder {
+        RevalidationHandlerHolder(RevalidationHandler handler) {
+            this.handler = handler;
+        }
+        RevalidationHandler handler;
+    }
+
+    /**
+     * A holder for XMLDTDLoaders. This allows us to reuse SoftReferences
+     * which haven't yet been cleared by the garbage collector.
+     */
+    static final class XMLDTDLoaderHolder {
+        XMLDTDLoaderHolder(XMLDTDLoader loader) {
+            this.loader = loader;
+        }
+        XMLDTDLoader loader;
+    }
 
 } // class DOMImplementationImpl
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,7 +32,6 @@
 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
 import com.sun.org.apache.xerces.internal.util.PropertyState;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
-import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
@@ -52,6 +51,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.StringTokenizer;
 import javax.xml.XMLConstants;
 import javax.xml.catalog.CatalogFeatures;
 import jdk.xml.internal.JdkXmlUtils;
@@ -70,7 +70,7 @@
  *
  * @author Elena Litani, IBM
  * @author Neeraj Bajaj, Sun Microsystems.
- * @LastModified: Oct 2017
+ * @LastModified: Apr 2019
  */
 public class DOMConfigurationImpl extends ParserConfigurationSettings
     implements XMLParserConfiguration, DOMConfiguration {
@@ -79,6 +79,9 @@
     // Constants
     //
 
+    protected static final String XML11_DATATYPE_VALIDATOR_FACTORY =
+        "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl";
+
     // feature identifiers
 
     /** Feature identifier: validation. */
@@ -101,12 +104,41 @@
     protected static final String NORMALIZE_DATA =
         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
 
+    /** Feature identifier: send element default value via characters() */
+    protected static final String SCHEMA_ELEMENT_DEFAULT =
+        Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
+
     /** sending psvi in the pipeline */
     protected static final String SEND_PSVI =
         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
 
-    protected final static String DTD_VALIDATOR_FACTORY_PROPERTY =
-        Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
+    /** Feature: generate synthetic annotations */
+    protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
+        Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
+
+    /** Feature identifier: validate annotations */
+    protected static final String VALIDATE_ANNOTATIONS =
+        Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
+
+    /** Feature identifier: honour all schemaLocations */
+    protected static final String HONOUR_ALL_SCHEMALOCATIONS =
+        Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
+
+    /** Feature identifier: use grammar pool only */
+    protected static final String USE_GRAMMAR_POOL_ONLY =
+        Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
+
+    /** Feature identifier: load external DTD. */
+    protected static final String DISALLOW_DOCTYPE_DECL_FEATURE =
+        Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
+
+    /** Feature identifier: balance syntax trees. */
+    protected static final String BALANCE_SYNTAX_TREES =
+        Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES;
+
+    /** Feature identifier: warn on duplicate attribute definition. */
+    protected static final String WARN_ON_DUPLICATE_ATTDEF =
+        Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
 
     /** Feature identifier: namespace growth */
     protected static final String NAMESPACE_GROWTH =
@@ -133,9 +165,9 @@
     protected static final String SYMBOL_TABLE =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
 
-    /** Property id: Grammar pool*/
+    /** Property id: Grammar pool. */
     protected static final String GRAMMAR_POOL =
-    Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
+        Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
 
     /** Property identifier: error handler. */
     protected static final String ERROR_HANDLER =
@@ -147,15 +179,31 @@
 
     /** Property identifier: JAXP schema language / DOM schema-type. */
     protected static final String JAXP_SCHEMA_LANGUAGE =
-    Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
+        Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
 
     /** Property identifier: JAXP schema source/ DOM schema-location. */
     protected static final String JAXP_SCHEMA_SOURCE =
-    Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
+        Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
+
+    /** Property identifier: DTD validator. */
+    protected final static String DTD_VALIDATOR_PROPERTY =
+        Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
+
+    /** Property identifier: datatype validator factory. */
+    protected static final String DTD_VALIDATOR_FACTORY_PROPERTY =
+        Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
 
     protected static final String VALIDATION_MANAGER =
         Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
 
+    /** Property identifier: schema location. */
+    protected static final String SCHEMA_LOCATION =
+        Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
+
+    /** Property identifier: no namespace schema location. */
+    protected static final String SCHEMA_NONS_LOCATION =
+        Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
+
     /** Property identifier: Schema DV Factory */
     protected static final String SCHEMA_DV_FACTORY =
         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
@@ -209,8 +257,18 @@
     protected final DOMErrorHandlerWrapper fErrorHandlerWrapper =
                 new DOMErrorHandlerWrapper();
 
+    /** Current Datatype validator factory. */
+    protected DTDDVFactory fCurrentDVFactory;
+
+    /** The XML 1.0 Datatype validator factory. */
+    protected DTDDVFactory fDatatypeValidatorFactory;
+
+    /** The XML 1.1 Datatype validator factory. **/
+    protected DTDDVFactory fXML11DatatypeFactory;
+
     // private data
 
+    private String fSchemaLocation = null;
     private DOMStringList fRecognizedParameters;
 
 
@@ -256,7 +314,16 @@
             SCHEMA_FULL_CHECKING,
             DYNAMIC_VALIDATION,
             NORMALIZE_DATA,
+            SCHEMA_ELEMENT_DEFAULT,
             SEND_PSVI,
+            GENERATE_SYNTHETIC_ANNOTATIONS,
+            VALIDATE_ANNOTATIONS,
+            HONOUR_ALL_SCHEMALOCATIONS,
+            USE_GRAMMAR_POOL_ONLY,
+            DISALLOW_DOCTYPE_DECL_FEATURE,
+            BALANCE_SYNTAX_TREES,
+            WARN_ON_DUPLICATE_ATTDEF,
+            PARSER_SETTINGS,
             NAMESPACE_GROWTH,
             TOLERATE_DUPLICATES,
             XMLConstants.USE_CATALOG,
@@ -270,9 +337,19 @@
         setFeature(SCHEMA_FULL_CHECKING, false);
         setFeature(DYNAMIC_VALIDATION, false);
         setFeature(NORMALIZE_DATA, false);
+        setFeature(SCHEMA_ELEMENT_DEFAULT, false);
         setFeature(XERCES_NAMESPACES, true);
         setFeature(SEND_PSVI, true);
+        setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false);
+        setFeature(VALIDATE_ANNOTATIONS, false);
+        setFeature(HONOUR_ALL_SCHEMALOCATIONS, false);
+        setFeature(USE_GRAMMAR_POOL_ONLY, false);
+        setFeature(DISALLOW_DOCTYPE_DECL_FEATURE, false);
+        setFeature(BALANCE_SYNTAX_TREES, false);
+        setFeature(WARN_ON_DUPLICATE_ATTDEF, false);
+        setFeature(PARSER_SETTINGS, true);
         setFeature(NAMESPACE_GROWTH, false);
+        setFeature(TOLERATE_DUPLICATES, false);
         setFeature(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT);
         setFeature(JdkXmlUtils.OVERRIDE_PARSER, JdkXmlUtils.OVERRIDE_PARSER_DEFAULT);
 
@@ -288,6 +365,9 @@
             GRAMMAR_POOL,
             JAXP_SCHEMA_SOURCE,
             JAXP_SCHEMA_LANGUAGE,
+            SCHEMA_LOCATION,
+            SCHEMA_NONS_LOCATION,
+            DTD_VALIDATOR_PROPERTY,
             DTD_VALIDATOR_FACTORY_PROPERTY,
             SCHEMA_DV_FACTORY,
             SECURITY_MANAGER,
@@ -321,7 +401,10 @@
         setProperty(ERROR_REPORTER, fErrorReporter);
         addComponent(fErrorReporter);
 
-        setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, DTDDVFactory.getInstance());
+        fDatatypeValidatorFactory = DTDDVFactory.getInstance();
+        fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
+        fCurrentDVFactory = fDatatypeValidatorFactory;
+        setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory);
 
         XMLEntityManager manager =  new XMLEntityManager();
         setProperty(ENTITY_MANAGER, manager);
@@ -348,8 +431,7 @@
         if (fErrorReporter.getMessageFormatter("http://www.w3.org/TR/xml-schema-1") == null) {
             MessageFormatter xmft = null;
             try {
-               xmft = (MessageFormatter)(
-                    ObjectFactory.newInstance("com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter", true));
+               xmft = new com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter();
             } catch (Exception exception){
             }
 
@@ -396,8 +478,8 @@
      * has ended.  If a client application wants to terminate
      * parsing early, it should throw an exception.
      *
-     * @param source The input source for the top-level of the
-     *               XML document.
+     * @param inputSource The input source for the top-level of the
+     *                    XML document.
      *
      * @exception XNIException Any XNI exception, possibly wrapping
      *                         another exception.
@@ -462,9 +544,7 @@
      *                 uninstall the currently installed resolver.
      */
     public void setEntityResolver(XMLEntityResolver resolver) {
-        if (resolver !=null) {
-            fProperties.put(ENTITY_RESOLVER, resolver);
-        }
+        fProperties.put(ENTITY_RESOLVER, resolver);
     } // setEntityResolver(XMLEntityResolver)
 
     /**
@@ -514,6 +594,26 @@
     } // getErrorHandler():XMLErrorHandler
 
     /**
+     * Returns the state of a feature.
+     *
+     * @param featureId The feature identifier.
+     * @return true if the feature is supported
+     *
+     * @throws XMLConfigurationException Thrown for configuration error.
+     *                                   In general, components should
+     *                                   only throw this exception if
+     *                                   it is <strong>really</strong>
+     *                                   a critical error.
+     */
+    public boolean getFeature(String featureId)
+        throws XMLConfigurationException {
+        if (featureId.equals(PARSER_SETTINGS)) {
+            return true;
+        }
+        return super.getFeature(featureId);
+    }
+
+    /**
      * Set the state of a feature.
      *
      * Set the state of any feature in a SAX2 parser.  The parser
@@ -576,8 +676,8 @@
 
         // REVISIT: Recognizes DOM L3 default features only.
         //          Does not yet recognize Xerces features.
-                if(value instanceof Boolean){
-                        boolean state = ((Boolean)value).booleanValue();
+        if(value instanceof Boolean){
+            boolean state = ((Boolean)value).booleanValue();
 
             if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
                 features = (short) (state ? features | COMMENTS : features & ~COMMENTS);
@@ -625,22 +725,12 @@
                     || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
                     ) {
                 if (state) { // true is not supported
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "FEATURE_NOT_SUPPORTED",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+                    throw newFeatureNotSupportedError(name);
                 }
             }
                         else if ( name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
                 if (!state) { // false is not supported
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "FEATURE_NOT_SUPPORTED",
-                            new Object[] { name });
-                   throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+                    throw newFeatureNotSupportedError(name);
                 }
             }
             else if (name.equalsIgnoreCase(SEND_PSVI) ){
@@ -648,12 +738,7 @@
                 // because in this case we won't be able to retrieve element
                 // default value.
                 if (!state) { // false is not supported
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "FEATURE_NOT_SUPPORTED",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+                    throw newFeatureNotSupportedError(name);
                 }
             }
             else if (name.equalsIgnoreCase(Constants.DOM_PSVI)){
@@ -673,23 +758,16 @@
 
         }
 
-                if (!found || !(value instanceof Boolean))  { // set properties
-                        found = true;
+        if (!found || !(value instanceof Boolean))  { // set properties
+                found = true;
 
             if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
                 if (value instanceof DOMErrorHandler || value == null) {
                     fErrorHandlerWrapper.setErrorHandler((DOMErrorHandler)value);
                     setErrorHandler(fErrorHandlerWrapper);
                 }
-
                 else {
-                    // REVISIT: type mismatch
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
             }
             else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) {
@@ -700,36 +778,45 @@
                     catch (XMLConfigurationException e) {}
                 }
                 else {
-                    // REVISIT: type mismatch
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
-
             }
             else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) {
                 if (value instanceof String || value == null) {
                     try {
-                        // map DOM schema-location to JAXP schemaSource property
-                        setProperty(
-                            Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
-                            value);
+                        if (value == null) {
+                            fSchemaLocation = null;
+                            setProperty (
+                                Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
+                                null);
+                        }
+                        else {
+                            fSchemaLocation = (String) value;
+                            // map DOM schema-location to JAXP schemaSource property
+                            // tokenize location string
+                            StringTokenizer t = new StringTokenizer(fSchemaLocation, " \n\t\r");
+                            if (t.hasMoreTokens()) {
+                                List<String> locations = new ArrayList<>();
+                                locations.add(t.nextToken());
+                                while (t.hasMoreTokens()) {
+                                    locations.add (t.nextToken());
+                                }
+                                setProperty (
+                                    Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
+                                    locations.toArray(new String[locations.size()]));
+                            }
+                            else {
+                                setProperty (
+                                    Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE,
+                                    new String [] {(String) value});
+                            }
+                        }
                     }
                     catch (XMLConfigurationException e) {}
                 }
                 else {
-                    // REVISIT: type mismatch
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
-
             }
             else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
                 if (value instanceof String || value == null) {
@@ -754,57 +841,43 @@
                     catch (XMLConfigurationException e) {}
                 }
                 else {
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
-
             }
-            else if (name.equalsIgnoreCase(SYMBOL_TABLE)){
+            else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) {
+                if (value instanceof XMLEntityResolver || value == null) {
+                    try {
+                        setEntityResolver((XMLEntityResolver) value);
+                    }
+                    catch (XMLConfigurationException e) {}
+                }
+                else {
+                    throw newTypeMismatchError(name);
+                }
+            }
+            else if (name.equalsIgnoreCase(SYMBOL_TABLE)) {
                 // Xerces Symbol Table
                 if (value instanceof SymbolTable){
                     setProperty(SYMBOL_TABLE, value);
                 }
                 else {
-                    // REVISIT: type mismatch
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
             }
-            else if (name.equalsIgnoreCase (GRAMMAR_POOL)){
-                if (value instanceof XMLGrammarPool){
+            else if (name.equalsIgnoreCase (GRAMMAR_POOL)) {
+                if (value instanceof XMLGrammarPool || value == null) {
                     setProperty(GRAMMAR_POOL, value);
                 }
                 else {
-                    // REVISIT: type mismatch
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "TYPE_MISMATCH_ERR",
-                            new Object[] { name });
-                    throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+                    throw newTypeMismatchError(name);
                 }
-
             }
-            else {
+                else {
                 // REVISIT: check if this is a boolean parameter -- type mismatch should be thrown.
                 //parameter is not recognized
-                String msg =
-                    DOMMessageFormatter.formatMessage(
-                        DOMMessageFormatter.DOM_DOMAIN,
-                        "FEATURE_NOT_FOUND",
-                        new Object[] { name });
-                throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+                throw newFeatureNotFoundError(name);
             }
         }
-
     }
 
 
@@ -878,23 +951,23 @@
                         return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE);
                 }
                 else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) {
-                        return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE);
+            return fSchemaLocation;
                 }
-        else if (name.equalsIgnoreCase(SYMBOL_TABLE)){
+        else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) {
+            return getEntityResolver();
+        }
+        else if (name.equalsIgnoreCase(SYMBOL_TABLE)) {
             return getProperty(SYMBOL_TABLE);
         }
-        else if (name.equalsIgnoreCase(GRAMMAR_POOL)){
+        else if (name.equalsIgnoreCase(GRAMMAR_POOL)) {
             return getProperty(GRAMMAR_POOL);
         }
+        else if (name.equalsIgnoreCase(SECURITY_MANAGER)) {
+            return getProperty(SECURITY_MANAGER);
+        }
                 else {
-                        String msg =
-                                DOMMessageFormatter.formatMessage(
-                                        DOMMessageFormatter.DOM_DOMAIN,
-                                        "FEATURE_NOT_FOUND",
-                                        new Object[] { name });
-                        throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
+                    throw newFeatureNotFoundError(name);
                 }
-
         }
 
     /**
@@ -966,15 +1039,19 @@
         }
         else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
             // REVISIT: should null value be supported?
-            //as of now we are only supporting W3C XML Schema
-            return ( (value instanceof String) && value.equals(Constants.NS_XMLSCHEMA) ) ? true : false ;
+            // as of now we are only supporting W3C XML Schema and DTD.
+            return ((value instanceof String) &&
+                    (value.equals(Constants.NS_XMLSCHEMA) || value.equals(Constants.NS_DTD))) ? true : false;
         }
-        else if (name.equalsIgnoreCase(SYMBOL_TABLE)){
+        else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) {
+            return (value instanceof XMLEntityResolver) ? true : false;
+        }
+        else if (name.equalsIgnoreCase(SYMBOL_TABLE)) {
             // Xerces Symbol Table
-            return (value instanceof SymbolTable) ? true : false ;
+            return (value instanceof SymbolTable) ? true : false;
         }
-        else if (name.equalsIgnoreCase (GRAMMAR_POOL)){
-            return (value instanceof XMLGrammarPool) ? true : false ;
+        else if (name.equalsIgnoreCase (GRAMMAR_POOL)) {
+            return (value instanceof XMLGrammarPool) ? true : false;
         }
         else {
             //false if the parameter is not recognized or the requested value is not supported.
@@ -991,46 +1068,49 @@
      * can be set by the application. Note that this list can also contain
      * parameter names defined outside this specification.
      */
-    public DOMStringList getParameterNames() {
-        if (fRecognizedParameters == null){
+        public DOMStringList getParameterNames() {
+            if (fRecognizedParameters == null){
             List<String> parameters = new ArrayList<>();
 
-            //Add DOM recognized parameters
-            //REVISIT: Would have been nice to have a list of
-            //recognized paramters.
-            parameters.add(Constants.DOM_COMMENTS);
-            parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
-            parameters.add(Constants.DOM_CDATA_SECTIONS);
-            parameters.add(Constants.DOM_ENTITIES);
-            parameters.add(Constants.DOM_SPLIT_CDATA);
-            parameters.add(Constants.DOM_NAMESPACES);
-            parameters.add(Constants.DOM_VALIDATE);
+                //Add DOM recognized parameters
+                //REVISIT: Would have been nice to have a list of
+                //recognized paramters.
+                parameters.add(Constants.DOM_COMMENTS);
+                parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
+                parameters.add(Constants.DOM_CDATA_SECTIONS);
+                parameters.add(Constants.DOM_ENTITIES);
+                parameters.add(Constants.DOM_SPLIT_CDATA);
+                parameters.add(Constants.DOM_NAMESPACES);
+                parameters.add(Constants.DOM_VALIDATE);
 
-            parameters.add(Constants.DOM_INFOSET);
-            parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
-            parameters.add(Constants.DOM_CANONICAL_FORM);
-            parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
-            parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
-            parameters.add(Constants.DOM_WELLFORMED);
+                parameters.add(Constants.DOM_INFOSET);
+                parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
+                parameters.add(Constants.DOM_CANONICAL_FORM);
+                parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
+                parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
+                parameters.add(Constants.DOM_WELLFORMED);
 
-            parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
-            parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
+                parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
+                parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
 
-            parameters.add(Constants.DOM_ERROR_HANDLER);
-            parameters.add(Constants.DOM_SCHEMA_TYPE);
-            parameters.add(Constants.DOM_SCHEMA_LOCATION);
-            parameters.add(Constants.DOM_RESOURCE_RESOLVER);
+                parameters.add(Constants.DOM_ERROR_HANDLER);
+                parameters.add(Constants.DOM_SCHEMA_TYPE);
+                parameters.add(Constants.DOM_SCHEMA_LOCATION);
+                parameters.add(Constants.DOM_RESOURCE_RESOLVER);
 
-            //Add recognized xerces features and properties
-            parameters.add(GRAMMAR_POOL);
-            parameters.add(SYMBOL_TABLE);
-            parameters.add(SEND_PSVI);
+                //Add recognized xerces features and properties
+                parameters.add(ENTITY_RESOLVER);
+                parameters.add(GRAMMAR_POOL);
+                parameters.add(SECURITY_MANAGER);
+                parameters.add(SYMBOL_TABLE);
+                parameters.add(SEND_PSVI);
 
-            fRecognizedParameters = new DOMStringListImpl(parameters);
-        }
+                fRecognizedParameters = new DOMStringListImpl(parameters);
 
-        return fRecognizedParameters;
-    }//getParameterNames
+            }
+
+            return fRecognizedParameters;
+        }//getParameterNames
 
     //
     // Protected methods
@@ -1061,6 +1141,7 @@
      * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the
      *            requested feature is not known or supported.
      */
+    @Override
     protected PropertyState checkProperty(String propertyId)
         throws XMLConfigurationException {
 
@@ -1115,4 +1196,44 @@
         return new ValidationManager();
     }
 
-} // class XMLParser
+    protected final void setDTDValidatorFactory(String version) {
+        if ("1.1".equals(version)) {
+            if (fCurrentDVFactory != fXML11DatatypeFactory) {
+                fCurrentDVFactory = fXML11DatatypeFactory;
+                setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory);
+            }
+        }
+        else if (fCurrentDVFactory != fDatatypeValidatorFactory) {
+            fCurrentDVFactory = fDatatypeValidatorFactory;
+            setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory);
+        }
+    }
+
+    private static DOMException newFeatureNotSupportedError(String name) {
+        String msg =
+            DOMMessageFormatter.formatMessage(
+                DOMMessageFormatter.DOM_DOMAIN,
+                "FEATURE_NOT_SUPPORTED",
+                new Object[] { name });
+        return new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
+    }
+
+    private static DOMException newFeatureNotFoundError(String name) {
+        String msg =
+            DOMMessageFormatter.formatMessage(
+                DOMMessageFormatter.DOM_DOMAIN,
+                "FEATURE_NOT_FOUND",
+                new Object[] { name });
+        return new DOMException(DOMException.NOT_FOUND_ERR, msg);
+    }
+
+    private static DOMException newTypeMismatchError(String name) {
+        String msg =
+            DOMMessageFormatter.formatMessage(
+                DOMMessageFormatter.DOM_DOMAIN,
+                "TYPE_MISMATCH_ERR",
+                new Object[] { name });
+        return new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
+    }
+
+} // class DOMConfigurationImpl
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -22,21 +22,17 @@
 
 
 
-import com.sun.org.apache.xerces.internal.dom.AbortException;
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
-import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
-import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
+import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader;
 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator;
 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
-import com.sun.org.apache.xerces.internal.parsers.XMLGrammarPreparser;
 import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
 import com.sun.org.apache.xerces.internal.util.XML11Char;
 import com.sun.org.apache.xerces.internal.util.XMLChar;
-import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
 import com.sun.org.apache.xerces.internal.xni.Augmentations;
 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
@@ -48,15 +44,12 @@
 import com.sun.org.apache.xerces.internal.xni.XMLString;
 import com.sun.org.apache.xerces.internal.xni.XNIException;
 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
-import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
 import java.io.IOException;
-import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
@@ -96,7 +89,7 @@
  *
  * @author Elena Litani, IBM
  * @author Neeraj Bajaj, Sun Microsystems, inc.
- * @LastModified: Nov 2017
+ * @LastModified: Apr 2019
  */
 public class DOMNormalizer implements XMLDocumentHandler {
 
@@ -155,7 +148,7 @@
 
     /** for setting the PSVI */
     protected Node fCurrentNode = null;
-    private QName fAttrQName = new QName();
+    private final QName fAttrQName = new QName();
 
     // attribute value normalization
     final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0);
@@ -163,8 +156,11 @@
     //DTD validator
     private XMLDTDValidator fDTDValidator;
 
-    //Check if element content is all "ignorable whitespace"
-    private boolean allWhitespace = false;
+    /** Empty string to pass to the validator. **/
+    public static final XMLString EMPTY_STRING = new XMLString();
+
+    // Check if element content is all "ignorable whitespace"
+    private boolean fAllWhitespace = false;
 
     // Constructor
     //
@@ -177,24 +173,30 @@
      * Normalizes document.
      * Note: reset() must be called before this method.
      */
-        protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) {
+    protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) {
 
-                fDocument = document;
-                fConfiguration = config;
+        fDocument = document;
+        fConfiguration = config;
+        fAllWhitespace = false;
+        fNamespaceValidation = false;
 
-                // intialize and reset DOMNormalizer component
-                //
-                fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
-                // reset namespace context
-                fNamespaceContext.reset();
-                fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
+        String xmlVersion = fDocument.getXmlVersion();
+        String schemaType = null;
+        String [] schemaLocations = null;
 
-                if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
+        // intialize and reset DOMNormalizer component
+        //
+        fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
+        // reset namespace context
+        fNamespaceContext.reset();
+        fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, null);
+
+        if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
             String schemaLang = (String)fConfiguration.getProperty(DOMConfigurationImpl.JAXP_SCHEMA_LANGUAGE);
 
-            if(schemaLang != null && schemaLang.equals(Constants.NS_XMLSCHEMA)) {
-                        fValidationHandler =
-                                CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA);
+            if (schemaLang != null && schemaLang.equals(Constants.NS_XMLSCHEMA)) {
+                schemaType = XMLGrammarDescription.XML_SCHEMA;
+                fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(schemaType, xmlVersion);
                 fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true);
                 fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA_FULL_CHECKING, true);
                 // report fatal error on DOM Level 1 nodes
@@ -203,49 +205,74 @@
                 // check if we need to fill in PSVI
                 fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false;
             }
+            else {
+                schemaType = XMLGrammarDescription.XML_DTD;
+                if (schemaLang != null) {
+                    schemaLocations = (String []) fConfiguration.getProperty(DOMConfigurationImpl.JAXP_SCHEMA_SOURCE);
+                }
+                fConfiguration.setDTDValidatorFactory(xmlVersion);
+                fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(schemaType, xmlVersion);
+                fPSVI = false;
+            }
 
-                        fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
+            fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
 
             // reset ID table
             fDocument.clearIdentifiers();
 
-            if(fValidationHandler != null)
-            // reset schema validator
+            if (fValidationHandler != null) {
+                // reset the validation handler
                 ((XMLComponent) fValidationHandler).reset(fConfiguration);
-
-                }
-
-                fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
-                if (fValidationHandler != null) {
-                        fValidationHandler.setDocumentHandler(this);
-                        fValidationHandler.startDocument(
-                    new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI,
-                                                -1, -1 ), fDocument.encoding, fNamespaceContext, null);
-
-                }
-                try {
-                        Node kid, next;
-                        for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
-                                next = kid.getNextSibling();
-                                kid = normalizeNode(kid);
-                                if (kid != null) { // don't advance
-                                        next = kid;
-                                }
-                        }
-
-                        // release resources
-                        if (fValidationHandler != null) {
-                                fValidationHandler.endDocument(null);
-                                CoreDOMImplementationImpl.singleton.releaseValidator(
-                                        XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
-                                fValidationHandler = null;
-                        }
-                } catch (AbortException e) {
-                    return;
-                }
-
+            }
+        }
+        else {
+            fValidationHandler = null;
         }
 
+        fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
+        if (fValidationHandler != null) {
+            fValidationHandler.setDocumentHandler(this);
+            fValidationHandler.startDocument(
+                    new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI,
+                            -1, -1 ), fDocument.encoding, fNamespaceContext, null);
+            fValidationHandler.xmlDecl(fDocument.getXmlVersion(),
+                    fDocument.getXmlEncoding(), fDocument.getXmlStandalone() ? "yes" : "no", null);
+        }
+        try {
+            if (schemaType == XMLGrammarDescription.XML_DTD) {
+                processDTD(xmlVersion, schemaLocations != null ? schemaLocations[0] : null);
+            }
+
+            Node kid, next;
+            for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
+                next = kid.getNextSibling();
+                kid = normalizeNode(kid);
+                if (kid != null) { // don't advance
+                    next = kid;
+                }
+            }
+
+            // release resources
+            if (fValidationHandler != null) {
+                fValidationHandler.endDocument(null);
+                fValidationHandler.setDocumentHandler(null);
+                CoreDOMImplementationImpl.singleton.releaseValidator(schemaType, xmlVersion, fValidationHandler);
+                fValidationHandler = null;
+            }
+        }
+        catch (RuntimeException e) {
+            // release resources
+            if (fValidationHandler != null) {
+                fValidationHandler.setDocumentHandler(null);
+                CoreDOMImplementationImpl.singleton.releaseValidator(schemaType, xmlVersion, fValidationHandler);
+                fValidationHandler = null;
+            }
+            if (e instanceof AbortException) {
+                return; // processing aborted by the user
+            }
+            throw e; // otherwise re-throw.
+        }
+    }
 
     /**
      *
@@ -273,16 +300,7 @@
                 if (DEBUG_ND) {
                     System.out.println("==>normalizeNode:{doctype}");
                 }
-                DocumentTypeImpl docType = (DocumentTypeImpl)node;
-                fDTDValidator = (XMLDTDValidator)CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_DTD);
-                fDTDValidator.setDocumentHandler(this);
-                fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, createGrammarPool(docType));
-                fDTDValidator.reset(fConfiguration);
-                fDTDValidator.startDocument(
-                        new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI,
-                            -1, -1 ), fDocument.encoding, fNamespaceContext, null);
-                fDTDValidator.doctypeDecl(docType.getName(), docType.getPublicId(), docType.getSystemId(), null);
-                //REVISIT: well-formness encoding info
+                // REVISIT: well-formedness encoding info
                 break;
             }
 
@@ -297,7 +315,7 @@
                     if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
                             fDocument.isXMLVersionChanged()){
                         if (fNamespaceValidation){
-                            wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()) ;
+                            wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version());
                         }
                         else {
                             wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
@@ -329,13 +347,21 @@
                     // remove default attributes
                     namespaceFixUp(elem, attributes);
 
-                    if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0 && attributes != null ) {
-                        for (int i = 0; i < attributes.getLength(); ++i) {
-                            Attr att = (Attr)attributes.getItem(i);
-                            if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) ||
-                                XMLSymbols.PREFIX_XMLNS.equals(att.getName())) {
-                                elem.removeAttributeNode(att);
-                                --i;
+                    if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) {
+                        // Namespace declarations may have been added by namespace fix-up. Need
+                        // to fetch the AttributeMap again if it contained no attributes prior
+                        // to namespace fix-up.
+                        if (attributes == null) {
+                            attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
+                        }
+                        if (attributes != null) {
+                            for (int i = 0; i < attributes.getLength(); ++i) {
+                                Attr att = (Attr)attributes.getItem(i);
+                                if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) ||
+                                        XMLSymbols.PREFIX_XMLNS.equals(att.getName())) {
+                                    elem.removeAttributeNode(att);
+                                    --i;
+                                }
                             }
                         }
                     }
@@ -347,16 +373,21 @@
                             //removeDefault(attr, attributes);
                             attr.normalize();
                             if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
-                                    isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
-                                if (fDocument.isXMLVersionChanged()){
-                                    wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
-                                    if (!wellformed){
-                                                            String msg = DOMMessageFormatter.formatMessage(
-                                                              DOMMessageFormatter.DOM_DOMAIN,
-                                                              "wf-invalid-character-in-node-name",
-                                                               new Object[]{"Attr",node.getNodeName()});
-                                                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
-                                                                "wf-invalid-character-in-node-name");
+                                    isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, attr.getValue(), fDocument.isXML11Version());
+                                if (fDocument.isXMLVersionChanged()) {
+                                    if (fNamespaceValidation){
+                                        wellformed = CoreDocumentImpl.isValidQName(node.getPrefix(), node.getLocalName(), fDocument.isXML11Version());
+                                    }
+                                    else {
+                                        wellformed = CoreDocumentImpl.isXMLName(node.getNodeName(), fDocument.isXML11Version());
+                                    }
+                                    if (!wellformed) {
+                                        String msg = DOMMessageFormatter.formatMessage(
+                                          DOMMessageFormatter.DOM_DOMAIN,
+                                          "wf-invalid-character-in-node-name",
+                                           new Object[]{"Attr",node.getNodeName()});
+                                        reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
+                                            "wf-invalid-character-in-node-name");
                                     }
                                 }
                             }
@@ -379,26 +410,12 @@
                     fValidationHandler.startElement(fQName, fAttrProxy, null);
                 }
 
-                if (fDTDValidator != null) {
-                    // REVISIT: possible solutions to discard default content are:
-                    //         either we pass some flag to XML Schema validator
-                    //         or rely on the PSVI information.
-                    fAttrProxy.setAttributes(attributes, fDocument, elem);
-                    updateQName(elem, fQName); // updates global qname
-                    // set error node in the dom error wrapper
-                    // so if error occurs we can report an error node
-                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
-                    fCurrentNode = node;
-                    // call re-validation handler
-                    fDTDValidator.startElement(fQName, fAttrProxy, null);
-                }
-
                 // normalize children
                 Node kid, next;
                 for (kid = elem.getFirstChild(); kid != null; kid = next) {
                     next = kid.getNextSibling();
                     kid = normalizeNode(kid);
-                    if (kid !=null) {
+                    if (kid != null) {
                         next = kid;  // don't advance
                     }
                 }
@@ -412,7 +429,6 @@
 
                 }
 
-
                 if (fValidationHandler != null) {
                     updateQName(elem, fQName); // updates global qname
                     //
@@ -423,16 +439,6 @@
                     fValidationHandler.endElement(fQName, null);
                 }
 
-                if (fDTDValidator != null) {
-                    updateQName(elem, fQName); // updates global qname
-                    //
-                    // set error node in the dom error wrapper
-                    // so if error occurs we can report an error node
-                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
-                    fCurrentNode = node;
-                    fDTDValidator.endElement(fQName, null);
-                }
-
                 // pop namespace context
                 fNamespaceContext.popContext();
 
@@ -465,6 +471,13 @@
                         // of the document
                         isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version());
                     }
+                    if (fValidationHandler != null) {
+                        // Don't bother filling an XMLString with the text of the comment.
+                        // We only send the comment event to the validator handler so that
+                        // when  the schema-type is DTD an error will be reported for a
+                        // comment appearing in EMPTY content.
+                        fValidationHandler.comment(EMPTY_STRING, null);
+                    }
                 }//end-else if comment node is not to be removed.
                                 break;
             }
@@ -531,16 +544,6 @@
                     fValidationHandler.characterData(node.getNodeValue(), null);
                     fValidationHandler.endCDATA(null);
                 }
-
-                if (fDTDValidator != null) {
-                    // set error node in the dom error wrapper
-                    // so if error occurs we can report an error node
-                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
-                    fCurrentNode = node;
-                    fDTDValidator.startCDATA(null);
-                    fDTDValidator.characterData(node.getNodeValue(), null);
-                    fDTDValidator.endCDATA(null);
-                }
                 String value = node.getNodeValue();
 
                 if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
@@ -605,42 +608,37 @@
 
                     short nextType = (next != null)?next.getNodeType():-1;
                     if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 &&
-                           nextType == Node.ENTITY_NODE) ||
-                          ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
-                           nextType == Node.COMMENT_NODE) ||
-                          ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
-                          nextType == Node.CDATA_SECTION_NODE)) {
-                              if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
-                                  isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
-                              }
-                              if (fValidationHandler != null) {
-                                     fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
-                                     fCurrentNode = node;
-                                     fValidationHandler.characterData(node.getNodeValue(), null);
-                                     if (DEBUG_ND) {
-                                         System.out.println("=====>characterData(),"+nextType);
-
-                                     }
-                              }
-                              if (fDTDValidator != null) {
-                                  fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
-                                  fCurrentNode = node;
-                                  fDTDValidator.characterData(node.getNodeValue(), null);
-                                  if (DEBUG_ND) {
-                                      System.out.println("=====>characterData(),"+nextType);
-
-                                  }
-                                  if(allWhitespace) {
-                                      allWhitespace = false;
-                                      ((TextImpl)node).setIgnorableWhitespace(true);
-                                  }
-                              }
+                            nextType == Node.ENTITY_NODE) ||
+                            ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
+                                    nextType == Node.COMMENT_NODE) ||
+                                    ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
+                                    nextType == Node.CDATA_SECTION_NODE)) {
+                        if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
+                            isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
+                        }
+                        if (fValidationHandler != null) {
+                            fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
+                            fCurrentNode = node;
+                            fValidationHandler.characterData(node.getNodeValue(), null);
+                            if (!fNamespaceValidation) {
+                                if (fAllWhitespace) {
+                                    fAllWhitespace = false;
+                                    ((TextImpl)node).setIgnorableWhitespace(true);
+                                }
+                                else {
+                                    ((TextImpl)node).setIgnorableWhitespace(false);
+                                }
+                            }
+                            if (DEBUG_ND) {
+                                System.out.println("=====>characterData(),"+nextType);
+                            }
+                        }
                     }
                     else {
-                            if (DEBUG_ND) {
-                                System.out.println("=====>don't send characters(),"+nextType);
+                        if (DEBUG_ND) {
+                            System.out.println("=====>don't send characters(),"+nextType);
 
-                            }
+                        }
                     }
                 }
                 break;
@@ -674,42 +672,66 @@
                 //which may not be valid XML character
                 isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version());
             }
+
+            if (fValidationHandler != null) {
+                // Don't bother filling an XMLString with the data section of the
+                // processing instruction. We only send the processing instruction
+                // event to the validator handler so that when the schema-type is
+                // DTD an error will be reported for a processing instruction
+                // appearing in EMPTY content.
+                fValidationHandler.processingInstruction(((ProcessingInstruction) node).getTarget(), EMPTY_STRING, null);
+            }
         }//end case Node.PROCESSING_INSTRUCTION_NODE
 
         }//end of switch
         return null;
     }//normalizeNode
 
-    private XMLGrammarPool createGrammarPool(DocumentTypeImpl docType) {
-
-        XMLGrammarPoolImpl pool = new XMLGrammarPoolImpl();
+    private void processDTD(String xmlVersion, String schemaLocation) {
 
-        XMLGrammarPreparser preParser = new XMLGrammarPreparser(fSymbolTable);
-        preParser.registerPreparser(XMLGrammarDescription.XML_DTD, null);
-        preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE, true);
-        preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATION_FEATURE, true);
-        preParser.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, pool);
+        String rootName = null;
+        String publicId = null;
+        String systemId = schemaLocation;
+        String baseSystemId = fDocument.getDocumentURI();
+        String internalSubset = null;
 
-        String internalSubset = docType.getInternalSubset();
-        XMLInputSource is = new XMLInputSource(docType.getPublicId(), docType.getSystemId(), null, false);
-
-        if(internalSubset != null)
-            is.setCharacterStream(new StringReader(internalSubset));
-        try {
-            DTDGrammar g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is);
-            ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName());
-            is.setCharacterStream(null);
-            g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is);
-            ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName());
-
-        } catch (XNIException e) {
-        } catch (IOException e) {
+        DocumentType docType = fDocument.getDoctype();
+        if (docType != null) {
+            rootName = docType.getName();
+            publicId = docType.getPublicId();
+            if (systemId == null || systemId.length() == 0) {
+                systemId = docType.getSystemId();
+            }
+            internalSubset = docType.getInternalSubset();
+        }
+        // If the DOM doesn't have a DocumentType node we may still
+        // be able to fetch a DTD if the application provided a URI
+        else {
+            Element elem = fDocument.getDocumentElement();
+            if (elem == null) return;
+            rootName = elem.getNodeName();
+            if (systemId == null || systemId.length() == 0) return;
         }
 
-        return pool;
-    }
-
-
+        XMLDTDLoader loader = null;
+        try {
+            fValidationHandler.doctypeDecl(rootName, publicId, systemId, null);
+            loader = CoreDOMImplementationImpl.singleton.getDTDLoader(xmlVersion);
+            loader.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
+            loader.setEntityResolver(fConfiguration.getEntityResolver());
+            loader.setErrorHandler(fConfiguration.getErrorHandler());
+            loader.loadGrammarWithContext((XMLDTDValidator) fValidationHandler, rootName,
+                    publicId, systemId, baseSystemId, internalSubset);
+        }
+        // REVISIT: Should probably report this exception to the error handler.
+        catch (IOException e) {
+        }
+        finally {
+            if (loader != null) {
+                CoreDOMImplementationImpl.singleton.releaseDTDLoader(xmlVersion, loader);
+            }
+        }
+    } // processDTD(String, String)
 
     protected final void expandEntityRef (Node parent, Node reference){
         Node kid, next;
@@ -740,30 +762,15 @@
         //
         // ------------------------------------
 
-        String value, name, uri, prefix;
+        String value, uri, prefix;
         if (attributes != null) {
 
             // Record all valid local declarations
             for (int k = 0; k < attributes.getLength(); ++k) {
                 Attr attr = (Attr)attributes.getItem(k);
-
-                //do the name check only when version of the document was changed &
-                //application has set the value of well-formed features to true
-                if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
-                    fDocument.isXMLVersionChanged()) {
-                    //checkQName does checking based on the version of the document
-                    fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ;
-                }
-
                 uri = attr.getNamespaceURI();
                 if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
                     // namespace attribute
-
-                    // "namespace-declarations" == false; Discard all namespace declaration attributes
-                    if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) {
-                        continue;
-                    }
-
                     value = attr.getNodeValue();
                     if (value == null) {
                         value=XMLSymbols.EMPTY_STRING;
@@ -798,7 +805,7 @@
                         } else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol)  -- xmlns
                             // empty prefix is always bound ("" or some string)
                             value = fSymbolTable.addSymbol(value);
-                            fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value);
+                            fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value.length() != 0 ? value : null);
                             //removeDefault (attr, attributes);
                             continue;
                         }
@@ -826,12 +833,7 @@
 
         uri = element.getNamespaceURI();
         prefix = element.getPrefix();
-
-        // "namespace-declarations" == false? Discard all namespace declaration attributes
-        if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) {
-            // no namespace declaration == no namespace URI, semantics are to keep prefix
-            uri = null;
-        } else if (uri != null) {  // Element has a namespace
+        if (uri != null) {  // Element has a namespace
             uri = fSymbolTable.addSymbol(uri);
             prefix = (prefix == null ||
                       prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
@@ -870,8 +872,8 @@
                     // undeclare default namespace declaration (before that element
                     // bound to non-zero length uir), but adding xmlns="" decl
                     addNamespaceDecl (XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING, element);
-                    fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
-                    fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
+                    fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, null);
+                    fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, null);
                 }
             }
         }
@@ -894,12 +896,35 @@
                 // normalize attribute value
                 attr.normalize();
                 value = attr.getValue();
-                name = attr.getNodeName();
                 uri = attr.getNamespaceURI();
 
                 // make sure that value is never null.
                 if (value == null) {
-                    value=XMLSymbols.EMPTY_STRING;
+                    value = XMLSymbols.EMPTY_STRING;
+                }
+
+                //---------------------------------------
+                // check if value of the attribute is namespace well-formed
+                //---------------------------------------
+                if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) {
+                    isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, value, fDocument.isXML11Version());
+                    if (fDocument.isXMLVersionChanged()) {
+                        boolean wellformed;
+                        if (fNamespaceValidation){
+                            wellformed = CoreDocumentImpl.isValidQName(attr.getPrefix(), attr.getLocalName(), fDocument.isXML11Version());
+                        }
+                        else {
+                            wellformed = CoreDocumentImpl.isXMLName(attr.getNodeName(), fDocument.isXML11Version());
+                        }
+                        if (!wellformed) {
+                            String msg = DOMMessageFormatter.formatMessage(
+                                    DOMMessageFormatter.DOM_DOMAIN,
+                                    "wf-invalid-character-in-node-name",
+                                    new Object[]{"Attr", attr.getNodeName()});
+                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
+                            "wf-invalid-character-in-node-name");
+                        }
+                    }
                 }
 
                 if (uri != null) {  // attribute has namespace !=null
@@ -916,23 +941,6 @@
                     if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
                         continue;
                     }
-                    //---------------------------------------
-                    // check if value of the attribute is namespace well-formed
-                    //---------------------------------------
-                    if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) {
-                            isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
-                            if (fDocument.isXMLVersionChanged()){
-                                boolean wellformed=CoreDocumentImpl.isXMLName(attr.getNodeName() , fDocument.isXML11Version());
-                                if (!wellformed){
-                                                        String msg = DOMMessageFormatter.formatMessage(
-                                                            DOMMessageFormatter.DOM_DOMAIN,
-                                                            "wf-invalid-character-in-node-name",
-                                                            new Object[]{"Attribute", attr.getNodeName()});
-                                        reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
-                                            "wf-invalid-character-in-node-name");
-                                }
-                        }
-                    }
 
                     // ---------------------------------------
                     // remove default attributes
@@ -948,7 +956,6 @@
                     // reset id-attributes
                     ((AttrImpl)attr).setIdAttribute(false);
 
-
                     uri = fSymbolTable.addSymbol(uri);
 
                     // find if for this prefix a URI was already declared
@@ -962,7 +969,6 @@
                         // conflict: attribute has a prefix that conficlicts with a binding
                         //           already active in scope
 
-                        name  = attr.getNodeName();
                         // Find if any prefix for attributes namespace URI is available
                         // in the scope
                         String declaredPrefix = fNamespaceContext.getPrefix(uri);
@@ -1447,8 +1453,8 @@
         protected CoreDocumentImpl fDocument;
         protected ElementImpl fElement;
 
-        protected final Vector<Augmentations> fAugmentations = new Vector<>(5);
-
+        protected Vector<String> fDTDTypes = new Vector<>(5);
+        protected Vector<Augmentations> fAugmentations = new Vector<>(5);
 
         public void setAttributes(AttributeMap attributes, CoreDocumentImpl doc, ElementImpl elem) {
             fDocument = doc;
@@ -1456,7 +1462,7 @@
             fElement = elem;
             if (attributes != null) {
                 int length = attributes.getLength();
-
+                fDTDTypes.setSize(length);
                 fAugmentations.setSize(length);
                 // REVISIT: this implementation does not store any value in augmentations
                 //          and basically not keeping augs in parallel to attributes map
@@ -1464,34 +1470,37 @@
                 for (int i = 0; i < length; i++) {
                     fAugmentations.setElementAt(new AugmentationsImpl(), i);
                 }
-            } else {
+            }
+            else {
+                fDTDTypes.setSize(0);
                 fAugmentations.setSize(0);
             }
         }
 
 
-                /**
+        /**
          * This method adds default declarations
                  * @see com.sun.org.apache.xerces.internal.xni.XMLAttributes#addAttribute(QName, String, String)
-                 */
-                public int addAttribute(QName qname, String attrType, String attrValue) {
-                        int index = fElement.getXercesAttribute(qname.uri, qname.localpart);
-                        // add defaults to the tree
-                        if (index < 0) {
+         */
+        public int addAttribute(QName qname, String attrType, String attrValue) {
+            int index = fElement.getXercesAttribute(qname.uri, qname.localpart);
+            // add defaults to the tree
+            if (index < 0) {
                 // the default attribute was removed by a user and needed to
                 // be added back
-                                AttrImpl attr = (AttrImpl)
-                                        ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS(
-                                                qname.uri,
-                                                qname.rawname,
-                                                qname.localpart);
+                AttrImpl attr = (AttrImpl)
+                    ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS(
+                        qname.uri,
+                        qname.rawname,
+                        qname.localpart);
                 // REVISIT: the following should also update ID table
                 attr.setNodeValue(attrValue);
                 index = fElement.setXercesAttributeNode(attr);
+                fDTDTypes.insertElementAt(attrType, index);
                 fAugmentations.insertElementAt(new AugmentationsImpl(), index);
                 attr.setSpecified(false);
-                        }
-                        else {
+            }
+            else {
                 // default attribute is in the tree
                 // we don't need to do anything since prefix was already fixed
                 // at the namespace fixup time and value must be same value, otherwise
@@ -1500,7 +1509,7 @@
 
             }
             return index;
-                }
+        }
 
 
         public void removeAllAttributes(){
@@ -1523,41 +1532,58 @@
             return -1;
         }
 
-        public int getIndex(String uri, String localPart){
+        public int getIndex(String uri, String localPart) {
             // REVISIT: implement
             return -1;
         }
 
-        public void setName(int attrIndex, QName attrName){
+        public void setName(int attrIndex, QName attrName) {
             // REVISIT: implement
         }
 
-        public void getName(int attrIndex, QName attrName){
-            if (fAttributes !=null) {
+        public void getName(int attrIndex, QName attrName) {
+            if (fAttributes != null) {
                 updateQName((Node)fAttributes.getItem(attrIndex), attrName);
             }
         }
 
-        public String getPrefix(int index){
-            // REVISIT: implement
+        public String getPrefix(int index) {
+            if (fAttributes != null) {
+                Node node = (Node) fAttributes.getItem(index);
+                String prefix = node.getPrefix();
+                prefix = (prefix != null && prefix.length() != 0) ? fSymbolTable.addSymbol(prefix) : null;
+                return prefix;
+            }
+            return null;
+        }
+
+        public String getURI(int index) {
+            if (fAttributes != null) {
+                Node node = (Node) fAttributes.getItem(index);
+                String namespace = node.getNamespaceURI();
+                namespace = (namespace != null) ? fSymbolTable.addSymbol(namespace) : null;
+                return namespace;
+            }
             return null;
         }
 
 
-        public String getURI(int index){
-            // REVISIT: implement
+        public String getLocalName(int index) {
+            if (fAttributes != null) {
+                Node node = (Node) fAttributes.getItem(index);
+                String localName = node.getLocalName();
+                localName = (localName != null) ? fSymbolTable.addSymbol(localName) : null;
+                return localName;
+            }
             return null;
         }
 
-
-        public String getLocalName(int index){
-            // REVISIT: implement
-            return null;
-        }
-
-
-        public String getQName(int index){
-            // REVISIT: implement
+        public String getQName(int index) {
+            if (fAttributes != null) {
+                Node node = (Node) fAttributes.getItem(index);
+                String rawname = fSymbolTable.addSymbol(node.getNodeName());
+                return rawname;
+            }
             return null;
         }
 
@@ -1566,27 +1592,31 @@
             return null;
         }
 
-        public void setType(int attrIndex, String attrType){
-            // REVISIT: implement
+        public void setType(int attrIndex, String attrType) {
+            fDTDTypes.setElementAt(attrType, attrIndex);
         }
 
+        public String getType(int index) {
+            String type = fDTDTypes.elementAt(index);
+            return (type != null) ? getReportableType(type) : "CDATA";
+        }
 
-        public String getType(int index){
+        public String getType(String qName) {
             return "CDATA";
         }
 
-
-        public String getType(String qName){
+        public String getType(String uri, String localName) {
             return "CDATA";
         }
 
-
-        public String getType(String uri, String localName){
-            return "CDATA";
+        private String getReportableType(String type) {
+            if (type.charAt(0) == '(') {
+                return "NMTOKEN";
+            }
+            return type;
         }
 
-
-        public void setValue(int attrIndex, String attrValue){
+        public void setValue(int attrIndex, String attrValue) {
             // REVISIT: is this desired behaviour?
             // The values are updated in the case datatype-normalization is turned on
             // in this case we need to make sure that specified attributes stay specified
@@ -1609,13 +1639,11 @@
 
         }
 
-
         public String getValue(String qName){
             // REVISIT: implement
             return null;
         }
 
-
         public String getValue(String uri, String localName){
             if (fAttributes != null) {
                 Node node =  fAttributes.getNamedItemNS(uri, localName);
@@ -1624,19 +1652,16 @@
             return null;
         }
 
-
         public void setNonNormalizedValue(int attrIndex, String attrValue){
             // REVISIT: implement
 
         }
 
-
         public String getNonNormalizedValue(int attrIndex){
             // REVISIT: implement
             return null;
         }
 
-
         public void setSpecified(int attrIndex, boolean specified){
             AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex);
             attr.setSpecified(specified);
@@ -1788,58 +1813,85 @@
      * @exception XNIException
      *                   Thrown by handler to signal an error.
      */
-        public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
-                throws XNIException {
-                Element currentElement = (Element) fCurrentNode;
-                int attrCount = attributes.getLength();
+    public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
+        throws XNIException {
+        Element currentElement = (Element) fCurrentNode;
+        int attrCount = attributes.getLength();
         if (DEBUG_EVENTS) {
             System.out.println("==>startElement: " +element+
-            " attrs.length="+attrCount);
+                    " attrs.length="+attrCount);
         }
 
-                for (int i = 0; i < attrCount; i++) {
-                        attributes.getName(i, fAttrQName);
-                        Attr attr = null;
+        for (int i = 0; i < attrCount; i++) {
+            attributes.getName(i, fAttrQName);
+            Attr attr = null;
 
-                        attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
+            attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
+            if (attr == null) {
+                // Must be a non-namespace aware DOM Level 1 node.
+                attr = currentElement.getAttributeNode(fAttrQName.rawname);
+            }
             AttributePSVI attrPSVI =
-                                (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
+                (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
 
-                        if (attrPSVI != null) {
+            if (attrPSVI != null) {
                 //REVISIT: instead we should be using augmentations:
                 // to set/retrieve Id attributes
                 XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition();
                 boolean id = false;
-                if (decl != null){
+                if (decl != null) {
                     id = ((XSSimpleType)decl).isIDType();
-                } else{
+                }
+                else {
                     decl = attrPSVI.getTypeDefinition();
-                    if (decl !=null){
-                       id = ((XSSimpleType)decl).isIDType();
+                    if (decl != null) {
+                        id = ((XSSimpleType)decl).isIDType();
                     }
                 }
-                if (id){
+                if (id) {
                     ((ElementImpl)currentElement).setIdAttributeNode(attr, true);
                 }
 
-                                if (fPSVI) {
-                                        ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
-                                }
-                                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
-                                        // datatype-normalization
-                                        // NOTE: The specified value MUST be set after we set
-                                        //       the node value because that turns the "specified"
-                                        //       flag to "true" which may overwrite a "false"
-                                        //       value from the attribute list.
-                                        boolean specified = attr.getSpecified();
-                                        attr.setValue(attrPSVI.getSchemaValue().getNormalizedValue());
-                                        if (!specified) {
-                                                ((AttrImpl) attr).setSpecified(specified);
-                                        }
-                                }
+                if (fPSVI) {
+                    ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
+                }
+
+                // Updating the TypeInfo for this attribute.
+                ((AttrImpl) attr).setType(decl);
+
+                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
+                    // datatype-normalization
+                    // NOTE: The specified value MUST be set after we set
+                    //       the node value because that turns the "specified"
+                    //       flag to "true" which may overwrite a "false"
+                    //       value from the attribute list.
+                    final String normalizedValue = attrPSVI.getSchemaValue().getNormalizedValue();
+                    if (normalizedValue != null) {
+                        boolean specified = attr.getSpecified();
+                        attr.setValue(normalizedValue);
+                        if (!specified) {
+                            ((AttrImpl) attr).setSpecified(specified);
                         }
+                    }
                 }
+            }
+            else { // DTD
+                String type = null;
+                boolean isDeclared = Boolean.TRUE.equals(attributes.getAugmentations(i).getItem (Constants.ATTRIBUTE_DECLARED));
+                // For DOM Level 3 TypeInfo, the type name must
+                // be null if this attribute has not been declared
+                // in the DTD.
+                if (isDeclared) {
+                    type = attributes.getType(i);
+                    if ("ID".equals (type)) {
+                        ((ElementImpl) currentElement).setIdAttributeNode(attr, true);
+                    }
+                }
+                // Updating the TypeInfo for this attribute.
+                ((AttrImpl) attr).setType(type);
+            }
         }
+    }
 
 
     /**
@@ -1948,7 +2000,7 @@
      *                   Thrown by handler to signal an error.
      */
     public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException{
-        allWhitespace = true;
+        fAllWhitespace = true;
     }
 
     /**
@@ -1960,38 +2012,51 @@
      * @exception XNIException
      *                   Thrown by handler to signal an error.
      */
-        public void endElement(QName element, Augmentations augs) throws XNIException {
-                if (DEBUG_EVENTS) {
-                        System.out.println("==>endElement: " + element);
-                }
+    public void endElement(QName element, Augmentations augs) throws XNIException {
+        if (DEBUG_EVENTS) {
+            System.out.println("==>endElement: " + element);
+        }
 
-        if(augs != null) {
-                ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
-                if (elementPSVI != null) {
-                        ElementImpl elementNode = (ElementImpl) fCurrentNode;
-                        if (fPSVI) {
-                                ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
-                        }
-                        // include element default content (if one is available)
-                        String normalizedValue = elementPSVI.getSchemaValue().getNormalizedValue();
-                        if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
+        if (augs != null) {
+            ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
+            if (elementPSVI != null) {
+                ElementImpl elementNode = (ElementImpl) fCurrentNode;
+                if (fPSVI) {
+                    ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
+                }
+                // Updating the TypeInfo for this element.
+                if (elementNode instanceof ElementNSImpl) {
+                    XSTypeDefinition type = elementPSVI.getMemberTypeDefinition();
+                    if (type == null) {
+                        type = elementPSVI.getTypeDefinition();
+                    }
+                    ((ElementNSImpl) elementNode).setType(type);
+                }
+                // include element default content (if one is available)
+                String normalizedValue = elementPSVI.getSchemaValue().getNormalizedValue();
+                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
                     if (normalizedValue !=null)
-                                    elementNode.setTextContent(normalizedValue);
-                        }
-                        else {
-                                // NOTE: this is a hack: it is possible that DOM had an empty element
-                                // and validator sent default value using characters(), which we don't
-                                // implement. Thus, here we attempt to add the default value.
-                                String text = elementNode.getTextContent();
-                                if (text.length() == 0) {
-                                        // default content could be provided
+                        elementNode.setTextContent(normalizedValue);
+                }
+                else {
+                    // NOTE: this is a hack: it is possible that DOM had an empty element
+                    // and validator sent default value using characters(), which we don't
+                    // implement. Thus, here we attempt to add the default value.
+                    String text = elementNode.getTextContent();
+                    if (text.length() == 0) {
+                        // default content could be provided
                         if (normalizedValue !=null)
                             elementNode.setTextContent(normalizedValue);
-                                }
-                        }
+                    }
                 }
+                return;
+            }
         }
+        // DTD; elements have no type.
+        if (fCurrentNode instanceof ElementNSImpl) {
+            ((ElementNSImpl) fCurrentNode).setType(null);
         }
+    }
 
 
     /**
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -69,7 +69,7 @@
     // protected
 
     /** Chunk shift. */
-    protected static final int CHUNK_SHIFT = 8;           // 2^8 = 256
+    protected static final int CHUNK_SHIFT = 11;           // 2^11 = 2k
 
     /** Chunk size. */
     protected static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
@@ -78,7 +78,7 @@
     protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
 
     /** Initial chunk size. */
-    protected static final int INITIAL_CHUNK_COUNT = (1 << (13 - CHUNK_SHIFT));   // 32
+    protected static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT));   // 2^16 = 64k
 
     //
     // Data
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -56,6 +56,7 @@
  * @author Joe Kesselman, IBM
  * @author Andy Clark, IBM
  * @since  PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  */
 public class DocumentTypeImpl
     extends ParentNode
@@ -324,7 +325,7 @@
                 Node entNode2 =
                     argEntities.getNamedItem(entNode1.getNodeName());
 
-                if (!((NodeImpl) entNode1).isEqualNode((NodeImpl) entNode2))
+                if (!((NodeImpl) entNode1).isEqualNode(entNode2))
                     return false;
             }
         }
@@ -344,7 +345,7 @@
                 Node noteNode2 =
                     argNotations.getNamedItem(noteNode1.getNodeName());
 
-                if (!((NodeImpl) noteNode1).isEqualNode((NodeImpl) noteNode2))
+                if (!((NodeImpl) noteNode1).isEqualNode(noteNode2))
                     return false;
             }
         }
@@ -357,7 +358,7 @@
      * NON-DOM
      * set the ownerDocument of this node and its children
      */
-    void setOwnerDocument(CoreDocumentImpl doc) {
+    protected void setOwnerDocument(CoreDocumentImpl doc) {
         super.setOwnerDocument(doc);
         entities.setOwnerDocument(doc);
         notations.setOwnerDocument(doc);
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -55,38 +54,33 @@
  * @author Andy Clark, IBM
  * @author Ralf Pfeiffer, IBM
  * @since PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  */
 public class ElementImpl
-        extends ParentNode
-        implements Element, ElementTraversal, TypeInfo {
+    extends ParentNode
+    implements Element, ElementTraversal, TypeInfo {
 
     //
     // Constants
     //
-    /**
-     * Serialization version.
-     */
+
+    /** Serialization version. */
     static final long serialVersionUID = 3717253516652722278L;
     //
     // Data
     //
 
-    /**
-     * Element name.
-     */
+    /** Element name. */
     protected String name;
 
-    /**
-     * Attributes.
-     */
+    /** Attributes. */
     protected AttributeMap attributes;
 
     //
     // Constructors
     //
-    /**
-     * Factory constructor.
-     */
+
+    /** Factory constructor. */
     public ElementImpl(CoreDocumentImpl ownerDoc, String name) {
         super(ownerDoc);
         this.name = name;
@@ -94,8 +88,7 @@
     }
 
     // for ElementNSImpl
-    protected ElementImpl() {
-    }
+    protected ElementImpl() {}
 
     // Support for DOM Level 3 renameNode method.
     // Note: This only deals with part of the pb. CoreDocumentImpl
@@ -109,9 +102,9 @@
             if (colon1 != -1) {
                 String msg
                         = DOMMessageFormatter.formatMessage(
-                                DOMMessageFormatter.DOM_DOMAIN,
-                                "NAMESPACE_ERR",
-                                null);
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "NAMESPACE_ERR",
+                            null);
                 throw new DOMException(DOMException.NAMESPACE_ERR, msg);
             }
             if (!CoreDocumentImpl.isXMLName(name, ownerDocument.isXML11Version())) {
@@ -287,7 +280,7 @@
         if (attributes == null) {
             return "";
         }
-        Attr attr = (Attr) (attributes.getNamedItem(name));
+        Attr attr = (Attr)(attributes.getNamedItem(name));
         return (attr == null) ? "" : attr.getValue();
 
     } // getAttribute(String):String
@@ -307,7 +300,7 @@
         if (attributes == null) {
             return null;
         }
-        return (Attr) attributes.getNamedItem(name);
+        return (Attr)attributes.getNamedItem(name);
 
     } // getAttributeNode(String):Attr
 
@@ -453,7 +446,7 @@
      * readonly.
      */
     public Attr removeAttributeNode(Attr oldAttr)
-            throws DOMException {
+        throws DOMException {
 
         if (ownerDocument.errorChecking && isReadOnly()) {
             String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
@@ -491,36 +484,35 @@
      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
      * readonly.
      */
-    public void setAttribute(String name, String value) {
+        public void setAttribute(String name, String value) {
 
-        if (ownerDocument.errorChecking && isReadOnly()) {
-            String msg
-                    = DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "NO_MODIFICATION_ALLOWED_ERR",
-                            null);
-            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
-        }
+                if (ownerDocument.errorChecking && isReadOnly()) {
+                    String msg = DOMMessageFormatter.formatMessage(
+                                        DOMMessageFormatter.DOM_DOMAIN,
+                                        "NO_MODIFICATION_ALLOWED_ERR",
+                                        null);
+                    throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
+                }
 
-        if (needsSyncData()) {
-            synchronizeData();
-        }
+                if (needsSyncData()) {
+                        synchronizeData();
+                }
 
-        Attr newAttr = getAttributeNode(name);
-        if (newAttr == null) {
-            newAttr = getOwnerDocument().createAttribute(name);
+                Attr newAttr = getAttributeNode(name);
+                if (newAttr == null) {
+                        newAttr = getOwnerDocument().createAttribute(name);
 
-            if (attributes == null) {
-                attributes = new AttributeMap(this, null);
-            }
+                        if (attributes == null) {
+                                attributes = new AttributeMap(this, null);
+                        }
 
-            newAttr.setNodeValue(value);
-            attributes.setNamedItem(newAttr);
-        } else {
-            newAttr.setNodeValue(value);
-        }
+                        newAttr.setNodeValue(value);
+                        attributes.setNamedItem(newAttr);
+                } else {
+                        newAttr.setNodeValue(value);
+                }
 
-    } // setAttribute(String,String)
+        } // setAttribute(String,String)
 
     /**
      * Add a new attribute/value pair, or replace the value of the existing
@@ -546,13 +538,13 @@
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                        msg);
+                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                                     msg);
             }
 
             if (newAttr.getOwnerDocument() != ownerDocument) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
-                throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
+                    throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
             }
         }
 
@@ -589,7 +581,7 @@
             return "";
         }
 
-        Attr attr = (Attr) (attributes.getNamedItemNS(namespaceURI, localName));
+        Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName));
         return (attr == null) ? "" : attr.getValue();
 
     } // getAttributeNS(String,String):String
@@ -633,41 +625,38 @@
      * @since WD-DOM-Level-2-19990923
      */
     public void setAttributeNS(String namespaceURI, String qualifiedName,
-            String value) {
-        if (ownerDocument.errorChecking && isReadOnly()) {
-            String msg
-                    = DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "NO_MODIFICATION_ALLOWED_ERR",
-                            null);
-            throw new DOMException(
-                    DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                    msg);
-        }
-        if (needsSyncData()) {
-            synchronizeData();
-        }
-        int index = qualifiedName.indexOf(':');
-        String prefix, localName;
-        if (index < 0) {
-            prefix = null;
-            localName = qualifiedName;
-        } else {
-            prefix = qualifiedName.substring(0, index);
-            localName = qualifiedName.substring(index + 1);
-        }
-        Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
-        if (newAttr == null) {
+                                          String value) {
+                if (ownerDocument.errorChecking && isReadOnly()) {
+                    String msg = DOMMessageFormatter.formatMessage(
+                                        DOMMessageFormatter.DOM_DOMAIN,
+                                        "NO_MODIFICATION_ALLOWED_ERR",
+                                        null);
+                    throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
+                }
+                if (needsSyncData()) {
+                        synchronizeData();
+                }
+                int index = qualifiedName.indexOf(':');
+                String prefix, localName;
+                if (index < 0) {
+                        prefix = null;
+                        localName = qualifiedName;
+                } else {
+                        prefix = qualifiedName.substring(0, index);
+                        localName = qualifiedName.substring(index + 1);
+                }
+                Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
+                if (newAttr == null) {
             // REVISIT: this is not efficient, we are creating twice the same
             //          strings for prefix and localName.
-            newAttr = getOwnerDocument().createAttributeNS(
-                    namespaceURI,
-                    qualifiedName);
-            if (attributes == null) {
-                attributes = new AttributeMap(this, null);
-            }
-            newAttr.setNodeValue(value);
-            attributes.setNamedItemNS(newAttr);
+                        newAttr = getOwnerDocument().createAttributeNS(
+                                        namespaceURI,
+                                        qualifiedName);
+                        if (attributes == null) {
+                                attributes = new AttributeMap(this, null);
+                        }
+                        newAttr.setNodeValue(value);
+                        attributes.setNamedItemNS(newAttr);
                 }
                 else {
             if (newAttr instanceof AttrNSImpl){
@@ -693,12 +682,12 @@
                 // This case is not defined by the DOM spec, we choose
                 // to create a new attribute in this case and remove an old one from the tree
                 // note this might cause events to be propagated or user data to be lost
-                newAttr = new AttrNSImpl((CoreDocumentImpl)getOwnerDocument(), namespaceURI, qualifiedName, localName);
+                newAttr = ((CoreDocumentImpl)getOwnerDocument()).createAttributeNS(namespaceURI, qualifiedName, localName);
                 attributes.setNamedItemNS(newAttr);
             }
 
-            newAttr.setNodeValue(value);
-        }
+                        newAttr.setNodeValue(value);
+                }
 
     } // setAttributeNS(String,String,String)
 
@@ -753,7 +742,7 @@
         if (attributes == null) {
             return null;
         }
-        return (Attr) attributes.getNamedItemNS(namespaceURI, localName);
+        return (Attr)attributes.getNamedItemNS(namespaceURI, localName);
 
     } // getAttributeNodeNS(String,String):Attr
 
@@ -788,9 +777,9 @@
         if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
-                throw new DOMException(
-                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                        msg);
+                    throw new DOMException(
+                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                                     msg);
             }
             if (newAttr.getOwnerDocument() != ownerDocument) {
                 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
@@ -807,8 +796,8 @@
     } // setAttributeNodeNS(Attr):Attr
 
     /**
-     * NON-DOM: sets attribute node for this element
-     */
+      * NON-DOM: sets attribute node for this element
+      */
     protected int setXercesAttributeNode(Attr attr) {
 
         if (needsSyncData()) {
@@ -823,8 +812,8 @@
     }
 
     /**
-     * NON-DOM: get inded of an attribute
-     */
+      * NON-DOM: get inded of an attribute
+      */
     protected int getXercesAttribute(String namespaceURI, String localName) {
 
         if (needsSyncData()) {
@@ -879,7 +868,7 @@
      * @since WD-DOM-Level-2-19990923
      */
     public NodeList getElementsByTagNameNS(String namespaceURI,
-            String localName) {
+                                           String localName) {
         return new DeepNodeListImpl(this, namespaceURI, localName);
     }
 
@@ -911,7 +900,7 @@
                     }
                 } else {
                     Node n2 = map2.getNamedItemNS(n1.getNamespaceURI(),
-                            n1.getLocalName());
+                                                  n1.getLocalName());
                     if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
                         return false;
                     }
@@ -930,14 +919,15 @@
         }
         if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                        msg);
+                        DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
             }
 
             if (at.getOwnerElement() != this) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
                 throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
             }
         }
@@ -959,22 +949,21 @@
         Attr at = getAttributeNode(name);
 
         if (at == null) {
-            String msg = DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "NOT_FOUND_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
-        }
+                }
 
         if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
-                throw new DOMException(
-                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                        msg);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
+                throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
             }
 
             if (at.getOwnerElement() != this) {
-                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
                 throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
             }
         }
@@ -991,7 +980,7 @@
      * DOM Level 3: register the given attribute node as an ID attribute
      */
     public void setIdAttributeNS(String namespaceURI, String localName,
-            boolean makeId) {
+                                    boolean makeId) {
         if (needsSyncData()) {
             synchronizeData();
         }
@@ -1002,19 +991,18 @@
         Attr at = getAttributeNodeNS(namespaceURI, localName);
 
         if (at == null) {
-            String msg = DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "NOT_FOUND_ERR", null);
+                String msg = DOMMessageFormatter.formatMessage(
+                        DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
-        }
+                }
 
-        if (ownerDocument.errorChecking) {
+                if (ownerDocument.errorChecking) {
             if (isReadOnly()) {
                 String msg = DOMMessageFormatter.formatMessage(
                         DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                 throw new DOMException(
-                        DOMException.NO_MODIFICATION_ALLOWED_ERR,
-                        msg);
+                                     DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                                     msg);
             }
 
             if (at.getOwnerElement() != this) {
@@ -1029,14 +1017,14 @@
         } else {
             ownerDocument.putIdentifier(at.getValue(), this);
         }
-    }
+   }
 
     /**
      * @see org.w3c.dom.TypeInfo#getTypeName()
      */
-    public String getTypeName() {
+     public String getTypeName() {
         return null;
-    }
+     }
 
     /**
      * @see org.w3c.dom.TypeInfo#getTypeNamespace()
@@ -1059,17 +1047,16 @@
      * reference type
      */
     public boolean isDerivedFrom(String typeNamespaceArg,
-            String typeNameArg,
-            int derivationMethod) {
+                                 String typeNameArg,
+                                 int derivationMethod) {
 
         return false;
     }
 
-    /**
-     * Method getSchemaTypeInfo.
-     *
-     * @return TypeInfo
-     */
+        /**
+         * Method getSchemaTypeInfo.
+         * @return TypeInfo
+         */
     public TypeInfo getSchemaTypeInfo() {
         if (needsSyncData()) {
             synchronizeData();
@@ -1159,8 +1146,7 @@
         if (doctype == null) {
             return null;
         }
-        ElementDefinitionImpl eldef
-                = (ElementDefinitionImpl) doctype.getElements()
+        ElementDefinitionImpl eldef = (ElementDefinitionImpl)doctype.getElements()
                 .getNamedItem(getNodeName());
         if (eldef == null) {
             return null;
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -86,13 +86,13 @@
 
         private void setName(String namespaceURI, String qname) {
 
-                String prefix;
-                // DOM Level 3: namespace URI is never empty string.
-                this.namespaceURI = namespaceURI;
-                if (namespaceURI != null) {
+            String prefix;
+            // DOM Level 3: namespace URI is never empty string.
+            this.namespaceURI = namespaceURI;
+            if (namespaceURI != null) {
             //convert the empty string to 'null'
-                        this.namespaceURI =     (namespaceURI.length() == 0) ? null : namespaceURI;
-                }
+            this.namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI;
+            }
 
         int colon1, colon2 ;
 
@@ -190,37 +190,6 @@
         reconcileDefaultAttributes();
     }
 
-    /**
-     * NON-DOM: resets this node and sets specified values for the node
-     *
-     * @param ownerDocument
-     * @param namespaceURI
-     * @param qualifiedName
-     * @param localName
-     */
-    protected void setValues (CoreDocumentImpl ownerDocument,
-                            String namespaceURI, String qualifiedName,
-                            String localName){
-
-        // remove children first
-        firstChild = null;
-        previousSibling = null;
-        nextSibling = null;
-        fNodeListCache = null;
-
-        // set owner document
-        attributes = null;
-        super.flags = 0;
-        setOwnerDocument(ownerDocument);
-
-        // synchronizeData will initialize attributes
-        needsSyncData(true);
-        super.name = qualifiedName;
-        this.localName = localName;
-        this.namespaceURI = namespaceURI;
-
-    }
-
     //
     // Node methods
     //
@@ -340,88 +309,13 @@
         return localName;
     }
 
-
-   /**
-     * DOM Level 3 WD - Experimental.
-     * Retrieve baseURI
+    /**
+     * NON-DOM
+     * Returns the xml:base attribute.
      */
-    public String getBaseURI() {
-
-        if (needsSyncData()) {
-            synchronizeData();
-        }
-        // Absolute base URI is computed according to XML Base (http://www.w3.org/TR/xmlbase/#granularity)
-
-        // 1.  the base URI specified by an xml:base attribute on the element, if one exists
-
-        if (attributes != null) {
-            Attr attrNode = (Attr)attributes.getNamedItemNS("http://www.w3.org/XML/1998/namespace", "base");
-            if (attrNode != null) {
-                String uri =  attrNode.getNodeValue();
-                if (uri.length() != 0 ) {// attribute value is always empty string
-                    try {
-                        uri = new URI(uri).toString();
-                    }
-                    catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e) {
-                        // This may be a relative URI.
-
-                        // Start from the base URI of the parent, or if this node has no parent, the owner node.
-                        NodeImpl parentOrOwner = (parentNode() != null) ? parentNode() : ownerNode;
-
-                        // Make any parentURI into a URI object to use with the URI(URI, String) constructor.
-                        String parentBaseURI = (parentOrOwner != null) ? parentOrOwner.getBaseURI() : null;
-
-                        if (parentBaseURI != null) {
-                            try {
-                                uri = new URI(new URI(parentBaseURI), uri).toString();
-                            }
-                            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex){
-                                // This should never happen: parent should have checked the URI and returned null if invalid.
-                                return null;
-                            }
-                            return uri;
-                        }
-                        // REVISIT: what should happen in this case?
-                        return null;
-                    }
-                    return uri;
-                }
-            }
-        }
-
-        //2.the base URI of the element's parent element within the document or external entity,
-        //if one exists
-        String parentElementBaseURI = (this.parentNode() != null) ? this.parentNode().getBaseURI() : null ;
-        //base URI of parent element is not null
-        if(parentElementBaseURI != null){
-            try {
-                //return valid absolute base URI
-               return new URI(parentElementBaseURI).toString();
-            }
-            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){
-                // REVISIT: what should happen in this case?
-                return null;
-            }
-        }
-        //3. the base URI of the document entity or external entity containing the element
-
-        String baseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null ;
-
-        if(baseURI != null){
-            try {
-                //return valid absolute base URI
-               return new URI(baseURI).toString();
-            }
-            catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){
-                // REVISIT: what should happen in this case?
-                return null;
-            }
-        }
-
-        return null;
-
-    }
-
+    protected Attr getXMLBaseAttribute() {
+        return (Attr) attributes.getNamedItemNS("http://www.w3.org/XML/1998/namespace", "base");
+    } // getXMLBaseAttribute():Attr
 
     /**
      * @see org.w3c.dom.TypeInfo#getTypeName()
@@ -452,12 +346,12 @@
      * Checks if a type is derived from another by restriction. See:
      * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom
      *
-     * @param ancestorNS
+     * @param typeNamespaceArg
      *        The namspace of the ancestor type declaration
-     * @param ancestorName
+     * @param typeNameArg
      *        The name of the ancestor type declaration
-     * @param type
-     *        The reference type definition
+     * @param derivationMethod
+     *        The derivation method
      *
      * @return boolean True if the type is derived by restriciton for the
      *         reference type
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
  */
  /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,6 +27,7 @@
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -78,6 +79,7 @@
  * @author Arnaud  Le Hors, IBM
  * @author Joe Kesselman, IBM
  * @since  PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  */
 public abstract class NodeImpl
     implements Node, NodeList, EventTarget, Cloneable, Serializable{
@@ -122,15 +124,6 @@
      */
     public static final short TREE_POSITION_DISCONNECTED = 0x00;
 
-
-    // DocumentPosition
-    public static final short DOCUMENT_POSITION_DISCONNECTED = 0x01;
-    public static final short DOCUMENT_POSITION_PRECEDING = 0x02;
-    public static final short DOCUMENT_POSITION_FOLLOWING = 0x04;
-    public static final short DOCUMENT_POSITION_CONTAINS = 0x08;
-    public static final short DOCUMENT_POSITION_IS_CONTAINED = 0x10;
-    public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
-
     /** Serialization version. */
     static final long serialVersionUID = -6316591992167219696L;
 
@@ -324,7 +317,7 @@
      * NON-DOM
      * set the ownerDocument of this node
      */
-    void setOwnerDocument(CoreDocumentImpl doc) {
+    protected void setOwnerDocument(CoreDocumentImpl doc) {
         if (needsSyncData()) {
             synchronizeData();
         }
@@ -559,7 +552,7 @@
      * @see ParentNode
      *
      * @return org.w3c.dom.Node
-     * @param Index int
+     * @param index int
      */
     public Node item(int index) {
         return null;
@@ -976,9 +969,7 @@
           return 0;
 
         // check if other is from a different implementation
-        try {
-            NodeImpl node = (NodeImpl) other;
-        } catch (ClassCastException e) {
+        if (other != null && !(other instanceof NodeImpl)) {
             // other comes from a different implementation
             String msg = DOMMessageFormatter.formatMessage(
                DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
@@ -1041,7 +1032,7 @@
             otherDepth +=1;
             if (node == this)
               // The other node is a descendent of the reference node.
-              return (DOCUMENT_POSITION_IS_CONTAINED |
+              return (DOCUMENT_POSITION_CONTAINED_BY |
                       DOCUMENT_POSITION_FOLLOWING);
             otherAncestor = node;
         }
@@ -1131,7 +1122,7 @@
           case Node.NOTATION_NODE:
           case Node.ENTITY_NODE: {
           DocumentType container = thisOwnerDoc.getDoctype();
-            if (container == this) return (DOCUMENT_POSITION_IS_CONTAINED |
+            if (container == this) return (DOCUMENT_POSITION_CONTAINED_BY |
                                           DOCUMENT_POSITION_FOLLOWING);
             otherNode = otherAncestor = thisOwnerDoc;
             break;
@@ -1139,7 +1130,7 @@
           case Node.DOCUMENT_TYPE_NODE: {
             if (thisNode == otherOwnerDoc)
               return (DOCUMENT_POSITION_FOLLOWING |
-                      DOCUMENT_POSITION_IS_CONTAINED);
+                      DOCUMENT_POSITION_CONTAINED_BY);
             else if (otherOwnerDoc!=null && thisOwnerDoc==otherOwnerDoc)
               return (DOCUMENT_POSITION_PRECEDING);
             break;
@@ -1153,7 +1144,7 @@
                   // The other node is a descendent of the reference
                   // node's element
                   return DOCUMENT_POSITION_FOLLOWING |
-                         DOCUMENT_POSITION_IS_CONTAINED;
+                         DOCUMENT_POSITION_CONTAINED_BY;
                 otherAncestor = node;
             }
 
@@ -1302,8 +1293,8 @@
         return getNodeValue();  // overriden in some subclasses
     }
 
-    // internal method taking a StringBuffer in parameter
-    void getTextContent(StringBuffer buf) throws DOMException {
+    // internal method taking a StringBuilder in parameter
+    void getTextContent(StringBuilder buf) throws DOMException {
         String content = getNodeValue();
         if (content != null) {
             buf.append(content);
@@ -1425,7 +1416,11 @@
             return false;
         }
         case Node.DOCUMENT_NODE:{
-                return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
+                Element docElement = ((Document)this).getDocumentElement();
+                if (docElement != null) {
+                    return docElement.isDefaultNamespace(namespaceURI);
+                }
+                return false;
             }
 
         case Node.ENTITY_NODE :
@@ -1475,12 +1470,15 @@
 
         switch (type) {
         case Node.ELEMENT_NODE: {
-
-                String namespace = this.getNamespaceURI(); // to flip out children
+                this.getNamespaceURI(); // to flip out children
                 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
             }
         case Node.DOCUMENT_NODE:{
-                return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
+                Element docElement = ((Document)this).getDocumentElement();
+                if (docElement != null) {
+                    return docElement.lookupPrefix(namespaceURI);
+                }
+                return null;
             }
 
         case Node.ENTITY_NODE :
@@ -1511,8 +1509,8 @@
      * Look up the namespace URI associated to the given prefix, starting from this node.
      * Use lookupNamespaceURI(null) to lookup the default namespace
      *
-     * @param namespaceURI
-     * @return th URI for the namespace
+     * @param specifiedPrefix
+     * @return the URI for the namespace
      * @since DOM Level 3
      */
     public String lookupNamespaceURI(String specifiedPrefix) {
@@ -1537,20 +1535,20 @@
                     int length = map.getLength();
                     for (int i=0;i<length;i++) {
                         Node attr = map.item(i);
-                        String attrPrefix = attr.getPrefix();
-                        String value = attr.getNodeValue();
                         namespace = attr.getNamespaceURI();
                         if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
+                            String attrPrefix = attr.getPrefix();
+                            String value = attr.getNodeValue();
                             // at this point we are dealing with DOM Level 2 nodes only
                             if (specifiedPrefix == null &&
                                 attr.getNodeName().equals("xmlns")) {
                                 // default namespace
-                                return value;
+                                return value.length() > 0 ? value : null;
                             } else if (attrPrefix !=null &&
                                        attrPrefix.equals("xmlns") &&
                                        attr.getLocalName().equals(specifiedPrefix)) {
                                 // non default namespace
-                                return value;
+                                return value.length() > 0 ? value : null;
                             }
                         }
                     }
@@ -1565,7 +1563,11 @@
 
             }
         case Node.DOCUMENT_NODE : {
-                return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix);
+                Element docElement = ((Document)this).getDocumentElement();
+                if (docElement != null) {
+                    return docElement.lookupNamespaceURI(specifiedPrefix);
+                }
+                return null;
             }
         case Node.ENTITY_NODE :
         case Node.NOTATION_NODE:
@@ -1591,15 +1593,14 @@
         }
     }
 
-
-    Node getElementAncestor (Node currentNode){
+    Node getElementAncestor(Node currentNode) {
         Node parent = currentNode.getParentNode();
-        if (parent != null) {
+        while (parent != null) {
             short type = parent.getNodeType();
             if (type == Node.ELEMENT_NODE) {
                 return parent;
             }
-            return getElementAncestor(parent);
+            parent = parent.getParentNode();
         }
         return null;
     }
@@ -1624,10 +1625,10 @@
             int length = map.getLength();
             for (int i=0;i<length;i++) {
                 Node attr = map.item(i);
-                String attrPrefix = attr.getPrefix();
-                String value = attr.getNodeValue();
                 namespace = attr.getNamespaceURI();
                 if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
+                    String attrPrefix = attr.getPrefix();
+                    String value = attr.getNodeValue();
                     // DOM Level 2 nodes
                     if (((attr.getNodeName().equals("xmlns")) ||
                          (attrPrefix !=null && attrPrefix.equals("xmlns")) &&
@@ -1687,9 +1688,6 @@
      * <code>Text</code> nodes, as well as any user data or event listeners
      * registered on the nodes.
      * @param arg The node to compare equality with.
-     * @param deep If <code>true</code>, recursively compare the subtrees; if
-     *   <code>false</code>, compare only the nodes themselves (and its
-     *   attributes, if it is an <code>Element</code>).
      * @return If the nodes, and possibly subtrees are equal,
      *   <code>true</code> otherwise <code>false</code>.
      * @since DOM Level 3
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -21,11 +21,8 @@
 
 package com.sun.org.apache.xerces.internal.dom;
 
-import org.w3c.dom.DOMException;
 import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
 import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
 
 /**
  * The DOMImplementation class is description of a particular
@@ -40,7 +37,7 @@
  *
  * @since  PR-DOM-Level-1-19980818.
  */
-public class PSVIDOMImplementationImpl extends CoreDOMImplementationImpl {
+public class PSVIDOMImplementationImpl extends DOMImplementationImpl {
 
     //
     // Data
@@ -49,7 +46,7 @@
     // static
 
     /** Dom implementation singleton. */
-    static PSVIDOMImplementationImpl singleton = new PSVIDOMImplementationImpl();
+    static final PSVIDOMImplementationImpl singleton = new PSVIDOMImplementationImpl();
 
     //
     // Public methods
@@ -84,42 +81,12 @@
                feature.equalsIgnoreCase("psvi");
     } // hasFeature(String,String):boolean
 
-    /**
-     * Introduced in DOM Level 2. <p>
-     *
-     * Creates an XML Document object of the specified type with its document
-     * element.
-     *
-     * @param namespaceURI     The namespace URI of the document
-     *                         element to create, or null.
-     * @param qualifiedName    The qualified name of the document
-     *                         element to create.
-     * @param doctype          The type of document to be created or null.<p>
-     *
-     *                         When doctype is not null, its
-     *                         Node.ownerDocument attribute is set to
-     *                         the document being created.
-     * @return Document        A new Document object.
-     * @throws DOMException    WRONG_DOCUMENT_ERR: Raised if doctype has
-     *                         already been used with a different document.
-     * @since WD-DOM-Level-2-19990923
-     */
-    public Document           createDocument(String namespaceURI,
-                                             String qualifiedName,
-                                             DocumentType doctype)
-                                             throws DOMException
-    {
-        if (doctype != null && doctype.getOwnerDocument() != null) {
-            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
-                                   DOMMessageFormatter.formatMessage(
-                                   DOMMessageFormatter.XML_DOMAIN,
-                                                       "WRONG_DOCUMENT_ERR", null));
-        }
-        DocumentImpl doc = new PSVIDocumentImpl(doctype);
-        Element e = doc.createElementNS( namespaceURI, qualifiedName);
-        doc.appendChild(e);
-        return doc;
+    //
+    // Protected methods
+    //
+
+    protected CoreDocumentImpl createDocument(DocumentType doctype) {
+        return new PSVIDocumentImpl(doctype);
     }
 
-
-} // class DOMImplementationImpl
+} // class PSVIDOMImplementationImpl
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -68,6 +68,7 @@
  * @author Arnaud  Le Hors, IBM
  * @author Joe Kesselman, IBM
  * @author Andy Clark, IBM
+ * @LastModified: Apr 2019
  */
 public abstract class ParentNode
     extends ChildNode {
@@ -174,18 +175,16 @@
      * NON-DOM
      * set the ownerDocument of this node and its children
      */
-    void setOwnerDocument(CoreDocumentImpl doc) {
+    protected void setOwnerDocument(CoreDocumentImpl doc) {
         if (needsSyncChildren()) {
             synchronizeChildren();
         }
-       for (ChildNode child = firstChild;
-             child != null; child = child.nextSibling) {
-             child.setOwnerDocument(doc);
-        }
-        /* setting the owner document of self, after it's children makes the
-           data of children available to the new document. */
         super.setOwnerDocument(doc);
         ownerDocument = doc;
+        for (ChildNode child = firstChild;
+        child != null; child = child.nextSibling) {
+            child.setOwnerDocument(doc);
+        }
     }
 
     /**
@@ -368,16 +367,14 @@
             // Prevent cycles in the tree
             // newChild cannot be ancestor of this Node,
             // and actually cannot be this
-            if (ownerDocument.ancestorChecking) {
-                boolean treeSafe = true;
-                for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode())
-                {
-                    treeSafe = newChild != a;
-                }
-                if(!treeSafe) {
-                    throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
-                                DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null));
-                }
+            boolean treeSafe = true;
+            for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode())
+            {
+                treeSafe = newChild != a;
+            }
+            if(!treeSafe) {
+                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+                            DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null));
             }
         }
 
@@ -509,6 +506,9 @@
         // notify document
         ownerDocument.removingNode(this, oldInternal, replace);
 
+        // Save previous sibling for normalization checking.
+        final ChildNode oldPreviousSibling = oldInternal.previousSibling();
+
         // update cached length if we have any
         if (fNodeListCache != null) {
             if (fNodeListCache.fLength != -1) {
@@ -519,7 +519,7 @@
                 // move the cache to its (soon former) previous sibling
                 if (fNodeListCache.fChild == oldInternal) {
                     fNodeListCache.fChildIndex--;
-                    fNodeListCache.fChild = oldInternal.previousSibling();
+                    fNodeListCache.fChild = oldPreviousSibling;
                 } else {
                     // otherwise just invalidate the cache
                     fNodeListCache.fChildIndex = -1;
@@ -550,9 +550,6 @@
             }
         }
 
-        // Save previous sibling for normalization checking.
-        ChildNode oldPreviousSibling = oldInternal.previousSibling();
-
         // Remove oldInternal's references to tree
         oldInternal.ownerNode       = ownerDocument;
         oldInternal.isOwned(false);
@@ -624,20 +621,15 @@
             if (next == null) {
                 return hasTextContent(child) ? ((NodeImpl) child).getTextContent() : "";
             }
-            if (fBufferStr == null){
-                fBufferStr = new StringBuffer();
-            }
-            else {
-                fBufferStr.setLength(0);
-            }
-            getTextContent(fBufferStr);
-            return fBufferStr.toString();
+            StringBuilder buf = new StringBuilder();
+            getTextContent(buf);
+            return buf.toString();
         }
         return "";
     }
 
-    // internal method taking a StringBuffer in parameter
-    void getTextContent(StringBuffer buf) throws DOMException {
+    // internal method taking a StringBuilder in parameter
+    void getTextContent(StringBuilder buf) throws DOMException {
         Node child = getFirstChild();
         while (child != null) {
             if (hasTextContent(child)) {
@@ -684,6 +676,9 @@
     private int nodeListGetLength() {
 
         if (fNodeListCache == null) {
+            if (needsSyncChildren()) {
+                synchronizeChildren();
+            }
             // get rid of trivial cases
             if (firstChild == null) {
                 return 0;
@@ -733,6 +728,9 @@
     private Node nodeListItem(int index) {
 
         if (fNodeListCache == null) {
+            if (needsSyncChildren()) {
+                synchronizeChildren();
+            }
             // get rid of trivial case
             if (firstChild == lastChild()) {
                 return index == 0 ? firstChild : null;
@@ -870,7 +868,7 @@
         Node child1 = getFirstChild();
         Node child2 = arg.getFirstChild();
         while (child1 != null && child2 != null) {
-            if (!((NodeImpl) child1).isEqualNode(child2)) {
+            if (!child1.isEqualNode(child2)) {
                 return false;
             }
             child1 = child1.getNextSibling();
@@ -997,7 +995,7 @@
     /** Serialize object. */
     private void writeObject(ObjectOutputStream out) throws IOException {
 
-        // synchronize chilren
+        // synchronize children
         if (needsSyncChildren()) {
             synchronizeChildren();
         }
@@ -1022,7 +1020,7 @@
     /*
      * a class to store some user data along with its handler
      */
-    protected class UserDataRecord implements Serializable {
+    class UserDataRecord implements Serializable {
         /** Serialization version. */
         private static final long serialVersionUID = 3258126977134310455L;
 
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -42,6 +41,7 @@
  * @xerces.internal
  *
  * @since  PR-DOM-Level-1-19980818.
+ * @LastModified: Apr 2019
  */
 public class TextImpl
     extends CharacterDataImpl
@@ -146,37 +146,32 @@
             synchronizeData();
         }
 
-        if (fBufferStr == null){
-            fBufferStr = new StringBuffer();
-        }
-        else {
-            fBufferStr.setLength(0);
-        }
+        StringBuilder buffer = new StringBuilder();
         if (data != null && data.length() != 0) {
-            fBufferStr.append(data);
+            buffer.append(data);
         }
 
-        //concatenate text of logically adjacent text nodes to the left of this node in the tree
-        getWholeTextBackward(this.getPreviousSibling(), fBufferStr, this.getParentNode());
-        String temp = fBufferStr.toString();
+        // concatenate text of logically adjacent text nodes to the left of this node in the tree
+        getWholeTextBackward(this.getPreviousSibling(), buffer, this.getParentNode());
+        String temp = buffer.toString();
 
-        //clear buffer
-        fBufferStr.setLength(0);
+        // clear buffer
+        buffer.setLength(0);
 
-        //concatenate text of logically adjacent text nodes to the right of this node in the tree
-        getWholeTextForward(this.getNextSibling(), fBufferStr, this.getParentNode());
+        // concatenate text of logically adjacent text nodes to the right of this node in the tree
+        getWholeTextForward(this.getNextSibling(), buffer, this.getParentNode());
 
-        return temp + fBufferStr.toString();
+        return temp + buffer.toString();
 
     }
 
     /**
-     * internal method taking a StringBuffer in parameter and inserts the
+     * internal method taking a StringBuilder in parameter and inserts the
      * text content at the start of the buffer
      *
      * @param buf
      */
-    protected void insertTextContent(StringBuffer buf) throws DOMException {
+    protected void insertTextContent(StringBuilder buf) throws DOMException {
          String content = getNodeValue();
          if (content != null) {
              buf.insert(0, content);
@@ -193,7 +188,7 @@
      *         other than EntityRef, Text, CDATA is encountered, otherwise
      *         return false
      */
-    private boolean getWholeTextForward(Node node, StringBuffer buffer, Node parent){
+    private boolean getWholeTextForward(Node node, StringBuilder buffer, Node parent){
         // boolean to indicate whether node is a child of an entity reference
         boolean inEntRef = false;
 
@@ -240,7 +235,7 @@
      *         other than EntityRef, Text, CDATA is encountered, otherwise
      *         return false
      */
-    private boolean getWholeTextBackward(Node node, StringBuffer buffer, Node parent){
+    private boolean getWholeTextBackward(Node node, StringBuilder buffer, Node parent){
 
         // boolean to indicate whether node is a child of an entity reference
         boolean inEntRef = false;
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,11 +23,11 @@
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * This class implements the basic operations for managing parser
@@ -42,6 +42,7 @@
  *
  * @author Andy Clark, IBM
  *
+ * @LastModified: Apr 2019
  */
 public class ParserConfigurationSettings
     implements XMLComponentManager {
@@ -56,13 +57,13 @@
     // data
 
     /** Recognized properties. */
-    protected Set<String> fRecognizedProperties;
+    protected List<String> fRecognizedProperties;
 
     /** Properties. */
     protected Map<String, Object> fProperties;
 
     /** Recognized features. */
-    protected Set<String> fRecognizedFeatures;
+    protected List<String> fRecognizedFeatures;
 
     /** Features. */
     protected Map<String, Boolean> fFeatures;
@@ -86,8 +87,8 @@
     public ParserConfigurationSettings(XMLComponentManager parent) {
 
         // create storage for recognized features and properties
-        fRecognizedFeatures = new HashSet<>();
-        fRecognizedProperties = new HashSet<>();
+        fRecognizedFeatures = new ArrayList<>();
+        fRecognizedProperties = new ArrayList<>();
 
         // create table for features and properties
         fFeatures = new HashMap<>();
@@ -195,7 +196,7 @@
      *                                   a critical error.
      */
     @Override
-    public final boolean getFeature(String featureId)
+    public boolean getFeature(String featureId)
         throws XMLConfigurationException {
 
         FeatureState state = getFeatureState(featureId);
@@ -222,7 +223,7 @@
             FeatureState checkState = checkFeature(featureId);
             if (checkState.isExceptional()) {
                 return checkState;
-            }
+        }
             return FeatureState.is(false);
         }
         return FeatureState.is(state);
@@ -241,7 +242,7 @@
      *                                   a critical error.
      */
     @Override
-    public final Object getProperty(String propertyId)
+    public Object getProperty(String propertyId)
         throws XMLConfigurationException {
 
         PropertyState state = getPropertyState(propertyId);
@@ -270,7 +271,7 @@
             PropertyState state = checkProperty(propertyId);
             if (state.isExceptional()) {
                 return state;
-            }
+        }
         }
 
         return PropertyState.is(propertyValue);
@@ -325,7 +326,7 @@
                 PropertyState state = fParentSettings.getPropertyState(propertyId);
                 if (state.isExceptional()) {
                     return state;
-                }
+            }
             }
             else {
                 return PropertyState.NOT_RECOGNIZED;
--- a/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java	Tue Apr 16 13:16:49 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java	Thu Apr 25 15:54:21 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,12 @@
  */
 package dom;
 
+import com.sun.org.apache.xerces.internal.dom.AttrImpl;
+import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
+import com.sun.org.apache.xerces.internal.dom.ElementImpl;
+import com.sun.org.apache.xerces.internal.dom.events.MutationEventImpl;
+import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -33,20 +37,24 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventListener;
 
 /*
  * @test
- * @bug 8213117
+ * @bug 8213117 8222743
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @modules java.xml
+ * @modules java.xml/com.sun.org.apache.xerces.internal.dom
+ * @modules java.xml/com.sun.org.apache.xerces.internal.dom.events
+ * @modules java.xml/com.sun.org.apache.xerces.internal.jaxp
  * @run testng dom.DocumentTest
  * @summary Tests functionalities for Document.
  */
 @Listeners({jaxp.library.BasePolicy.class})
 public class DocumentTest {
-
-    private static final String XML1 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>";
-    private static final String XML2 = "<root><newNode newAttrib=\"new value\"></newNode></root>";
+    static final int DOC1 = 1;
+    static final int DOC2 = 2;
 
     /**
      * Verifies the adoptNode method. Before a node from a deferred DOM can be
@@ -54,12 +62,11 @@
      */
     @Test
     public void testAdoptNode() throws Exception {
+        String xml1 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>";
+        String xml2 = "<root><newNode newAttrib=\"new value\"></newNode></root>";
 
-        DocumentBuilder builder = DocumentBuilderFactory.newInstance()
-                .newDocumentBuilder();
-
-        Document doc1 = getDocument(builder, XML1);
-        Document doc2 = getDocument(builder, XML2);
+        Document doc1 = getDocument(xml1);
+        Document doc2 = getDocument(xml2);
 
         Element newNode = (Element) doc2.getFirstChild().getFirstChild();
         Element replacementNode = (Element) doc1.adoptNode(newNode);
@@ -72,10 +79,118 @@
         Assert.assertEquals(attrValue, "new value");
     }
 
-    private static Document getDocument(DocumentBuilder builder, String xml) throws SAXException, IOException {
+    /**
+     * Verifies that the lookupNamespaceURI method returns null (not empty string)
+     * for unbound prefix.
+     *
+     * Specification for lookupNamespaceURI:
+     * Returns the associated namespace URI or null if none is found.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testUnboundNamespaceURI() throws Exception {
+        String xml = "<?xml version='1.1'?>"
+                + "<root><e1 xmlns='' xmlns:p1='' xmlns:p2='uri2'><e2/></e1></root>";
+
+        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        Document doc = getDocument(xml);
+        Element e1 = doc.getDocumentElement();
+        Element e2 = (Element)e1.getFirstChild().getFirstChild();
+
+        Assert.assertEquals(e1.lookupNamespaceURI(null), null);
+        Assert.assertEquals(e2.lookupNamespaceURI(null), null);
+
+        Assert.assertEquals(e1.lookupNamespaceURI("p1"), null);
+        Assert.assertEquals(e2.lookupNamespaceURI("p1"), null);
+
+        Assert.assertEquals(e1.lookupNamespaceURI("p2"), null);
+        Assert.assertEquals(e2.lookupNamespaceURI("p2"), "uri2");
+    }
+
+    /**
+     * Verifies that calling namespace methods on an empty document won't result
+     * in a NPE.
+     * @throws Exception
+     */
+    @Test
+    public void testNamespaceNPE() throws Exception {
+        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+        document.lookupNamespaceURI("prefix");
+        document.lookupPrefix("uri");
+        document.isDefaultNamespace("uri");
+    }
+
+    /**
+     * Verifies that manipulating an independent document from within a mutation
+     * listener does not modify the original event object.
+     */
+    @Test
+    public void testMutation() throws Exception {
+        String xml1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                + "<root><a a_attr=\"a_attr_value\"/></root>";
+        String xml2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                + "<root><b b_attr=\"b_attr_value\"/></root>";
+        DocumentBuilder db = DocumentBuilderFactoryImpl.newInstance().newDocumentBuilder();
+        DocumentImpl doc1 = (DocumentImpl)getDocument(xml1);
+        DocumentImpl doc2 = (DocumentImpl)getDocument(xml2);
+        ElementImpl a = (ElementImpl) doc1.getDocumentElement().getFirstChild();
+        AttrImpl attr = (AttrImpl) a.getAttributeNode("a_attr");
+        attr.addEventListener(MutationEventImpl.DOM_NODE_REMOVED, new MyEventListener(DOC1, doc2), false);
+        doc2.addEventListener(MutationEventImpl.DOM_ATTR_MODIFIED, new MyEventListener(DOC2), true);
+
+        // make a change to doc1 to trigger the event
+        Element a1 = (Element) doc1.getDocumentElement().getFirstChild();
+        a1.setAttribute("a_attr", "a_attr_newvalue");
+    }
+
+    private static Document getDocument(String xml) throws Exception {
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        DocumentBuilder db = dbf.newDocumentBuilder();
         InputStream a = new ByteArrayInputStream(xml.getBytes());
-        Document out = builder.parse(a);
+        Document out = db.parse(a);
         return out;
     }
 
+    // EventListener that mutates an unrelated document when an event is received.
+    static class MyEventListener implements EventListener {
+
+        private int docId;
+        private Document doc = null;
+
+        public MyEventListener(int docId) {
+            this.docId = docId;
+        }
+
+        public MyEventListener(int docId, Document doc) {
+            this.docId = docId;
+            this.doc = doc;
+        }
+
+        public void handleEvent(Event evt) {
+            if (docId == DOC1) {
+                //check the related node before making changes
+                checkRelatedNode(evt, "a_attr_value");
+                //make a change to doc2
+                Element ele = (Element)doc.getDocumentElement().getFirstChild();
+                ele.setAttribute("b_attr", "value for b_attr in doc2");
+                //check the related node again after the change
+                checkRelatedNode(evt, "a_attr_value");
+            } else { //DOC2
+                checkRelatedNode(evt, "value for b_attr in doc2");
+            }
+        }
+
+    }
+
+    // Utility method to display an event
+    public static void checkRelatedNode(Event evt, String expected) {
+        //System.out.println(" Event: " + evt + ", on " + evt.getTarget());
+        if (evt instanceof MutationEventImpl) {
+            MutationEventImpl mutation = (MutationEventImpl) evt;
+            //System.out.println(" + Related: " + mutation.getRelatedNode());
+            Assert.assertTrue(mutation.getRelatedNode().toString().contains(expected));
+        }
+    }
 }