changeset 23778:0d8b898d450c

Merge
author lana
date Tue, 01 Apr 2014 17:27:49 -0700
parents c826d05f1fb0 ce87cedb71cf
children bf6b3c7f8f05
files
diffstat 7 files changed, 927 insertions(+), 950 deletions(-) [+]
line wrap: on
line diff
--- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMStringListImpl.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMStringListImpl.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 2001, 2002,2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -20,6 +21,7 @@
 
 package com.sun.org.apache.xerces.internal.dom;
 
+import java.util.ArrayList;
 import java.util.Vector;
 
 import org.w3c.dom.DOMStringList;
@@ -35,47 +37,54 @@
  */
 public class DOMStringListImpl implements DOMStringList {
 
-        //A collection of DOMString values
-    private Vector fStrings;
+    // A collection of DOMString values
+    private final ArrayList fStrings;
 
     /**
      * Construct an empty list of DOMStringListImpl
      */
     public DOMStringListImpl() {
-        fStrings = new Vector();
+        fStrings = new ArrayList();
     }
 
     /**
-     * Construct an empty list of DOMStringListImpl
+     * Construct a DOMStringListImpl from an ArrayList
      */
-    public DOMStringListImpl(Vector params) {
+    public DOMStringListImpl(ArrayList params) {
         fStrings = params;
     }
 
-        /**
-         * @see org.w3c.dom.DOMStringList#item(int)
-         */
-        public String item(int index) {
-        try {
-            return (String) fStrings.elementAt(index);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            return null;
+    /**
+     * Construct a DOMStringListImpl from a Vector
+     */
+    public DOMStringListImpl(Vector params) {
+        fStrings = new ArrayList(params);
+    }
+
+    /**
+     * @see org.w3c.dom.DOMStringList#item(int)
+     */
+    public String item(int index) {
+        final int length = getLength();
+        if (index >= 0 && index < length) {
+            return (String) fStrings.get(index);
         }
-        }
+        return null;
+    }
 
-        /**
-         * @see org.w3c.dom.DOMStringList#getLength()
-         */
-        public int getLength() {
-                return fStrings.size();
-        }
+    /**
+     * @see org.w3c.dom.DOMStringList#getLength()
+     */
+    public int getLength() {
+            return fStrings.size();
+    }
 
-        /**
-         * @see org.w3c.dom.DOMStringList#contains(String)
-         */
-        public boolean contains(String param) {
-                return fStrings.contains(param) ;
-        }
+    /**
+     * @see org.w3c.dom.DOMStringList#contains(String)
+     */
+    public boolean contains(String param) {
+        return fStrings.contains(param);
+    }
 
     /**
      * DOM Internal:
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java	Tue Apr 01 17:27:49 2014 -0700
@@ -1,13 +1,14 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
  */
-
 /*
- * Copyright 2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -52,7 +53,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Stack;
-import javax.xml.XMLConstants;
+import java.util.StringTokenizer;
 
 
 /**
@@ -1810,7 +1811,7 @@
         userDir = userDir.replace(separator, '/');
 
         int len = userDir.length(), ch;
-        StringBuffer buffer = new StringBuffer(len*3);
+        StringBuilder buffer = new StringBuilder(len*3);
         // change C:/blah to /C:/blah
         if (len >= 2 && userDir.charAt(1) == ':') {
             ch = Character.toUpperCase(userDir.charAt(0));
@@ -1880,6 +1881,61 @@
         return gUserDirURI;
     }
 
+    public static OutputStream createOutputStream(String uri) throws IOException {
+        // URI was specified. Handle relative URIs.
+        final String expanded = XMLEntityManager.expandSystemId(uri, null, true);
+        final URL url = new URL(expanded != null ? expanded : uri);
+        OutputStream out = null;
+        String protocol = url.getProtocol();
+        String host = url.getHost();
+        // Use FileOutputStream if this URI is for a local file.
+        if (protocol.equals("file")
+                && (host == null || host.length() == 0 || host.equals("localhost"))) {
+            File file = new File(getPathWithoutEscapes(url.getPath()));
+            if (!file.exists()) {
+                File parent = file.getParentFile();
+                if (parent != null && !parent.exists()) {
+                    parent.mkdirs();
+                }
+            }
+            out = new FileOutputStream(file);
+        }
+        // Try to write to some other kind of URI. Some protocols
+        // won't support this, though HTTP should work.
+        else {
+            URLConnection urlCon = url.openConnection();
+            urlCon.setDoInput(false);
+            urlCon.setDoOutput(true);
+            urlCon.setUseCaches(false); // Enable tunneling.
+            if (urlCon instanceof HttpURLConnection) {
+                // The DOM L3 REC says if we are writing to an HTTP URI
+                // it is to be done with an HTTP PUT.
+                HttpURLConnection httpCon = (HttpURLConnection) urlCon;
+                httpCon.setRequestMethod("PUT");
+            }
+            out = urlCon.getOutputStream();
+        }
+        return out;
+    }
+
+    private static String getPathWithoutEscapes(String origPath) {
+        if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) {
+            // Locate the escape characters
+            StringTokenizer tokenizer = new StringTokenizer(origPath, "%");
+            StringBuilder result = new StringBuilder(origPath.length());
+            int size = tokenizer.countTokens();
+            result.append(tokenizer.nextToken());
+            for(int i = 1; i < size; ++i) {
+                String token = tokenizer.nextToken();
+                // Decode the 2 digit hexadecimal number following % in '%nn'
+                result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue());
+                result.append(token.substring(2));
+            }
+            return result.toString();
+        }
+        return origPath;
+    }
+
     /**
      * Absolutizes a URI using the current value
      * of the "user.dir" property as the base URI. If
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RangeToken.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RangeToken.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -351,7 +352,7 @@
                                                 // src2:      o----o
                                                 // src2:          o----o
                                                 // src2:  o------------o
-                if (src2begin <= src2begin && src1end <= src2end) {
+                if (src2begin <= src1begin && src1end <= src2end) {
                                                 // src1:    o--------o
                                                 // src2:  o------------o
                                                 // res:     o--------o
@@ -384,6 +385,7 @@
                     result[wp++] = src2begin;
                     result[wp++] = src2end;
                     this.ranges[src1] = src2end+1;
+                    src2 += 2;
                 }
             } else if (src2end < src1begin) {
                                                 // Not overlapped
@@ -399,10 +401,6 @@
                                            +"]");
             }
         }
-        while (src1 < this.ranges.length) {
-            result[wp++] = this.ranges[src1++];
-            result[wp++] = this.ranges[src1++];
-        }
         this.ranges = new int[wp];
         System.arraycopy(result, 0, this.ranges, 0, wp);
                                                 // this.ranges is sorted and compacted.
@@ -464,8 +462,8 @@
                 if (ch > 0xffff)
                     lowers.addRange(ch, ch);
                 else {
-                    char uch = Character.toUpperCase((char)ch);
-                    lowers.addRange(uch, uch);
+                    char lch = Character.toLowerCase((char)ch);
+                    lowers.addRange(lch, lch);
                 }
             }
         }
@@ -479,8 +477,10 @@
 
     void dumpRanges() {
         System.err.print("RANGE: ");
-        if (this.ranges == null)
+        if (this.ranges == null) {
             System.err.println(" NULL");
+            return;
+        }
         for (int i = 0;  i < this.ranges.length;  i += 2) {
             System.err.print("["+this.ranges[i]+","+this.ranges[i+1]+"] ");
         }
@@ -552,10 +552,10 @@
             else if (this == Token.token_spaces)
                 ret = "\\s";
             else {
-                StringBuffer sb = new StringBuffer();
-                sb.append("[");
+                StringBuilder sb = new StringBuilder();
+                sb.append('[');
                 for (int i = 0;  i < this.ranges.length;  i += 2) {
-                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(",");
+                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(',');
                     if (this.ranges[i] == this.ranges[i+1]) {
                         sb.append(escapeCharInCharClass(this.ranges[i]));
                     } else {
@@ -564,7 +564,7 @@
                         sb.append(escapeCharInCharClass(this.ranges[i+1]));
                     }
                 }
-                sb.append("]");
+                sb.append(']');
                 ret = sb.toString();
             }
         } else {
@@ -578,7 +578,7 @@
                 StringBuffer sb = new StringBuffer();
                 sb.append("[^");
                 for (int i = 0;  i < this.ranges.length;  i += 2) {
-                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(",");
+                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0)  sb.append(',');
                     if (this.ranges[i] == this.ranges[i+1]) {
                         sb.append(escapeCharInCharClass(this.ranges[i]));
                     } else {
@@ -587,7 +587,7 @@
                         sb.append(escapeCharInCharClass(this.ranges[i+1]));
                     }
                 }
-                sb.append("]");
+                sb.append(']');
                 ret = sb.toString();
             }
         }
--- a/jaxp/src/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serialize/BaseMarkupSerializer.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -18,7 +19,6 @@
  * limitations under the License.
  */
 
-
 // Sep 14, 2000:
 //  Fixed comments to preserve whitespaces and add a line break
 //  when indenting. Reported by Gervase Markham <gerv@gerv.net>
@@ -57,17 +57,13 @@
 import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
 import com.sun.org.apache.xerces.internal.util.XMLChar;
-import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.DocumentType;
-import org.w3c.dom.DOMError;
-import org.w3c.dom.DOMErrorHandler;
 import org.w3c.dom.Element;
-import org.w3c.dom.Entity;
-import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
-import org.w3c.dom.Notation;
 import org.w3c.dom.ls.LSException;
 import org.w3c.dom.ls.LSSerializerFilter;
 import org.w3c.dom.traversal.NodeFilter;
@@ -126,7 +122,7 @@
  * @author Elena Litani, IBM
  * @author Sunitha Reddy, Sun Microsystems
  * @see Serializer
- * @see LSSerializer
+ * @see org.w3c.dom.ls.LSSerializer
  */
 public abstract class BaseMarkupSerializer
     implements ContentHandler, DocumentHandler, LexicalHandler,
@@ -337,6 +333,9 @@
         return true;
     }
 
+    protected void cleanup() {
+        fCurrentNode = null;
+    }
 
     protected void prepare()
         throws IOException
@@ -409,6 +408,7 @@
         reset();
         prepare();
         serializeNode( elem );
+        cleanup();
         _printer.flush();
         if ( _printer.getException() != null )
             throw _printer.getException();
@@ -438,7 +438,7 @@
      * writer and output format. Throws an exception only if
      * an I/O exception occured while serializing.
      *
-     * @param elem The element to serialize
+     * @param frag The document fragment to serialize
      * @throws IOException An I/O exception occured while
      *   serializing
      */
@@ -448,6 +448,7 @@
         reset();
         prepare();
         serializeNode( frag );
+        cleanup();
         _printer.flush();
         if ( _printer.getException() != null )
             throw _printer.getException();
@@ -470,6 +471,7 @@
         prepare();
         serializeNode( doc );
         serializePreRoot();
+        cleanup();
         _printer.flush();
         if ( _printer.getException() != null )
             throw _printer.getException();
@@ -530,22 +532,22 @@
                 if (!XMLChar.isValid(ch)) {
                     // check if it is surrogate
                     if (++index < end) {
-                        surrogates(ch, chars[index]);
+                        surrogates(ch, chars[index],true);
                     }
                     else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
-                } else {
-                    if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
-                        ch == '\n' || ch == '\r' || ch == '\t' ) {
-                        _printer.printText((char)ch);
-                    } else {
-                        // The character is not printable -- split CDATA section
-                        _printer.printText("]]>&#x");
-                        _printer.printText(Integer.toHexString(ch));
-                        _printer.printText(";<![CDATA[");
-                    }
+                }
+                if ( ( ch >= ' ' && _encodingInfo.isPrintable(ch) && ch != 0x7F ) ||
+                    ch == '\n' || ch == '\r' || ch == '\t' ) {
+                    _printer.printText(ch);
+                }
+                else {
+                    // The character is not printable -- split CDATA section
+                    _printer.printText("]]>&#x");
+                    _printer.printText(Integer.toHexString(ch));
+                    _printer.printText(";<![CDATA[");
                 }
             }
             _printer.setNextIndent( saveIndent );
@@ -1195,11 +1197,6 @@
         }
         case Node.DOCUMENT_NODE : {
             DocumentType      docType;
-            DOMImplementation domImpl;
-            NamedNodeMap      map;
-            Entity            entity;
-            Notation          notation;
-            int               i;
 
             serializeDocument();
 
@@ -1208,7 +1205,6 @@
             docType = ( (Document) node ).getDoctype();
             if (docType != null) {
                 // DOM Level 2 (or higher)
-                domImpl = ( (Document) node ).getImplementation();
                 try {
                     String internal;
 
@@ -1372,7 +1368,7 @@
      * state with <tt>empty</tt> and <tt>afterElement</tt> set to false.
      *
      * @return The current element state
-     * @throws IOException An I/O exception occured while
+     * @throws IOException An I/O exception occurred while
      *   serializing
      */
     protected ElementState content()
@@ -1415,7 +1411,6 @@
      * whether the text is printed as CDATA or unescaped.
      *
      * @param text The text to print
-     * @param unescaped True is should print unescaped
      * @throws IOException An I/O exception occured while
      *   serializing
      */
@@ -1430,9 +1425,6 @@
         // state) or whether we are inside a CDATA section or entity.
 
         if ( state.inCData || state.doCData ) {
-            int          index;
-            int          saveIndent;
-
             // Print a CDATA section. The text is not escaped, but ']]>'
             // appearing in the code must be identified and dealt with.
             // The contents of a text node is considered space preserving.
@@ -1440,7 +1432,7 @@
                 _printer.printText("<![CDATA[");
                 state.inCData = true;
             }
-            saveIndent = _printer.getNextIndent();
+            int saveIndent = _printer.getNextIndent();
             _printer.setNextIndent( 0 );
             printCDATAText( text);
             _printer.setNextIndent( saveIndent );
@@ -1543,12 +1535,10 @@
                             fDOMErrorHandler.handleError(fDOMError);
                             throw new LSException(LSException.SERIALIZE_ERR, msg);
                         }
-                        else {
-                            // issue error
-                            modifyDOMError(msg, DOMError.SEVERITY_ERROR, "cdata-section-not-splitted", fCurrentNode);
-                            if (!fDOMErrorHandler.handleError(fDOMError)) {
-                                throw new LSException(LSException.SERIALIZE_ERR, msg);
-                            }
+                        // issue error
+                        modifyDOMError(msg, DOMError.SEVERITY_ERROR, "cdata-section-not-splitted", fCurrentNode);
+                        if (!fDOMErrorHandler.handleError(fDOMError)) {
+                            throw new LSException(LSException.SERIALIZE_ERR, msg);
                         }
                     } else {
                         // issue warning
@@ -1573,29 +1563,29 @@
             if (!XMLChar.isValid(ch)) {
                 // check if it is surrogate
                 if (++index <length) {
-                    surrogates(ch, text.charAt(index));
+                    surrogates(ch, text.charAt(index),true);
                 }
                 else {
-                    fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                    fatalError("The character '"+ch+"' is an invalid XML character");
                 }
                 continue;
-            } else {
-                if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
-                     ch == '\n' || ch == '\r' || ch == '\t' ) {
-                    _printer.printText((char)ch);
-                } else {
+            }
+            if ( ( ch >= ' ' && _encodingInfo.isPrintable(ch) && ch != 0x7F ) ||
+                 ch == '\n' || ch == '\r' || ch == '\t' ) {
+                _printer.printText(ch);
+            }
+            else {
 
-                    // The character is not printable -- split CDATA section
-                    _printer.printText("]]>&#x");
-                    _printer.printText(Integer.toHexString(ch));
-                    _printer.printText(";<![CDATA[");
-                }
+                // The character is not printable -- split CDATA section
+                _printer.printText("]]>&#x");
+                _printer.printText(Integer.toHexString(ch));
+                _printer.printText(";<![CDATA[");
             }
         }
     }
 
 
-    protected void surrogates(int high, int low) throws IOException{
+    protected void surrogates(int high, int low, boolean inContent) throws IOException{
         if (XMLChar.isHighSurrogate(high)) {
             if (!XMLChar.isLowSurrogate(low)) {
                 //Invalid XML
@@ -1608,7 +1598,7 @@
                     fatalError("The character '"+(char)supplemental+"' is an invalid XML character");
                 }
                 else {
-                    if (content().inCData ) {
+                    if (inContent && content().inCData) {
                         _printer.printText("]]>&#x");
                         _printer.printText(Integer.toHexString(supplemental));
                         _printer.printText(";<![CDATA[");
@@ -1633,7 +1623,9 @@
      * Multiple spaces are printed as such, but spaces at beginning
      * of line are removed.
      *
-     * @param text The text to print
+     * @param chars The text to print
+     * @param start The start offset
+     * @param length The number of characters
      * @param preserveSpace Space preserving flag
      * @param unescaped Print unescaped
      */
@@ -1641,8 +1633,6 @@
                                     boolean preserveSpace, boolean unescaped )
         throws IOException
     {
-        int index;
-        char ch;
 
         if ( preserveSpace ) {
             // Preserving spaces: the text must print exactly as it is,
@@ -1650,12 +1640,14 @@
             // consolidating spaces. If a line terminator is used, a line
             // break will occur.
             while ( length-- > 0 ) {
-                ch = chars[ start ];
+                char ch = chars[ start ];
                 ++start;
-                if ( ch == '\n' || ch == '\r' || unescaped )
+                if ( ch == '\n' || ch == '\r' || unescaped ) {
                     _printer.printText( ch );
-                else
+                }
+                else {
                     printEscaped( ch );
+                }
             }
         } else {
             // Not preserving spaces: print one part at a time, and
@@ -1664,14 +1656,17 @@
             // by printing mechanism. Line terminator is treated
             // no different than other text part.
             while ( length-- > 0 ) {
-                ch = chars[ start ];
+                char ch = chars[ start ];
                 ++start;
-                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
+                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) {
                     _printer.printSpace();
-                else if ( unescaped )
+                }
+                else if ( unescaped ) {
                     _printer.printText( ch );
-                else
+                }
+                else {
                     printEscaped( ch );
+                }
             }
         }
     }
@@ -1703,12 +1698,15 @@
             // no different than other text part.
             for ( index = 0 ; index < text.length() ; ++index ) {
                 ch = text.charAt( index );
-                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' )
+                if ( ch == ' ' || ch == '\f' || ch == '\t' || ch == '\n' || ch == '\r' ) {
                     _printer.printSpace();
-                else if ( unescaped )
+                }
+                else if ( unescaped ) {
                     _printer.printText( ch );
-                else
+                }
+                else {
                     printEscaped( ch );
+                }
             }
         }
     }
@@ -1751,7 +1749,7 @@
             _printer.printText( '&' );
             _printer.printText( charRef );
             _printer.printText( ';' );
-        } else if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0xF7 ) ||
+        } else if ( ( ch >= ' ' && _encodingInfo.isPrintable((char)ch) && ch != 0x7F ) ||
                     ch == '\n' || ch == '\r' || ch == '\t' ) {
             // Non printables are below ASCII space but not tab or line
             // terminator, ASCII delete, or above a certain Unicode threshold.
@@ -1872,14 +1870,13 @@
     {
         if ( _elementStateCount > 0 ) {
             /*Corrected by David Blondeau (blondeau@intalio.com)*/
-                _prefixes = null;
-                //_prefixes = _elementStates[ _elementStateCount ].prefixes;
+            _prefixes = null;
+            //_prefixes = _elementStates[ _elementStateCount ].prefixes;
             -- _elementStateCount;
             return _elementStates[ _elementStateCount ];
-        } else {
-            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "Internal", null);
-            throw new IllegalStateException(msg);
         }
+        String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "Internal", null);
+        throw new IllegalStateException(msg);
     }
 
 
@@ -1890,11 +1887,14 @@
      *
      * @return True if in the state of the document
      */
-    protected boolean isDocumentState()
-    {
+    protected boolean isDocumentState() {
         return _elementStateCount == 0;
     }
 
+    /** Clears document state. **/
+    final void clearDocumentState() {
+        _elementStateCount = 0;
+    }
 
     /**
      * Returns the namespace prefix for the specified URI.
@@ -1913,15 +1913,14 @@
             if ( prefix != null )
                 return prefix;
         }
-        if ( _elementStateCount == 0 )
+        if ( _elementStateCount == 0 ) {
             return null;
-        else {
-            for ( int i = _elementStateCount ; i > 0 ; --i ) {
-                if ( _elementStates[ i ].prefixes != null ) {
-                    prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI );
-                    if ( prefix != null )
-                        return prefix;
-                }
+        }
+        for ( int i = _elementStateCount ; i > 0 ; --i ) {
+            if ( _elementStates[ i ].prefixes != null ) {
+                prefix = (String) _elementStates[ i ].prefixes.get( namespaceURI );
+                if ( prefix != null )
+                    return prefix;
             }
         }
         return null;
--- a/jaxp/src/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -17,21 +18,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.sun.org.apache.xml.internal.serialize;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.lang.reflect.Method;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.StringTokenizer;
-import java.util.Vector;
+import java.util.ArrayList;
 
 import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
@@ -39,10 +34,6 @@
 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
 import com.sun.org.apache.xerces.internal.dom.DOMNormalizer;
 import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.DOMError;
-import org.w3c.dom.DOMErrorHandler;
-import org.w3c.dom.DOMStringList;
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
 import com.sun.org.apache.xerces.internal.util.DOMUtil;
@@ -52,26 +43,30 @@
 import com.sun.org.apache.xerces.internal.util.XMLChar;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Comment;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMError;
+import org.w3c.dom.DOMErrorHandler;
 import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMStringList;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
 import org.w3c.dom.ls.LSException;
 import org.w3c.dom.ls.LSOutput;
 import org.w3c.dom.ls.LSSerializer;
 import org.w3c.dom.ls.LSSerializerFilter;
 
-
 /**
- * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer  by delegating serialization
- * calls to <CODE>XMLSerializer</CODE>.
- * LSSerializer provides an API for serializing (writing) a DOM document out in an
- * XML document. The XML data is written to an output stream.
- * During serialization of XML data, namespace fixup is done when possible as
- * defined in DOM Level 3 Core, Appendix B.
+ * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer by
+ * delegating serialization calls to <CODE>XMLSerializer</CODE>. LSSerializer
+ * provides an API for serializing (writing) a DOM document out in an XML
+ * document. The XML data is written to an output stream. During serialization
+ * of XML data, namespace fixup is done when possible as defined in DOM Level 3
+ * Core, Appendix B.
  *
  * @author Elena Litani, IBM
  * @author Gopal Sharma, Sun Microsystems
@@ -84,7 +79,6 @@
     // TODO: When DOM Level 3 goes to REC replace method calls using
     // reflection for: getXmlEncoding, getInputEncoding and getXmlEncoding
     // with regular static calls on the Document object.
-
     // data
     // serializer
     private XMLSerializer serializer;
@@ -95,35 +89,36 @@
     //Recognized parameters
     private DOMStringList fRecognizedParameters;
 
-    /** REVISIT: Currently we handle 3 different configurations, would be nice just have one configuration
-     * that has different recognized parameters depending if it is used in Core/LS.
+    /**
+     * REVISIT: Currently we handle 3 different configurations, would be nice
+     * just have one configuration that has different recognized parameters
+     * depending if it is used in Core/LS.
      */
     protected short features = 0;
 
-    protected final static short NAMESPACES          = 0x1<<0;
-    protected final static short WELLFORMED          = 0x1<<1;
-    protected final static short ENTITIES            = 0x1<<2;
-    protected final static short CDATA               = 0x1<<3;
-    protected final static short SPLITCDATA          = 0x1<<4;
-    protected final static short COMMENTS            = 0x1<<5;
-    protected final static short DISCARDDEFAULT      = 0x1<<6;
-    protected final static short INFOSET             = 0x1<<7;
-    protected final static short XMLDECL             = 0x1<<8;
-    protected final static short NSDECL              = 0x1<<9;
-    protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1<<10;
-    protected final static short FORMAT_PRETTY_PRINT = 0x1<<11;
+    protected final static short NAMESPACES = 0x1 << 0;
+    protected final static short WELLFORMED = 0x1 << 1;
+    protected final static short ENTITIES = 0x1 << 2;
+    protected final static short CDATA = 0x1 << 3;
+    protected final static short SPLITCDATA = 0x1 << 4;
+    protected final static short COMMENTS = 0x1 << 5;
+    protected final static short DISCARDDEFAULT = 0x1 << 6;
+    protected final static short INFOSET = 0x1 << 7;
+    protected final static short XMLDECL = 0x1 << 8;
+    protected final static short NSDECL = 0x1 << 9;
+    protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1 << 10;
+    protected final static short PRETTY_PRINT = 0x1 << 11;
 
     // well-formness checking
     private DOMErrorHandler fErrorHandler = null;
     private final DOMErrorImpl fError = new DOMErrorImpl();
     private final DOMLocatorImpl fLocator = new DOMLocatorImpl();
-    private static final RuntimeException abort = new RuntimeException();
 
     /**
-     * Constructs a new LSSerializer.
-     * The constructor turns on the namespace support in <code>XMLSerializer</code> and
-     * initializes the following fields: fNSBinder, fLocalNSBinder, fSymbolTable,
-     * fEmptySymbol, fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures.
+     * Constructs a new LSSerializer. The constructor turns on the namespace
+     * support in <code>XMLSerializer</code> and initializes the following
+     * fields: fNSBinder, fLocalNSBinder, fSymbolTable, fEmptySymbol,
+     * fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures.
      */
     public DOMSerializerImpl() {
         // set default features
@@ -142,24 +137,21 @@
         initSerializer(serializer);
     }
 
-
-
     //
     // LSSerializer methods
     //
-
-    public DOMConfiguration getDomConfig(){
+    public DOMConfiguration getDomConfig() {
         return this;
     }
 
-    /** DOM L3-EXPERIMENTAL:
-     * Setter for boolean and object parameters
+    /**
+     * DOM L3-EXPERIMENTAL: Setter for boolean and object parameters
      */
     public void setParameter(String name, Object value) throws DOMException {
         if (value instanceof Boolean) {
             boolean state = ((Boolean) value).booleanValue();
-            if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){
-                if (state){
+            if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
+                if (state) {
                     features &= ~ENTITIES;
                     features &= ~CDATA;
                     features |= NAMESPACES;
@@ -169,54 +161,50 @@
                 }
                 // false does not have any effect
             } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
-                features =
-                    (short) (state ? features | XMLDECL : features & ~XMLDECL);
+                features
+                        = (short) (state ? features | XMLDECL : features & ~XMLDECL);
             } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
-                features =
-                    (short) (state
+                features
+                        = (short) (state
                         ? features | NAMESPACES
                         : features & ~NAMESPACES);
                 serializer.fNamespaces = state;
             } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
-                features =
-                    (short) (state
+                features
+                        = (short) (state
                         ? features | SPLITCDATA
                         : features & ~SPLITCDATA);
             } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
-                features =
-                    (short) (state
+                features
+                        = (short) (state
                         ? features | DISCARDDEFAULT
                         : features & ~DISCARDDEFAULT);
             } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
-                features =
-                    (short) (state
+                features
+                        = (short) (state
                         ? features | WELLFORMED
                         : features & ~WELLFORMED);
-            } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)){
-                features =
-                    (short) (state
+            } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
+                features
+                        = (short) (state
                         ? features | ENTITIES
                         : features & ~ENTITIES);
-            }
-            else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)){
-                features =
-                    (short) (state
+            } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
+                features
+                        = (short) (state
                         ? features | CDATA
                         : features & ~CDATA);
-                        }
-            else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)){
-                features =
-                     (short) (state
-                         ? features | COMMENTS
-                         : features & ~COMMENTS);
-            }
-            else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)){
-                features =
-                     (short) (state
-                         ? features | FORMAT_PRETTY_PRINT
-                         : features & ~FORMAT_PRETTY_PRINT);
-            }
-                else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
+            } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
+                features
+                        = (short) (state
+                        ? features | COMMENTS
+                        : features & ~COMMENTS);
+            } else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
+                features
+                        = (short) (state
+                        ? features | PRETTY_PRINT
+                        : features & ~PRETTY_PRINT);
+            } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
                     || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
                     || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
                     || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
@@ -224,85 +212,81 @@
                 //  || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
                 // true is not supported
                 if (state) {
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "FEATURE_NOT_SUPPORTED",
-                            new Object[] { name });
+                    String msg
+                            = DOMMessageFormatter.formatMessage(
+                                    DOMMessageFormatter.DOM_DOMAIN,
+                                    "FEATURE_NOT_SUPPORTED",
+                                    new Object[]{name});
                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
                 }
-            }else if (
-                        name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
-                                //namespace-declaration has effect only if namespaces is true
-                                features =
-                                        (short) (state
-                                                ? features | NSDECL
-                                                : features & ~NSDECL);
-                                serializer.fNamespacePrefixes = state;
+            } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
+                //namespace-declaration has effect only if namespaces is true
+                features
+                        = (short) (state
+                        ? features | NSDECL
+                        : features & ~NSDECL);
+                serializer.fNamespacePrefixes = state;
             } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
                     || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
                 // false is not supported
                 if (!state) {
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "FEATURE_NOT_SUPPORTED",
-                            new Object[] { name });
+                    String msg
+                            = DOMMessageFormatter.formatMessage(
+                                    DOMMessageFormatter.DOM_DOMAIN,
+                                    "FEATURE_NOT_SUPPORTED",
+                                    new Object[]{name});
                     throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
                 }
             } else {
-                String msg =
-                    DOMMessageFormatter.formatMessage(
-                        DOMMessageFormatter.DOM_DOMAIN,
-                        "FEATURE_NOT_FOUND",
-                        new Object[] { name });
+                String msg
+                        = DOMMessageFormatter.formatMessage(
+                                DOMMessageFormatter.DOM_DOMAIN,
+                                "FEATURE_NOT_FOUND",
+                                new Object[]{name});
                 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
             }
         } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
             if (value == null || value instanceof DOMErrorHandler) {
-                fErrorHandler = (DOMErrorHandler)value;
+                fErrorHandler = (DOMErrorHandler) value;
             } else {
-                String msg =
-                    DOMMessageFormatter.formatMessage(
-                        DOMMessageFormatter.DOM_DOMAIN,
-                        "TYPE_MISMATCH_ERR",
-                        new Object[] { name });
+                String msg
+                        = DOMMessageFormatter.formatMessage(
+                                DOMMessageFormatter.DOM_DOMAIN,
+                                "TYPE_MISMATCH_ERR",
+                                new Object[]{name});
                 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg);
             }
-        } else if (
-            name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
+        } else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)
                 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
                 && value != null) {
-            String msg =
-                DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "FEATURE_NOT_SUPPORTED",
-                    new Object[] { name });
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "FEATURE_NOT_SUPPORTED",
+                            new Object[]{name});
             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
         } else {
-            String msg =
-                DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "FEATURE_NOT_FOUND",
-                    new Object[] { name });
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "FEATURE_NOT_FOUND",
+                            new Object[]{name});
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
         }
     }
 
-    /** DOM L3-EXPERIMENTAL:
-     * Check if parameter can be set
+    /**
+     * DOM L3-EXPERIMENTAL: Check if parameter can be set
      */
     public boolean canSetParameter(String name, Object state) {
-
         if (state == null) {
             return true;
         }
 
         if (state instanceof Boolean) {
             boolean value = ((Boolean) state).booleanValue();
-
             if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)
                 || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)
                 || name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)
@@ -312,8 +296,8 @@
                 || name.equalsIgnoreCase(Constants.DOM_ENTITIES)
                 || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)
                 || name.equalsIgnoreCase(Constants.DOM_COMMENTS)
-                || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)
-                || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
+                || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)
+                || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
                 // both values supported
                 return true;
             } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
@@ -329,8 +313,8 @@
                 // false is not supported
                 return value;
             }
-        } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER) &&
-            state == null || state instanceof DOMErrorHandler) {
+        } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)
+                && state == null || state instanceof DOMErrorHandler) {
             return true;
         }
 
@@ -338,60 +322,57 @@
     }
 
     /**
-     *  DOM Level 3 Core CR - Experimental.
+     * DOM Level 3 Core CR - Experimental.
      *
-     *  The list of the parameters supported by this
-     * <code>DOMConfiguration</code> object and for which at least one value
-     * can be set by the application. Note that this list can also contain
-     * parameter names defined outside this specification.
+     * The list of the parameters supported by this
+     * <code>DOMConfiguration</code> object and for which at least one value 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){
-                        Vector parameters = new Vector();
+        if (fRecognizedParameters == null) {
+            ArrayList parameters = new ArrayList();
 
-                        //Add DOM recognized parameters
-                        //REVISIT: Would have been nice to have a list of
-                        //recognized parameters.
-                        parameters.add(Constants.DOM_NAMESPACES);
-                        parameters.add(Constants.DOM_SPLIT_CDATA);
-                        parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT);
-                        parameters.add(Constants.DOM_XMLDECL);
-                        parameters.add(Constants.DOM_CANONICAL_FORM);
-                        parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
-                        parameters.add(Constants.DOM_VALIDATE);
-                        parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
-                        parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
-                        parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT);
-                        //parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
-                        parameters.add(Constants.DOM_WELLFORMED);
-                        parameters.add(Constants.DOM_INFOSET);
-                        parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
-                        parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
-                        parameters.add(Constants.DOM_ENTITIES);
-                        parameters.add(Constants.DOM_CDATA_SECTIONS);
-                        parameters.add(Constants.DOM_COMMENTS);
-                        parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
-                        parameters.add(Constants.DOM_ERROR_HANDLER);
-                        //parameters.add(Constants.DOM_SCHEMA_LOCATION);
-                        //parameters.add(Constants.DOM_SCHEMA_TYPE);
+            //Add DOM recognized parameters
+            //REVISIT: Would have been nice to have a list of
+            //recognized parameters.
+            parameters.add(Constants.DOM_NAMESPACES);
+            parameters.add(Constants.DOM_SPLIT_CDATA);
+            parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT);
+            parameters.add(Constants.DOM_XMLDECL);
+            parameters.add(Constants.DOM_CANONICAL_FORM);
+            parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
+            parameters.add(Constants.DOM_VALIDATE);
+            parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
+            parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
+            parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT);
+            //parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
+            parameters.add(Constants.DOM_WELLFORMED);
+            parameters.add(Constants.DOM_INFOSET);
+            parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
+            parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
+            parameters.add(Constants.DOM_ENTITIES);
+            parameters.add(Constants.DOM_CDATA_SECTIONS);
+            parameters.add(Constants.DOM_COMMENTS);
+            parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
+            parameters.add(Constants.DOM_ERROR_HANDLER);
+            //parameters.add(Constants.DOM_SCHEMA_LOCATION);
+            //parameters.add(Constants.DOM_SCHEMA_TYPE);
 
-                        //Add recognized xerces features and properties
-
-                        fRecognizedParameters = new DOMStringListImpl(parameters);
-
+            //Add recognized xerces features and properties
+            fRecognizedParameters = new DOMStringListImpl(parameters);
         }
 
         return fRecognizedParameters;
     }
 
-    /** DOM L3-EXPERIMENTAL:
-     * Getter for boolean and object parameters
+    /**
+     * DOM L3-EXPERIMENTAL: Getter for boolean and object parameters
      */
     public Object getParameter(String name) throws DOMException {
-
-        if(name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)){
-                      return null;
+        if (name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
+            return null;
         } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
             return ((features & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE;
         } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
@@ -408,23 +389,23 @@
             return (features & WELLFORMED) != 0 ? Boolean.TRUE : Boolean.FALSE;
         } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
             return (features & NSDECL) != 0 ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
+                || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
+            return Boolean.TRUE;
+        } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
+            return ((features & DISCARDDEFAULT) != 0) ? Boolean.TRUE : Boolean.FALSE;
         } else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
-            return (features & FORMAT_PRETTY_PRINT) != 0 ? Boolean.TRUE : Boolean.FALSE;
-        } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) ||
-                   name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
-            return Boolean.TRUE;
-        }else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)){
-            return ((features & DISCARDDEFAULT)!=0)?Boolean.TRUE:Boolean.FALSE;
-        }else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){
-            if ((features & ENTITIES) == 0 &&
-                 (features & CDATA) == 0 &&
-                 (features & NAMESPACES) != 0 &&
-                 (features & NSDECL) != 0 &&
-                 (features & WELLFORMED) != 0 &&
-                 (features & COMMENTS) != 0) {
-                     return Boolean.TRUE;
-                 }
-                 return Boolean.FALSE;
+            return ((features & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE;
+        } else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
+            if ((features & ENTITIES) == 0
+                    && (features & CDATA) == 0
+                    && (features & NAMESPACES) != 0
+                    && (features & NSDECL) != 0
+                    && (features & WELLFORMED) != 0
+                    && (features & COMMENTS) != 0) {
+                return Boolean.TRUE;
+            }
+            return Boolean.FALSE;
         } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
                 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
                 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
@@ -434,64 +415,48 @@
             return Boolean.FALSE;
         } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
             return fErrorHandler;
-        } else if (
-            name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
+        } else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
                 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
-            String msg =
-                DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "FEATURE_NOT_SUPPORTED",
-                    new Object[] { name });
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "FEATURE_NOT_SUPPORTED",
+                            new Object[]{name});
             throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
         } else {
-            String msg =
-                DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.DOM_DOMAIN,
-                    "FEATURE_NOT_FOUND",
-                    new Object[] { name });
+            String msg
+                    = DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.DOM_DOMAIN,
+                            "FEATURE_NOT_FOUND",
+                            new Object[]{name});
             throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
         }
     }
 
-
     /**
-     * DOM L3 EXPERIMENTAL:
-     *  Serialize the specified node as described above in the description of
-     * <code>LSSerializer</code>. The result of serializing the node is
-     * returned as a string. Writing a Document or Entity node produces a
-     * serialized form that is well formed XML. Writing other node types
-     * produces a fragment of text in a form that is not fully defined by
+     * DOM L3 EXPERIMENTAL: Serialize the specified node as described above in
+     * the description of <code>LSSerializer</code>. The result of serializing
+     * the node is returned as a string. Writing a Document or Entity node
+     * produces a serialized form that is well formed XML. Writing other node
+     * types produces a fragment of text in a form that is not fully defined by
      * this document, but that should be useful to a human for debugging or
      * diagnostic purposes.
-     * @param wnode  The node to be written.
-     * @return  Returns the serialized data
-     * @exception DOMException
-     *    DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a
-     *   <code>DOMString</code>.
-     * @exception LSException
-     *    SERIALIZE_ERR: Unable to serialize the node.  DOM applications should
-     *    attach a <code>DOMErrorHandler</code> using the parameter
-     *    &quot;<i>error-handler</i>&quot; to get details on error.
+     *
+     * @param wnode The node to be written.
+     * @return Returns the serialized data
+     * @exception DOMException DOMSTRING_SIZE_ERR: The resulting string is too
+     * long to fit in a <code>DOMString</code>.
+     * @exception LSException SERIALIZE_ERR: Unable to serialize the node. DOM
+     * applications should attach a <code>DOMErrorHandler</code> using the
+     * parameter &quot;<i>error-handler</i>&quot; to get details on error.
      */
     public String writeToString(Node wnode) throws DOMException, LSException {
         // determine which serializer to use:
-        Document doc = (wnode.getNodeType() == Node.DOCUMENT_NODE)?(Document)wnode:wnode.getOwnerDocument();
-        Method getVersion = null;
         XMLSerializer ser = null;
-        String ver = null;
-        // this should run under JDK 1.1.8...
-        try {
-            getVersion = doc.getClass().getMethod("getXmlVersion", new Class[]{});
-            if(getVersion != null ) {
-                ver = (String)getVersion.invoke(doc, (Object[]) null);
-            }
-        } catch (Exception e) {
-            // no way to test the version...
-            // ignore the exception
-        }
-        if(ver != null && ver.equals("1.1")) {
-            if(xml11Serializer == null) {
+        String ver = _getXmlVersion(wnode);
+        if (ver != null && ver.equals("1.1")) {
+            if (xml11Serializer == null) {
                 xml11Serializer = new XML11Serializer();
                 initSerializer(xml11Serializer);
             }
@@ -508,25 +473,21 @@
             ser._format.setEncoding("UTF-16");
             ser.setOutputCharStream(destination);
             if (wnode.getNodeType() == Node.DOCUMENT_NODE) {
-                ser.serialize((Document)wnode);
-            }
-            else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
-                ser.serialize((DocumentFragment)wnode);
-            }
-            else if (wnode.getNodeType() == Node.ELEMENT_NODE) {
-                ser.serialize((Element)wnode);
-            }
-            else if (wnode.getNodeType() == Node.TEXT_NODE ||
-                    wnode.getNodeType() == Node.COMMENT_NODE ||
-                    wnode.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
-                    wnode.getNodeType() == Node.CDATA_SECTION_NODE ||
-                    wnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
+                ser.serialize((Document) wnode);
+            } else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
+                ser.serialize((DocumentFragment) wnode);
+            } else if (wnode.getNodeType() == Node.ELEMENT_NODE) {
+                ser.serialize((Element) wnode);
+            } else if (wnode.getNodeType() == Node.TEXT_NODE
+                    || wnode.getNodeType() == Node.COMMENT_NODE
+                    || wnode.getNodeType() == Node.ENTITY_REFERENCE_NODE
+                    || wnode.getNodeType() == Node.CDATA_SECTION_NODE
+                    || wnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
                 ser.serialize(wnode);
-            }
-            else {
+            } else {
                 String msg = DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.SERIALIZER_DOMAIN,
-                    "unable-to-serialize-node", null);
+                        DOMMessageFormatter.SERIALIZER_DOMAIN,
+                        "unable-to-serialize-node", null);
                 if (ser.fDOMErrorHandler != null) {
                     DOMErrorImpl error = new DOMErrorImpl();
                     error.fType = "unable-to-serialize-node";
@@ -540,45 +501,42 @@
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            if (e == DOMNormalizer.abort){
+            if (e == DOMNormalizer.abort) {
                 // stopped at user request
                 return null;
             }
-            throw (LSException) new LSException(LSException.SERIALIZE_ERR, e.toString()).initCause(e);
+            throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         } catch (IOException ioe) {
             // REVISIT: A generic IOException doesn't provide enough information
             // to determine that the serialized document is too large to fit
             // into a string. This could have thrown for some other reason. -- mrglavas
             String msg = DOMMessageFormatter.formatMessage(
-                DOMMessageFormatter.DOM_DOMAIN,
-                "STRING_TOO_LONG",
-                new Object[] { ioe.getMessage()});
-            throw (DOMException) new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg).initCause(ioe);
+                    DOMMessageFormatter.DOM_DOMAIN,
+                    "STRING_TOO_LONG",
+                    new Object[]{ioe.getMessage()});
+            throw new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg);
+        } finally {
+            ser.clearDocumentState();
         }
-
         return destination.toString();
     }
 
     /**
-     * DOM L3 EXPERIMENTAL:
-     * The end-of-line sequence of characters to be used in the XML being
-     * written out. The only permitted values are these:
+     * DOM L3 EXPERIMENTAL: The end-of-line sequence of characters to be used in
+     * the XML being written out. The only permitted values are these:
      * <dl>
      * <dt><code>null</code></dt>
      * <dd>
-     * Use a default end-of-line sequence. DOM implementations should choose
-     * the default to match the usual convention for text files in the
-     * environment being used. Implementations must choose a default
-     * sequence that matches one of those allowed by  2.11 "End-of-Line
-     * Handling". </dd>
+     * Use a default end-of-line sequence. DOM implementations should choose the
+     * default to match the usual convention for text files in the environment
+     * being used. Implementations must choose a default sequence that matches
+     * one of those allowed by 2.11 "End-of-Line Handling". </dd>
      * <dt>CR</dt>
      * <dd>The carriage-return character (#xD).</dd>
      * <dt>CR-LF</dt>
-     * <dd> The
-     * carriage-return and line-feed characters (#xD #xA). </dd>
+     * <dd> The carriage-return and line-feed characters (#xD #xA). </dd>
      * <dt>LF</dt>
-     * <dd> The line-feed
-     * character (#xA). </dd>
+     * <dd> The line-feed character (#xA). </dd>
      * </dl>
      * <br>The default value for this attribute is <code>null</code>.
      */
@@ -586,27 +544,22 @@
         serializer._format.setLineSeparator(newLine);
     }
 
-
     /**
-     * DOM L3 EXPERIMENTAL:
-     * The end-of-line sequence of characters to be used in the XML being
-     * written out. The only permitted values are these:
+     * DOM L3 EXPERIMENTAL: The end-of-line sequence of characters to be used in
+     * the XML being written out. The only permitted values are these:
      * <dl>
      * <dt><code>null</code></dt>
      * <dd>
-     * Use a default end-of-line sequence. DOM implementations should choose
-     * the default to match the usual convention for text files in the
-     * environment being used. Implementations must choose a default
-     * sequence that matches one of those allowed by  2.11 "End-of-Line
-     * Handling". </dd>
+     * Use a default end-of-line sequence. DOM implementations should choose the
+     * default to match the usual convention for text files in the environment
+     * being used. Implementations must choose a default sequence that matches
+     * one of those allowed by 2.11 "End-of-Line Handling". </dd>
      * <dt>CR</dt>
      * <dd>The carriage-return character (#xD).</dd>
      * <dt>CR-LF</dt>
-     * <dd> The
-     * carriage-return and line-feed characters (#xD #xA). </dd>
+     * <dd> The carriage-return and line-feed characters (#xD #xA). </dd>
      * <dt>LF</dt>
-     * <dd> The line-feed
-     * character (#xA). </dd>
+     * <dd> The line-feed character (#xA). </dd>
      * </dl>
      * <br>The default value for this attribute is <code>null</code>.
      */
@@ -614,23 +567,23 @@
         return serializer._format.getLineSeparator();
     }
 
+    /**
+     * When the application provides a filter, the serializer will call out to
+     * the filter before serializing each Node. Attribute nodes are never passed
+     * to the filter. The filter implementation can choose to remove the node
+     * from the stream or to terminate the serialization early.
+     */
+    public LSSerializerFilter getFilter() {
+        return serializer.fDOMFilter;
+    }
 
     /**
-     *  When the application provides a filter, the serializer will call out
-     * to the filter before serializing each Node. Attribute nodes are never
-     * passed to the filter. The filter implementation can choose to remove
-     * the node from the stream or to terminate the serialization early.
+     * When the application provides a filter, the serializer will call out to
+     * the filter before serializing each Node. Attribute nodes are never passed
+     * to the filter. The filter implementation can choose to remove the node
+     * from the stream or to terminate the serialization early.
      */
-    public LSSerializerFilter getFilter(){
-        return serializer.fDOMFilter;
-    }
-    /**
-     *  When the application provides a filter, the serializer will call out
-     * to the filter before serializing each Node. Attribute nodes are never
-     * passed to the filter. The filter implementation can choose to remove
-     * the node from the stream or to terminate the serialization early.
-     */
-    public void setFilter(LSSerializerFilter filter){
+    public void setFilter(LSSerializerFilter filter) {
         serializer.fDOMFilter = filter;
     }
 
@@ -654,56 +607,44 @@
     }//copysettings
 
     /**
-      *  Serialize the specified node as described above in the general
-      * description of the <code>LSSerializer</code> interface. The output
-      * is written to the supplied <code>LSOutput</code>.
-      * <br> When writing to a <code>LSOutput</code>, the encoding is found by
-      * looking at the encoding information that is reachable through the
-      * <code>LSOutput</code> and the item to be written (or its owner
-      * document) in this order:
-      * <ol>
-      * <li> <code>LSOutput.encoding</code>,
-      * </li>
-      * <li>
-      * <code>Document.actualEncoding</code>,
-      * </li>
-      * <li>
-      * <code>Document.xmlEncoding</code>.
-      * </li>
-      * </ol>
-      * <br> If no encoding is reachable through the above properties, a
-      * default encoding of "UTF-8" will be used.
-      * <br> If the specified encoding is not supported an
-      * "unsupported-encoding" error is raised.
-      * <br> If no output is specified in the <code>LSOutput</code>, a
-      * "no-output-specified" error is raised.
-      * @param node  The node to serialize.
-      * @param destination The destination for the serialized DOM.
-      * @return  Returns <code>true</code> if <code>node</code> was
-      *   successfully serialized and <code>false</code> in case the node
-      *   couldn't be serialized.
-      */
-    public boolean write(Node node, LSOutput destination) throws LSException{
+     * Serialize the specified node as described above in the general
+     * description of the <code>LSSerializer</code> interface. The output is
+     * written to the supplied <code>LSOutput</code>.
+     * <br> When writing to a <code>LSOutput</code>, the encoding is found by
+     * looking at the encoding information that is reachable through the
+     * <code>LSOutput</code> and the item to be written (or its owner document)
+     * in this order:
+     * <ol>
+     * <li> <code>LSOutput.encoding</code>,
+     * </li>
+     * <li>
+     * <code>Document.actualEncoding</code>,
+     * </li>
+     * <li>
+     * <code>Document.xmlEncoding</code>.
+     * </li>
+     * </ol>
+     * <br> If no encoding is reachable through the above properties, a default
+     * encoding of "UTF-8" will be used.
+     * <br> If the specified encoding is not supported an "unsupported-encoding"
+     * error is raised.
+     * <br> If no output is specified in the <code>LSOutput</code>, a
+     * "no-output-specified" error is raised.
+     *
+     * @param node The node to serialize.
+     * @param destination The destination for the serialized DOM.
+     * @return Returns <code>true</code> if <code>node</code> was successfully
+     * serialized and <code>false</code> in case the node couldn't be
+     * serialized.
+     */
+    public boolean write(Node node, LSOutput destination) throws LSException {
 
-        if (node == null)
+        if (node == null) {
             return false;
+        }
 
-        Method getVersion = null;
         XMLSerializer ser = null;
-        String ver = null;
-        Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE)
-                ? (Document) node
-                : node.getOwnerDocument();
-        // this should run under JDK 1.1.8...
-        try {
-            getVersion = fDocument.getClass().getMethod("getXmlVersion", new Class[] {});
-            if (getVersion != null) {
-                ver = (String) getVersion.invoke(fDocument, (Object[]) null);
-            }
-        } catch (Exception e) {
-            //no way to test the version...
-            //ignore the exception
-        }
+        String ver = _getXmlVersion(node);
         //determine which serializer to use:
         if (ver != null && ver.equals("1.1")) {
             if (xml11Serializer == null) {
@@ -719,25 +660,9 @@
 
         String encoding = null;
         if ((encoding = destination.getEncoding()) == null) {
-            try {
-                Method getEncoding =
-                    fDocument.getClass().getMethod("getInputEncoding", new Class[] {});
-                if (getEncoding != null) {
-                    encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
-                }
-            } catch (Exception e) {
-                // ignore the exception
-            }
+            encoding = _getInputEncoding(node);
             if (encoding == null) {
-                try {
-                    Method getEncoding =
-                        fDocument.getClass().getMethod("getXmlEncoding", new Class[] {});
-                    if (getEncoding != null) {
-                        encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
-                    }
-                } catch (Exception e) {
-                    // ignore the exception
-                }
+                encoding = _getXmlEncoding(node);
                 if (encoding == null) {
                     encoding = "UTF-8";
                 }
@@ -748,13 +673,13 @@
             ser._format.setEncoding(encoding);
             OutputStream outputStream = destination.getByteStream();
             Writer writer = destination.getCharacterStream();
-            String uri =  destination.getSystemId();
+            String uri = destination.getSystemId();
             if (writer == null) {
                 if (outputStream == null) {
                     if (uri == null) {
                         String msg = DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.SERIALIZER_DOMAIN,
-                            "no-output-specified", null);
+                                DOMMessageFormatter.SERIALIZER_DOMAIN,
+                                "no-output-specified", null);
                         if (ser.fDOMErrorHandler != null) {
                             DOMErrorImpl error = new DOMErrorImpl();
                             error.fType = "no-output-specified";
@@ -763,81 +688,52 @@
                             ser.fDOMErrorHandler.handleError(error);
                         }
                         throw new LSException(LSException.SERIALIZE_ERR, msg);
+                    } else {
+                        ser.setOutputByteStream(XMLEntityManager.createOutputStream(uri));
                     }
-                    else {
-                        // URI was specified. Handle relative URIs.
-                        String expanded = XMLEntityManager.expandSystemId(uri, null, true);
-                        URL url = new URL(expanded != null ? expanded : uri);
-                        OutputStream out = null;
-                        String protocol = url.getProtocol();
-                        String host = url.getHost();
-                        // Use FileOutputStream if this URI is for a local file.
-                        if (protocol.equals("file")
-                            && (host == null || host.length() == 0 || host.equals("localhost"))) {
-                            out = new FileOutputStream(getPathWithoutEscapes(url.getFile()));
-                        }
-                        // Try to write to some other kind of URI. Some protocols
-                        // won't support this, though HTTP should work.
-                        else {
-                            URLConnection urlCon = url.openConnection();
-                            urlCon.setDoInput(false);
-                            urlCon.setDoOutput(true);
-                            urlCon.setUseCaches(false); // Enable tunneling.
-                            if (urlCon instanceof HttpURLConnection) {
-                                // The DOM L3 LS CR says if we are writing to an HTTP URI
-                                // it is to be done with an HTTP PUT.
-                                HttpURLConnection httpCon = (HttpURLConnection) urlCon;
-                                httpCon.setRequestMethod("PUT");
-                            }
-                            out = urlCon.getOutputStream();
-                        }
-                        ser.setOutputByteStream(out);
-                    }
-                }
-                else {
+                } else {
                     // byte stream was specified
                     ser.setOutputByteStream(outputStream);
                 }
-            }
-            else {
+            } else {
                 // character stream is specified
                 ser.setOutputCharStream(writer);
             }
 
-            if (node.getNodeType() == Node.DOCUMENT_NODE)
+            if (node.getNodeType() == Node.DOCUMENT_NODE) {
                 ser.serialize((Document) node);
-            else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
+            } else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
                 ser.serialize((DocumentFragment) node);
-            else if (node.getNodeType() == Node.ELEMENT_NODE)
+            } else if (node.getNodeType() == Node.ELEMENT_NODE) {
                 ser.serialize((Element) node);
-            else if (node.getNodeType() == Node.TEXT_NODE ||
-                    node.getNodeType() == Node.COMMENT_NODE ||
-                    node.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
-                    node.getNodeType() == Node.CDATA_SECTION_NODE ||
-                    node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
+            } else if (node.getNodeType() == Node.TEXT_NODE
+                    || node.getNodeType() == Node.COMMENT_NODE
+                    || node.getNodeType() == Node.ENTITY_REFERENCE_NODE
+                    || node.getNodeType() == Node.CDATA_SECTION_NODE
+                    || node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
                 ser.serialize(node);
+            } else {
+                return false;
             }
-            else
-                return false;
-        } catch( UnsupportedEncodingException ue) {
+        } catch (UnsupportedEncodingException ue) {
             if (ser.fDOMErrorHandler != null) {
                 DOMErrorImpl error = new DOMErrorImpl();
                 error.fException = ue;
-                                error.fType = "unsupported-encoding";
+                error.fType = "unsupported-encoding";
                 error.fMessage = ue.getMessage();
-                                error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
+                error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
                 ser.fDOMErrorHandler.handleError(error);
-                        }
+            }
             throw new LSException(LSException.SERIALIZE_ERR,
-                DOMMessageFormatter.formatMessage(
-                    DOMMessageFormatter.SERIALIZER_DOMAIN,
-                    "unsupported-encoding", null));
-                        //return false;
+                    DOMMessageFormatter.formatMessage(
+                            DOMMessageFormatter.SERIALIZER_DOMAIN,
+                            "unsupported-encoding", null));
+            //return false;
         } catch (LSException lse) {
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            if (e == DOMNormalizer.abort){
+            if (e == DOMNormalizer.abort) {
                 // stopped at user request
                 return false;
             }
@@ -851,62 +747,48 @@
                 ser.fDOMErrorHandler.handleError(error);
 
             }
-            e.printStackTrace();
             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        } finally {
+            ser.clearDocumentState();
         }
         return true;
 
     } //write
 
     /**
-      *  Serialize the specified node as described above in the general
-      * description of the <code>LSSerializer</code> interface. The output
-      * is written to the supplied URI.
-      * <br> When writing to a URI, the encoding is found by looking at the
-      * encoding information that is reachable through the item to be written
-      * (or its owner document) in this order:
-      * <ol>
-      * <li>
-      * <code>Document.inputEncoding</code>,
-      * </li>
-      * <li>
-      * <code>Document.xmlEncoding</code>.
-      * </li>
-      * </ol>
-      * <br> If no encoding is reachable through the above properties, a
-      * default encoding of "UTF-8" will be used.
-      * <br> If the specified encoding is not supported an
-      * "unsupported-encoding" error is raised.
-      * @param node  The node to serialize.
-      * @param URI The URI to write to.
-      * @return  Returns <code>true</code> if <code>node</code> was
-      *   successfully serialized and <code>false</code> in case the node
-      *   couldn't be serialized.
-      */
-    public boolean writeToURI(Node node, String URI) throws LSException{
-        if (node == null){
+     * Serialize the specified node as described above in the general
+     * description of the <code>LSSerializer</code> interface. The output is
+     * written to the supplied URI.
+     * <br> When writing to a URI, the encoding is found by looking at the
+     * encoding information that is reachable through the item to be written (or
+     * its owner document) in this order:
+     * <ol>
+     * <li>
+     * <code>Document.inputEncoding</code>,
+     * </li>
+     * <li>
+     * <code>Document.xmlEncoding</code>.
+     * </li>
+     * </ol>
+     * <br> If no encoding is reachable through the above properties, a default
+     * encoding of "UTF-8" will be used.
+     * <br> If the specified encoding is not supported an "unsupported-encoding"
+     * error is raised.
+     *
+     * @param node The node to serialize.
+     * @param URI The URI to write to.
+     * @return Returns <code>true</code> if <code>node</code> was successfully
+     * serialized and <code>false</code> in case the node couldn't be
+     * serialized.
+     */
+    public boolean writeToURI(Node node, String URI) throws LSException {
+        if (node == null) {
             return false;
         }
 
-        Method getXmlVersion = null;
         XMLSerializer ser = null;
-        String ver = null;
-        String encoding = null;
+        String ver = _getXmlVersion(node);
 
-        Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE)
-                ? (Document) node
-                : node.getOwnerDocument();
-        // this should run under JDK 1.1.8...
-        try {
-            getXmlVersion =
-                fDocument.getClass().getMethod("getXmlVersion", new Class[] {});
-            if (getXmlVersion != null) {
-                ver = (String) getXmlVersion.invoke(fDocument, (Object[]) null);
-            }
-        } catch (Exception e) {
-            // no way to test the version...
-            // ignore the exception
-        }
         if (ver != null && ver.equals("1.1")) {
             if (xml11Serializer == null) {
                 xml11Serializer = new XML11Serializer();
@@ -919,25 +801,9 @@
             ser = serializer;
         }
 
-        try {
-            Method getEncoding =
-                fDocument.getClass().getMethod("getInputEncoding", new Class[] {});
-            if (getEncoding != null) {
-                encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
-            }
-        } catch (Exception e) {
-            // ignore the exception
-        }
+        String encoding = _getInputEncoding(node);
         if (encoding == null) {
-            try {
-                Method getEncoding =
-                    fDocument.getClass().getMethod("getXmlEncoding", new Class[] {});
-                if (getEncoding != null) {
-                    encoding = (String) getEncoding.invoke(fDocument, (Object[]) null);
-                }
-            } catch (Exception e) {
-                // ignore the exception
-            }
+            encoding = _getXmlEncoding(node);
             if (encoding == null) {
                 encoding = "UTF-8";
             }
@@ -946,55 +812,28 @@
         try {
             prepareForSerialization(ser, node);
             ser._format.setEncoding(encoding);
+            ser.setOutputByteStream(XMLEntityManager.createOutputStream(URI));
 
-            // URI was specified. Handle relative URIs.
-            String expanded = XMLEntityManager.expandSystemId(URI, null, true);
-            URL url = new URL(expanded != null ? expanded : URI);
-            OutputStream out = null;
-            String protocol = url.getProtocol();
-            String host = url.getHost();
-            // Use FileOutputStream if this URI is for a local file.
-            if (protocol.equals("file")
-                && (host == null || host.length() == 0 || host.equals("localhost"))) {
-                out = new FileOutputStream(getPathWithoutEscapes(url.getFile()));
+            if (node.getNodeType() == Node.DOCUMENT_NODE) {
+                ser.serialize((Document) node);
+            } else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
+                ser.serialize((DocumentFragment) node);
+            } else if (node.getNodeType() == Node.ELEMENT_NODE) {
+                ser.serialize((Element) node);
+            } else if (node.getNodeType() == Node.TEXT_NODE
+                    || node.getNodeType() == Node.COMMENT_NODE
+                    || node.getNodeType() == Node.ENTITY_REFERENCE_NODE
+                    || node.getNodeType() == Node.CDATA_SECTION_NODE
+                    || node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
+                ser.serialize(node);
+            } else {
+                return false;
             }
-            // Try to write to some other kind of URI. Some protocols
-            // won't support this, though HTTP should work.
-            else {
-                URLConnection urlCon = url.openConnection();
-                urlCon.setDoInput(false);
-                urlCon.setDoOutput(true);
-                urlCon.setUseCaches(false); // Enable tunneling.
-                if (urlCon instanceof HttpURLConnection) {
-                    // The DOM L3 LS CR says if we are writing to an HTTP URI
-                    // it is to be done with an HTTP PUT.
-                    HttpURLConnection httpCon = (HttpURLConnection) urlCon;
-                    httpCon.setRequestMethod("PUT");
-                }
-                out = urlCon.getOutputStream();
-            }
-            ser.setOutputByteStream(out);
-
-            if (node.getNodeType() == Node.DOCUMENT_NODE)
-                ser.serialize((Document) node);
-            else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
-                ser.serialize((DocumentFragment) node);
-            else if (node.getNodeType() == Node.ELEMENT_NODE)
-                ser.serialize((Element) node);
-            else if (node.getNodeType() == Node.TEXT_NODE ||
-                    node.getNodeType() == Node.COMMENT_NODE ||
-                    node.getNodeType() == Node.ENTITY_REFERENCE_NODE ||
-                    node.getNodeType() == Node.CDATA_SECTION_NODE ||
-                    node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) {
-                ser.serialize(node);
-            }
-            else
-                return false;
         } catch (LSException lse) {
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            if (e == DOMNormalizer.abort){
+            if (e == DOMNormalizer.abort) {
                 // stopped at user request
                 return false;
             }
@@ -1008,24 +847,24 @@
                 ser.fDOMErrorHandler.handleError(error);
             }
             throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
+        } finally {
+            ser.clearDocumentState();
         }
         return true;
     } //writeURI
 
-
     //
     //  Private methods
     //
-
     private void prepareForSerialization(XMLSerializer ser, Node node) {
         ser.reset();
         ser.features = features;
         ser.fDOMErrorHandler = fErrorHandler;
         ser.fNamespaces = (features & NAMESPACES) != 0;
         ser.fNamespacePrefixes = (features & NSDECL) != 0;
-        ser._format.setOmitComments((features & COMMENTS)==0);
+        ser._format.setIndenting((features & PRETTY_PRINT) != 0);
+        ser._format.setOmitComments((features & COMMENTS) == 0);
         ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0);
-        ser._format.setIndenting((features & FORMAT_PRETTY_PRINT) != 0);
 
         if ((features & WELLFORMED) != 0) {
             // REVISIT: this is inefficient implementation of well-formness. Instead, we should check
@@ -1034,13 +873,13 @@
             root = node;
             Method versionChanged;
             boolean verifyNames = true;
-            Document document =(node.getNodeType() == Node.DOCUMENT_NODE)
+            Document document = (node.getNodeType() == Node.DOCUMENT_NODE)
                     ? (Document) node
                     : node.getOwnerDocument();
             try {
-                versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class[] {});
+                versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class[]{});
                 if (versionChanged != null) {
-                    verifyNames = ((Boolean)versionChanged.invoke(document, (Object[]) null)).booleanValue();
+                    verifyNames = ((Boolean) versionChanged.invoke(document, (Object[]) null)).booleanValue();
                 }
             } catch (Exception e) {
                 //no way to test the version...
@@ -1053,59 +892,53 @@
                     next = node.getFirstChild();
                     // No child nodes, so walk tree
                     while (next == null) {
-                      // Move to sibling if possible.
-                      next = node.getNextSibling();
-                      if (next == null) {
-                          node = node.getParentNode();
-                          if (root == node){
-                              next = null;
-                              break;
-                          }
-                          next = node.getNextSibling();
-                      }
+                        // Move to sibling if possible.
+                        next = node.getNextSibling();
+                        if (next == null) {
+                            node = node.getParentNode();
+                            if (root == node) {
+                                next = null;
+                                break;
+                            }
+                            next = node.getNextSibling();
+                        }
                     }
                     node = next;
                 }
-            }
-            else {
+            } else {
                 verify(node, verifyNames, false);
             }
         }
     }
 
-
-    private void verify (Node node, boolean verifyNames, boolean xml11Version){
+    private void verify(Node node, boolean verifyNames, boolean xml11Version) {
 
         int type = node.getNodeType();
         fLocator.fRelatedNode = node;
         boolean wellformed;
         switch (type) {
-            case Node.DOCUMENT_NODE:{
+            case Node.DOCUMENT_NODE: {
                 break;
             }
-            case Node.DOCUMENT_TYPE_NODE:{
+            case Node.DOCUMENT_TYPE_NODE: {
                 break;
             }
-            case Node.ELEMENT_NODE:{
-                if (verifyNames){
-                    if((features & NAMESPACES) != 0){
-                        wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), xml11Version) ;
+            case Node.ELEMENT_NODE: {
+                if (verifyNames) {
+                    if ((features & NAMESPACES) != 0) {
+                        wellformed = CoreDocumentImpl.isValidQName(node.getPrefix(), node.getLocalName(), xml11Version);
+                    } else {
+                        wellformed = CoreDocumentImpl.isXMLName(node.getNodeName(), xml11Version);
                     }
-                    else{
-                        wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version);
-                    }
-                    if (!wellformed){
-                            if (!wellformed){
-                                if (fErrorHandler != null) {
-                                    String msg = DOMMessageFormatter.formatMessage(
-                                        DOMMessageFormatter.DOM_DOMAIN,
-                                        "wf-invalid-character-in-node-name",
-                                        new Object[]{"Element", node.getNodeName()});
-                                        DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
-                                        "wf-invalid-character-in-node-name");
-                                }
-
-                            }
+                    if (!wellformed) {
+                        if (fErrorHandler != null) {
+                            String msg = DOMMessageFormatter.formatMessage(
+                                    DOMMessageFormatter.DOM_DOMAIN,
+                                    "wf-invalid-character-in-node-name",
+                                    new Object[]{"Element", node.getNodeName()});
+                            DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
+                                    "wf-invalid-character-in-node-name");
+                        }
                     }
                 }
 
@@ -1114,17 +947,17 @@
                     for (int i = 0; i < attributes.getLength(); ++i) {
                         Attr attr = (Attr) attributes.item(i);
                         fLocator.fRelatedNode = attr;
-                        DOMNormalizer.isAttrValueWF( fErrorHandler, fError, fLocator,
-                                      attributes, attr, attr.getValue(), xml11Version);
+                        DOMNormalizer.isAttrValueWF(fErrorHandler, fError, fLocator,
+                                attributes, attr, attr.getValue(), xml11Version);
                         if (verifyNames) {
-                            wellformed = CoreDocumentImpl.isXMLName( attr.getNodeName(), xml11Version);
+                            wellformed = CoreDocumentImpl.isXMLName(attr.getNodeName(), xml11Version);
                             if (!wellformed) {
-                                    String msg =
-                                        DOMMessageFormatter.formatMessage(
-                                            DOMMessageFormatter.DOM_DOMAIN,
-                                            "wf-invalid-character-in-node-name",
-                                            new Object[] { "Attr", node.getNodeName()});
-                                    DOMNormalizer.reportDOMError( fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
+                                String msg
+                                        = DOMMessageFormatter.formatMessage(
+                                                DOMMessageFormatter.DOM_DOMAIN,
+                                                "wf-invalid-character-in-node-name",
+                                                new Object[]{"Attr", node.getNodeName()});
+                                DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
                                         "wf-invalid-character-in-node-name");
                             }
                         }
@@ -1135,78 +968,156 @@
                 break;
             }
 
-        case Node.COMMENT_NODE: {
-            // only verify well-formness if comments included in the tree
-            if ((features & COMMENTS) != 0)
-                DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment)node).getData(), xml11Version);
-            break;
+            case Node.COMMENT_NODE: {
+                // only verify well-formness if comments included in the tree
+                if ((features & COMMENTS) != 0) {
+                    DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment) node).getData(), xml11Version);
+                }
+                break;
+            }
+            case Node.ENTITY_REFERENCE_NODE: {
+                // only if entity is preserved in the tree
+                if (verifyNames && (features & ENTITIES) != 0) {
+                    CoreDocumentImpl.isXMLName(node.getNodeName(), xml11Version);
+                }
+                break;
+
+            }
+            case Node.CDATA_SECTION_NODE: {
+                // verify content
+                DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
+                // the ]]> string will be checked during serialization
+                break;
+            }
+            case Node.TEXT_NODE: {
+                DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
+                break;
+            }
+            case Node.PROCESSING_INSTRUCTION_NODE: {
+                ProcessingInstruction pinode = (ProcessingInstruction) node;
+                String target = pinode.getTarget();
+                if (verifyNames) {
+                    if (xml11Version) {
+                        wellformed = XML11Char.isXML11ValidName(target);
+                    } else {
+                        wellformed = XMLChar.isValidName(target);
+                    }
+
+                    if (!wellformed) {
+                        String msg
+                                = DOMMessageFormatter.formatMessage(
+                                        DOMMessageFormatter.DOM_DOMAIN,
+                                        "wf-invalid-character-in-node-name",
+                                        new Object[]{"Element", node.getNodeName()});
+                        DOMNormalizer.reportDOMError(
+                                fErrorHandler,
+                                fError,
+                                fLocator,
+                                msg,
+                                DOMError.SEVERITY_FATAL_ERROR,
+                                "wf-invalid-character-in-node-name");
+                    }
+                }
+                DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version);
+                break;
+            }
         }
-        case Node.ENTITY_REFERENCE_NODE: {
-            // only if entity is preserved in the tree
-            if (verifyNames && (features & ENTITIES) != 0){
-                CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version);
+        fLocator.fRelatedNode = null;
+    }
+
+    private String _getXmlVersion(Node node) {
+        Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
+                ? (Document) node : node.getOwnerDocument();
+        if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
+            try {
+                return (String) DocumentMethods.fgDocumentGetXmlVersionMethod.invoke(doc, (Object[]) null);
+            } // The VM ran out of memory or there was some other serious problem. Re-throw.
+            catch (VirtualMachineError vme) {
+                throw vme;
+            } // ThreadDeath should always be re-thrown
+            catch (ThreadDeath td) {
+                throw td;
+            } // Ignore all other exceptions and errors
+            catch (Throwable t) {
             }
-            break;
+        }
+        return null;
+    }
 
+    private String _getInputEncoding(Node node) {
+        Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
+                ? (Document) node : node.getOwnerDocument();
+        if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
+            try {
+                return (String) DocumentMethods.fgDocumentGetInputEncodingMethod.invoke(doc, (Object[]) null);
+            } // The VM ran out of memory or there was some other serious problem. Re-throw.
+            catch (VirtualMachineError vme) {
+                throw vme;
+            } // ThreadDeath should always be re-thrown
+            catch (ThreadDeath td) {
+                throw td;
+            } // Ignore all other exceptions and errors
+            catch (Throwable t) {
+            }
         }
-        case Node.CDATA_SECTION_NODE: {
-            // verify content
-            DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
-            // the ]]> string will be checked during serialization
-            break;
+        return null;
+    }
+
+    private String _getXmlEncoding(Node node) {
+        Document doc = (node.getNodeType() == Node.DOCUMENT_NODE)
+                ? (Document) node : node.getOwnerDocument();
+        if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
+            try {
+                return (String) DocumentMethods.fgDocumentGetXmlEncodingMethod.invoke(doc, (Object[]) null);
+            } // The VM ran out of memory or there was some other serious problem. Re-throw.
+            catch (VirtualMachineError vme) {
+                throw vme;
+            } // ThreadDeath should always be re-thrown
+            catch (ThreadDeath td) {
+                throw td;
+            } // Ignore all other exceptions and errors
+            catch (Throwable t) {
+            }
         }
-        case Node.TEXT_NODE:{
-            DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version);
-            break;
-        }
-        case Node.PROCESSING_INSTRUCTION_NODE:{
-            ProcessingInstruction pinode = (ProcessingInstruction)node ;
-            String target = pinode.getTarget();
-            if (verifyNames) {
-                if (xml11Version) {
-                    wellformed = XML11Char.isXML11ValidName(target);
-                } else {
-                    wellformed = XMLChar.isValidName(target);
-                }
+        return null;
+    }
 
-                if (!wellformed) {
-                    String msg =
-                        DOMMessageFormatter.formatMessage(
-                            DOMMessageFormatter.DOM_DOMAIN,
-                            "wf-invalid-character-in-node-name",
-                            new Object[] { "Element", node.getNodeName()});
-                    DOMNormalizer.reportDOMError(
-                        fErrorHandler,
-                        fError,
-                        fLocator,
-                        msg,
-                        DOMError.SEVERITY_FATAL_ERROR,
-                        "wf-invalid-character-in-node-name");
-                }
-            }
-            DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version);
-            break;
-        }
+    /**
+     * Holder of DOM Level 3 methods from org.w3c.dom.Document.
+     */
+    static class DocumentMethods {
+
+        // Method: org.w3c.dom.Document.getXmlVersion()
+        private static java.lang.reflect.Method fgDocumentGetXmlVersionMethod = null;
+
+        // Method: org.w3c.dom.Document.getInputEncoding()
+        private static java.lang.reflect.Method fgDocumentGetInputEncodingMethod = null;
+
+        // Method: org.w3c.dom.Document.getXmlEncoding()
+        private static java.lang.reflect.Method fgDocumentGetXmlEncodingMethod = null;
+
+        // Flag indicating whether or not Document methods are available.
+        private static boolean fgDocumentMethodsAvailable = false;
+
+        private DocumentMethods() {
         }
 
+        // Attempt to get methods for org.w3c.dom.Document on class initialization.
+        static {
+            try {
+                fgDocumentGetXmlVersionMethod = Document.class.getMethod("getXmlVersion", new Class[]{});
+                fgDocumentGetInputEncodingMethod = Document.class.getMethod("getInputEncoding", new Class[]{});
+                fgDocumentGetXmlEncodingMethod = Document.class.getMethod("getXmlEncoding", new Class[]{});
+                fgDocumentMethodsAvailable = true;
+            } // ClassNotFoundException, NoSuchMethodException or SecurityException
+            // Whatever the case, we cannot retrieve the methods.
+            catch (Exception exc) {
+                fgDocumentGetXmlVersionMethod = null;
+                fgDocumentGetInputEncodingMethod = null;
+                fgDocumentGetXmlEncodingMethod = null;
+                fgDocumentMethodsAvailable = false;
+            }
+        }
     }
 
-    private String getPathWithoutEscapes(String origPath) {
-        if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) {
-            // Locate the escape characters
-            StringTokenizer tokenizer = new StringTokenizer(origPath, "%");
-            StringBuffer result = new StringBuffer(origPath.length());
-            int size = tokenizer.countTokens();
-            result.append(tokenizer.nextToken());
-            for(int i = 1; i < size; ++i) {
-                String token = tokenizer.nextToken();
-                // Decode the 2 digit hexadecimal number following % in '%nn'
-                result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue());
-                result.append(token.substring(2));
-            }
-            return result.toString();
-        }
-        return origPath;
-    }
-
-}//DOMSerializerImpl
+} //DOMSerializerImpl
--- a/jaxp/src/com/sun/org/apache/xml/internal/serialize/XML11Serializer.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serialize/XML11Serializer.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -18,8 +19,6 @@
  * limitations under the License.
  */
 
-
-
 // Sep 14, 2000:
 //  Fixed problem with namespace handling. Contributed by
 //  David Blondeau <blondeau@intalio.com>
@@ -33,22 +32,20 @@
 // Aug 21, 2000:
 //  Added ability to omit DOCTYPE declaration.
 
-
 package com.sun.org.apache.xml.internal.serialize;
 
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Writer;
 
 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
-import com.sun.org.apache.xerces.internal.impl.Constants;
 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 org.w3c.dom.DOMError;
+import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
-import org.w3c.dom.DOMError;
 
 /**
  * Implements an XML serializer supporting both DOM and SAX pretty
@@ -62,9 +59,9 @@
  * The serializer supports both DOM and SAX. SAX serializing is done by firing
  * SAX events and using the serializer as a document handler. DOM serializing is done
  * by calling {@link #serialize(Document)} or by using DOM Level 3
- * {@link org.w3c.dom.ls.DOMSerializer} and
- * serializing with {@link org.w3c.dom.ls.DOMSerializer#write},
- * {@link org.w3c.dom.ls.DOMSerializer#writeToString}.
+ * {@link org.w3c.dom.ls.LSSerializer} and
+ * serializing with {@link org.w3c.dom.ls.LSSerializer#write},
+ * {@link org.w3c.dom.ls.LSSerializer#writeToString}.
  * <p>
  * If an I/O exception occurs while serializing, the serializer
  * will not throw an exception directly, but only throw it
@@ -122,10 +119,6 @@
      */
     protected boolean fNamespaces = false;
 
-
-    private boolean fPreserveSpace;
-
-
     /**
      * Constructs a new serializer. The serializer cannot be used without
      * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
@@ -217,26 +210,27 @@
                     if (!XML11Char.isXML11Valid(ch)) {
                         // check if it is surrogate
                         if (++index < end) {
-                            surrogates(ch, chars[index]);
+                            surrogates(ch, chars[index], true);
                         }
                         else {
-                            fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                            fatalError("The character '"+ch+"' is an invalid XML character");
                         }
                         continue;
-                    } else {
-                        if ( _encodingInfo.isPrintable((char)ch) && XML11Char.isXML11ValidLiteral(ch)) {
-                            _printer.printText((char)ch);
-                        } else {
-                            // The character is not printable -- split CDATA section
-                            _printer.printText("]]>&#x");
-                            _printer.printText(Integer.toHexString(ch));
-                            _printer.printText(";<![CDATA[");
-                        }
+                    }
+                    if ( _encodingInfo.isPrintable(ch) && XML11Char.isXML11ValidLiteral(ch)) {
+                        _printer.printText(ch);
+                    }
+                    else {
+                        // The character is not printable -- split CDATA section
+                        _printer.printText("]]>&#x");
+                        _printer.printText(Integer.toHexString(ch));
+                        _printer.printText(";<![CDATA[");
                     }
                 }
                 _printer.setNextIndent( saveIndent );
 
-            } else {
+            }
+            else {
 
                 int saveIndent;
 
@@ -249,16 +243,17 @@
                     _printer.setNextIndent( 0 );
                     printText( chars, start, length, true, state.unescaped );
                     _printer.setNextIndent( saveIndent );
-                } else {
+                }
+                else {
                     printText( chars, start, length, false, state.unescaped );
                 }
             }
-        } catch ( IOException except ) {
+        }
+        catch ( IOException except ) {
             throw new SAXException( except );
         }
     }
 
-
     //
     // overwrite printing functions to make sure serializer prints out valid XML
     //
@@ -268,25 +263,31 @@
             int ch = source.charAt(i);
             if (!XML11Char.isXML11Valid(ch)) {
                 if (++i <length) {
-                    surrogates(ch, source.charAt(i));
-                } else {
+                    surrogates(ch, source.charAt(i), false);
+                }
+                else {
                     fatalError("The character '"+(char)ch+"' is an invalid XML character");
                 }
                 continue;
             }
-            if (ch == '\n' || ch == '\r' || ch == '\t' || ch == 0x0085 || ch == 0x2028){
-                                printHex(ch);
-                        } else if (ch == '<') {
-                                _printer.printText("&lt;");
-                        } else if (ch == '&') {
-                                _printer.printText("&amp;");
-                        } else if (ch == '"') {
-                                _printer.printText("&quot;");
-                        } else if ((ch >= ' ' && _encodingInfo.isPrintable((char) ch))) {
-                                _printer.printText((char) ch);
-                        } else {
-                                printHex(ch);
-                        }
+            if (ch == '\n' || ch == '\r' || ch == '\t' || ch == 0x0085 || ch == 0x2028) {
+                printHex(ch);
+            }
+            else if (ch == '<') {
+                _printer.printText("&lt;");
+            }
+            else if (ch == '&') {
+                _printer.printText("&amp;");
+            }
+            else if (ch == '"') {
+                _printer.printText("&quot;");
+            }
+            else if ((ch >= ' ' && _encodingInfo.isPrintable((char) ch))) {
+                _printer.printText((char) ch);
+            }
+            else {
+                printHex(ch);
+            }
         }
     }
 
@@ -344,54 +345,55 @@
             if (!XML11Char.isXML11Valid(ch)) {
                 // check if it is surrogate
                 if (++index < length) {
-                    surrogates(ch, text.charAt(index));
-                } else {
-                    fatalError(
-                        "The character '"
-                            + (char) ch
-                            + "' is an invalid XML character");
+                    surrogates(ch, text.charAt(index), true);
+                }
+                else {
+                    fatalError("The character '" + ch + "' is an invalid XML character");
                 }
                 continue;
-            } else {
-                if (_encodingInfo.isPrintable((char) ch)
-                    && XML11Char.isXML11ValidLiteral(ch)) {
-                    _printer.printText((char) ch);
-                } else {
-
-                    // The character is not printable -- split CDATA section
-                    _printer.printText("]]>&#x");
-                    _printer.printText(Integer.toHexString(ch));
-                    _printer.printText(";<![CDATA[");
-                }
+            }
+            if (_encodingInfo.isPrintable(ch)
+                && XML11Char.isXML11ValidLiteral(ch)) {
+                _printer.printText(ch);
+            }
+            else {
+                // The character is not printable -- split CDATA section
+                _printer.printText("]]>&#x");
+                _printer.printText(Integer.toHexString(ch));
+                _printer.printText(";<![CDATA[");
             }
         }
     }
 
-
     // note that this "int" should, in all cases, be a char.
     // REVISIT:  make it a char...
     protected final void printXMLChar( int ch ) throws IOException {
 
         if (ch == '\r' || ch == 0x0085 || ch == 0x2028) {
-                        printHex(ch);
-        } else if ( ch == '<') {
+            printHex(ch);
+        }
+        else if ( ch == '<') {
             _printer.printText("&lt;");
-        } else if (ch == '&') {
+        }
+        else if (ch == '&') {
             _printer.printText("&amp;");
-                } else if (ch == '>'){
-                        // character sequence "]]>" can't appear in content, therefore
-                        // we should escape '>'
-                        _printer.printText("&gt;");
-        } else if ( _encodingInfo.isPrintable((char)ch) && XML11Char.isXML11ValidLiteral(ch)) {
+        }
+        else if (ch == '>'){
+            // character sequence "]]>" can't appear in content, therefore
+            // we should escape '>'
+            _printer.printText("&gt;");
+        }
+        else if ( _encodingInfo.isPrintable((char)ch) && XML11Char.isXML11ValidLiteral(ch)) {
             _printer.printText((char)ch);
-        } else {
-             printHex(ch);
+        }
+        else {
+            printHex(ch);
         }
     }
 
 
 
-    protected final void surrogates(int high, int low) throws IOException{
+    protected final void surrogates(int high, int low, boolean inContent) throws IOException{
         if (XMLChar.isHighSurrogate(high)) {
             if (!XMLChar.isLowSurrogate(low)) {
                 //Invalid XML
@@ -404,7 +406,7 @@
                     fatalError("The character '"+(char)supplemental+"' is an invalid XML character");
                 }
                 else {
-                    if (content().inCData ) {
+                    if (inContent && content().inCData) {
                         _printer.printText("]]>&#x");
                         _printer.printText(Integer.toHexString(supplemental));
                         _printer.printText(";<![CDATA[");
@@ -414,7 +416,8 @@
                     }
                 }
             }
-        } else {
+        }
+        else {
             fatalError("The character '"+(char)high+"' is an invalid XML character");
         }
 
@@ -436,18 +439,21 @@
                 if (!XML11Char.isXML11Valid(ch)) {
                     // check if it is surrogate
                     if (++index <length) {
-                        surrogates(ch, text.charAt(index));
+                        surrogates(ch, text.charAt(index), true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
                 if ( unescaped  && XML11Char.isXML11ValidLiteral(ch)) {
                     _printer.printText( ch );
-                } else
+                }
+                else {
                     printXMLChar( ch );
+                }
             }
-        } else {
+        }
+        else {
             // Not preserving spaces: print one part at a time, and
             // use spaces between parts to break them into different
             // lines. Spaces at beginning of line will be stripped
@@ -458,27 +464,25 @@
                 if (!XML11Char.isXML11Valid(ch)) {
                     // check if it is surrogate
                     if (++index <length) {
-                        surrogates(ch, text.charAt(index));
+                        surrogates(ch, text.charAt(index), true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
 
-                if ( unescaped && XML11Char.isXML11ValidLiteral(ch) )
+                if ( unescaped && XML11Char.isXML11ValidLiteral(ch) ) {
                     _printer.printText( ch );
-                else
-                    printXMLChar( ch);
+                }
+                else {
+                    printXMLChar( ch );
+                }
             }
         }
     }
 
-
-
     protected void printText( char[] chars, int start, int length,
                               boolean preserveSpace, boolean unescaped ) throws IOException {
-        int index;
-        char ch;
 
         if ( preserveSpace ) {
             // Preserving spaces: the text must print exactly as it is,
@@ -486,52 +490,55 @@
             // consolidating spaces. If a line terminator is used, a line
             // break will occur.
             while ( length-- > 0 ) {
-                ch = chars[start++];
+                char ch = chars[start++];
                 if (!XML11Char.isXML11Valid(ch)) {
                     // check if it is surrogate
                     if ( length-- > 0) {
-                        surrogates(ch, chars[start++]);
+                        surrogates(ch, chars[start++], true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
-                if ( unescaped && XML11Char.isXML11ValidLiteral(ch))
+                if ( unescaped && XML11Char.isXML11ValidLiteral(ch)) {
                     _printer.printText( ch );
-                else
+                }
+                else {
                     printXMLChar( ch );
+                }
             }
-        } else {
+        }
+        else {
             // Not preserving spaces: print one part at a time, and
             // use spaces between parts to break them into different
             // lines. Spaces at beginning of line will be stripped
             // by printing mechanism. Line terminator is treated
             // no different than other text part.
             while ( length-- > 0 ) {
-                ch = chars[start++];
+                char ch = chars[start++];
                 if (!XML11Char.isXML11Valid(ch)) {
                     // check if it is surrogate
                     if ( length-- > 0) {
-                        surrogates(ch, chars[start++]);
+                        surrogates(ch, chars[start++], true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
 
-                if ( unescaped && XML11Char.isXML11ValidLiteral(ch))
+                if ( unescaped && XML11Char.isXML11ValidLiteral(ch)) {
                     _printer.printText( ch );
-                else
+                }
+                else {
                     printXMLChar( ch );
+                }
             }
         }
     }
 
-
     public boolean reset() {
         super.reset();
         return true;
-
     }
 
 }
--- a/jaxp/src/com/sun/org/apache/xml/internal/serialize/XMLSerializer.java	Wed Jul 05 19:34:36 2017 +0200
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serialize/XMLSerializer.java	Tue Apr 01 17:27:49 2014 -0700
@@ -3,11 +3,12 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
@@ -18,8 +19,6 @@
  * limitations under the License.
  */
 
-
-
 // Sep 14, 2000:
 //  Fixed problem with namespace handling. Contributed by
 //  David Blondeau <blondeau@intalio.com>
@@ -33,14 +32,13 @@
 // Aug 21, 2000:
 //  Added ability to omit DOCTYPE declaration.
 
-
 package com.sun.org.apache.xml.internal.serialize;
 
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Writer;
-import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
 
 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
@@ -50,6 +48,7 @@
 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMError;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
@@ -71,9 +70,9 @@
  * The serializer supports both DOM and SAX. SAX serializing is done by firing
  * SAX events and using the serializer as a document handler. DOM serializing is done
  * by calling {@link #serialize(Document)} or by using DOM Level 3
- * {@link org.w3c.dom.ls.DOMSerializer} and
- * serializing with {@link org.w3c.dom.ls.DOMSerializer#write},
- * {@link org.w3c.dom.ls.DOMSerializer#writeToString}.
+ * {@link org.w3c.dom.ls.LSSerializer} and
+ * serializing with {@link org.w3c.dom.ls.LSSerializer#write},
+ * {@link org.w3c.dom.ls.LSSerializer#writeToString}.
  * <p>
  * If an I/O exception occurs while serializing, the serializer
  * will not throw an exception directly, but only throw it
@@ -195,7 +194,7 @@
     /**
      * This methods turns on namespace fixup algorithm during
      * DOM serialization.
-     * @see org.w3c.dom.ls.DOMSerializer
+     * @see org.w3c.dom.ls.LSSerializer
      *
      * @param namespaces
      */
@@ -222,7 +221,6 @@
         ElementState state;
         String       name;
         String       value;
-        boolean      addNSAttr = false;
 
         if (DEBUG) {
             System.out.println("==>startElement("+namespaceURI+","+localName+
@@ -277,13 +275,16 @@
                 if (namespaceURI != null && ! namespaceURI.equals( "" )) {
                     String prefix;
                     prefix = getPrefix( namespaceURI );
-                    if (prefix != null && prefix.length() > 0)
+                    if (prefix != null && prefix.length() > 0) {
                         rawName = prefix + ":" + localName;
-                    else
+                    }
+                    else {
                         rawName = localName;
-                } else
+                    }
+                }
+                else {
                     rawName = localName;
-                addNSAttr = true;
+                }
             }
 
             _printer.printText( '<' );
@@ -334,18 +335,18 @@
             }
 
             if (_prefixes != null) {
-                Enumeration keys;
-
-                keys = _prefixes.keys();
-                while (keys.hasMoreElements()) {
+                Iterator entries = _prefixes.entrySet().iterator();
+                while (entries.hasNext()) {
                     _printer.printSpace();
-                    value = (String) keys.nextElement();
-                    name = (String) _prefixes.get( value );
+                    Map.Entry entry = (Map.Entry) entries.next();
+                    value = (String) entry.getKey();
+                    name = (String) entry.getValue();
                     if (name.length() == 0) {
                         _printer.printText( "xmlns=\"" );
                         printEscaped( value );
                         _printer.printText( '"' );
-                    } else {
+                    }
+                    else {
                         _printer.printText( "xmlns:" );
                         _printer.printText( name );
                         _printer.printText( "=\"" );
@@ -770,13 +771,11 @@
                                 //          xmlns:foo = ""
                             }
                             continue;
-                        } else { // xmlns
-                            // empty prefix is always bound ("" or some string)
-
-                            value = fSymbolTable.addSymbol(value);
-                            fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, value);
-                            continue;
                         }
+                        // xmlns --- empty prefix is always bound ("" or some string)
+                        value = fSymbolTable.addSymbol(value);
+                        fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, value);
+                        continue;
                     }  // end-else: valid declaration
                 } // end-if: namespace declaration
             }  // end-for
@@ -958,22 +957,20 @@
                                 //          xmlns:foo = ""
                             }
                             continue;
-                        } else { // xmlns
-                            // empty prefix is always bound ("" or some string)
-
-                            uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);
-                            localUri=fLocalNSBinder.getURI(XMLSymbols.EMPTY_STRING);
-                            value = fSymbolTable.addSymbol(value);
-                            if (localUri == null ){
-                                // declaration was not printed while fixing element namespace binding
-                                if (fNamespacePrefixes) {
-                                    printNamespaceAttr(XMLSymbols.EMPTY_STRING, value);
-                                }
-                                // case 4 does not apply here since attributes can't use
-                                // default namespace
+                        }
+                        // xmlns --- empty prefix is always bound ("" or some string)
+                        uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);
+                        localUri= fLocalNSBinder.getURI(XMLSymbols.EMPTY_STRING);
+                        value = fSymbolTable.addSymbol(value);
+                        if (localUri == null ) {
+                            // declaration was not printed while fixing element namespace binding
+                            if (fNamespacePrefixes) {
+                                printNamespaceAttr(XMLSymbols.EMPTY_STRING, value);
                             }
-                            continue;
+                            // case 4 does not apply here since attributes can't use
+                            // default namespace
                         }
+                        continue;
 
                     }
                     uri = fSymbolTable.addSymbol(uri);
@@ -1195,8 +1192,6 @@
         AttributesImpl attrsOnly;
         String         rawName;
         int            i;
-        int            indexColon;
-        String         prefix;
         int            length;
 
         if (attrs == null) {
@@ -1233,7 +1228,7 @@
             int ch = source.charAt(i);
             if (!XMLChar.isValid(ch)) {
                 if (++i < length) {
-                    surrogates(ch, source.charAt(i));
+                    surrogates(ch, source.charAt(i), false);
                 } else {
                     fatalError("The character '" + (char) ch + "' is an invalid XML character");
                 }
@@ -1291,16 +1286,17 @@
                 if (!XMLChar.isValid(ch)) {
                     // check if it is surrogate
                     if (++index <length) {
-                        surrogates(ch, text.charAt(index));
+                        surrogates(ch, text.charAt(index), true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
                 if ( unescaped ) {
                     _printer.printText( ch );
-                } else
+                } else {
                     printXMLChar( ch );
+                }
             }
         } else {
             // Not preserving spaces: print one part at a time, and
@@ -1313,17 +1309,18 @@
                 if (!XMLChar.isValid(ch)) {
                     // check if it is surrogate
                     if (++index <length) {
-                        surrogates(ch, text.charAt(index));
+                        surrogates(ch, text.charAt(index), true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
 
-                                if ( unescaped )
+                if ( unescaped ) {
                     _printer.printText( ch );
-                else
-                    printXMLChar( ch);
+                } else {
+                    printXMLChar( ch );
+                }
             }
         }
     }
@@ -1332,8 +1329,6 @@
 
     protected void printText( char[] chars, int start, int length,
                               boolean preserveSpace, boolean unescaped ) throws IOException {
-        int index;
-        char ch;
 
         if ( preserveSpace ) {
             // Preserving spaces: the text must print exactly as it is,
@@ -1341,13 +1336,13 @@
             // consolidating spaces. If a line terminator is used, a line
             // break will occur.
             while ( length-- > 0 ) {
-                ch = chars[start++];
+                char ch = chars[start++];
                 if (!XMLChar.isValid(ch)) {
                     // check if it is surrogate
                     if ( length-- > 0 ) {
-                        surrogates(ch, chars[start++]);
+                        surrogates(ch, chars[start++], true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }
@@ -1363,13 +1358,13 @@
             // by printing mechanism. Line terminator is treated
             // no different than other text part.
             while ( length-- > 0 ) {
-                ch = chars[start++];
+                char ch = chars[start++];
                 if (!XMLChar.isValid(ch)) {
                     // check if it is surrogate
                     if ( length-- > 0 ) {
-                        surrogates(ch, chars[start++]);
+                        surrogates(ch, chars[start++], true);
                     } else {
-                        fatalError("The character '"+(char)ch+"' is an invalid XML character");
+                        fatalError("The character '"+ch+"' is an invalid XML character");
                     }
                     continue;
                 }