changeset 6294:3fd3bcc8bd42

8004371: (props) Properties.loadFromXML needs small footprint XML parser as fallback when JAXP is not present Reviewed-by: alanb, mchung, psandoz
author joehw
date Wed, 19 Dec 2012 12:09:10 +0000
parents c79b26b8efe0
children cf15abdcdf88
files src/share/classes/jdk/internal/org/xml/sax/Attributes.java src/share/classes/jdk/internal/org/xml/sax/ContentHandler.java src/share/classes/jdk/internal/org/xml/sax/DTDHandler.java src/share/classes/jdk/internal/org/xml/sax/EntityResolver.java src/share/classes/jdk/internal/org/xml/sax/ErrorHandler.java src/share/classes/jdk/internal/org/xml/sax/InputSource.java src/share/classes/jdk/internal/org/xml/sax/Locator.java src/share/classes/jdk/internal/org/xml/sax/SAXException.java src/share/classes/jdk/internal/org/xml/sax/SAXNotRecognizedException.java src/share/classes/jdk/internal/org/xml/sax/SAXNotSupportedException.java src/share/classes/jdk/internal/org/xml/sax/SAXParseException.java src/share/classes/jdk/internal/org/xml/sax/XMLReader.java src/share/classes/jdk/internal/org/xml/sax/helpers/DefaultHandler.java src/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java src/share/classes/jdk/internal/util/xml/SAXParser.java src/share/classes/jdk/internal/util/xml/XMLStreamException.java src/share/classes/jdk/internal/util/xml/XMLStreamWriter.java src/share/classes/jdk/internal/util/xml/impl/Attrs.java src/share/classes/jdk/internal/util/xml/impl/Input.java src/share/classes/jdk/internal/util/xml/impl/Pair.java src/share/classes/jdk/internal/util/xml/impl/Parser.java src/share/classes/jdk/internal/util/xml/impl/ParserSAX.java src/share/classes/jdk/internal/util/xml/impl/ReaderUTF16.java src/share/classes/jdk/internal/util/xml/impl/ReaderUTF8.java src/share/classes/jdk/internal/util/xml/impl/SAXParserImpl.java src/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java src/share/classes/jdk/internal/util/xml/impl/XMLWriter.java
diffstat 27 files changed, 9851 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/Attributes.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Attributes.java - attribute list with Namespace support
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: Attributes.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Interface for a list of XML attributes.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This interface allows access to a list of attributes in
+ * three different ways:</p>
+ *
+ * <ol>
+ * <li>by attribute index;</li>
+ * <li>by Namespace-qualified name; or</li>
+ * <li>by qualified (prefixed) name.</li>
+ * </ol>
+ *
+ * <p>The list will not contain attributes that were declared
+ * #IMPLIED but not specified in the start tag.  It will also not
+ * contain attributes used as Namespace declarations (xmlns*) unless
+ * the <code>http://xml.org/sax/features/namespace-prefixes</code>
+ * feature is set to <var>true</var> (it is <var>false</var> by
+ * default).
+ * Because SAX2 conforms to the original "Namespaces in XML"
+ * recommendation, it normally does not
+ * give namespace declaration attributes a namespace URI.
+ * </p>
+ *
+ * <p>Some SAX2 parsers may support using an optional feature flag
+ * (<code>http://xml.org/sax/features/xmlns-uris</code>) to request
+ * that those attributes be given URIs, conforming to a later
+ * backwards-incompatible revision of that recommendation.  (The
+ * attribute's "local name" will be the prefix, or "xmlns" when
+ * defining a default element namespace.)  For portability, handler
+ * code should always resolve that conflict, rather than requiring
+ * parsers that can change the setting of that feature flag.  </p>
+ *
+ * <p>If the namespace-prefixes feature (see above) is
+ * <var>false</var>, access by qualified name may not be available; if
+ * the <code>http://xml.org/sax/features/namespaces</code> feature is
+ * <var>false</var>, access by Namespace-qualified names may not be
+ * available.</p>
+ *
+ * <p>This interface replaces the now-deprecated SAX1 {@link
+ * org.xml.sax.AttributeList AttributeList} interface, which does not
+ * contain Namespace support.  In addition to Namespace support, it
+ * adds the <var>getIndex</var> methods (below).</p>
+ *
+ * <p>The order of attributes in the list is unspecified, and will
+ * vary from implementation to implementation.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.helpers.AttributesImpl
+ * @see org.xml.sax.ext.DeclHandler#attributeDecl
+ */
+public interface Attributes
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Indexed access.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Return the number of attributes in the list.
+     *
+     * <p>Once you know the number of attributes, you can iterate
+     * through the list.</p>
+     *
+     * @return The number of attributes in the list.
+     * @see #getURI(int)
+     * @see #getLocalName(int)
+     * @see #getQName(int)
+     * @see #getType(int)
+     * @see #getValue(int)
+     */
+    public abstract int getLength ();
+
+
+    /**
+     * Look up an attribute's Namespace URI by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The Namespace URI, or the empty string if none
+     *         is available, or null if the index is out of
+     *         range.
+     * @see #getLength
+     */
+    public abstract String getURI (int index);
+
+
+    /**
+     * Look up an attribute's local name by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The local name, or the empty string if Namespace
+     *         processing is not being performed, or null
+     *         if the index is out of range.
+     * @see #getLength
+     */
+    public abstract String getLocalName (int index);
+
+
+    /**
+     * Look up an attribute's XML qualified (prefixed) name by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The XML qualified name, or the empty string
+     *         if none is available, or null if the index
+     *         is out of range.
+     * @see #getLength
+     */
+    public abstract String getQName (int index);
+
+
+    /**
+     * Look up an attribute's type by index.
+     *
+     * <p>The attribute type is one of the strings "CDATA", "ID",
+     * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+     * or "NOTATION" (always in upper case).</p>
+     *
+     * <p>If the parser has not read a declaration for the attribute,
+     * or if the parser does not report attribute types, then it must
+     * return the value "CDATA" as stated in the XML 1.0 Recommendation
+     * (clause 3.3.3, "Attribute-Value Normalization").</p>
+     *
+     * <p>For an enumerated attribute that is not a notation, the
+     * parser will report the type as "NMTOKEN".</p>
+     *
+     * @param index The attribute index (zero-based).
+     * @return The attribute's type as a string, or null if the
+     *         index is out of range.
+     * @see #getLength
+     */
+    public abstract String getType (int index);
+
+
+    /**
+     * Look up an attribute's value by index.
+     *
+     * <p>If the attribute value is a list of tokens (IDREFS,
+     * ENTITIES, or NMTOKENS), the tokens will be concatenated
+     * into a single string with each token separated by a
+     * single space.</p>
+     *
+     * @param index The attribute index (zero-based).
+     * @return The attribute's value as a string, or null if the
+     *         index is out of range.
+     * @see #getLength
+     */
+    public abstract String getValue (int index);
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Name-based query.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Look up the index of an attribute by Namespace name.
+     *
+     * @param uri The Namespace URI, or the empty string if
+     *        the name has no Namespace URI.
+     * @param localName The attribute's local name.
+     * @return The index of the attribute, or -1 if it does not
+     *         appear in the list.
+     */
+    public int getIndex (String uri, String localName);
+
+
+    /**
+     * Look up the index of an attribute by XML qualified (prefixed) name.
+     *
+     * @param qName The qualified (prefixed) name.
+     * @return The index of the attribute, or -1 if it does not
+     *         appear in the list.
+     */
+    public int getIndex (String qName);
+
+
+    /**
+     * Look up an attribute's type by Namespace name.
+     *
+     * <p>See {@link #getType(int) getType(int)} for a description
+     * of the possible types.</p>
+     *
+     * @param uri The Namespace URI, or the empty String if the
+     *        name has no Namespace URI.
+     * @param localName The local name of the attribute.
+     * @return The attribute type as a string, or null if the
+     *         attribute is not in the list or if Namespace
+     *         processing is not being performed.
+     */
+    public abstract String getType (String uri, String localName);
+
+
+    /**
+     * Look up an attribute's type by XML qualified (prefixed) name.
+     *
+     * <p>See {@link #getType(int) getType(int)} for a description
+     * of the possible types.</p>
+     *
+     * @param qName The XML qualified name.
+     * @return The attribute type as a string, or null if the
+     *         attribute is not in the list or if qualified names
+     *         are not available.
+     */
+    public abstract String getType (String qName);
+
+
+    /**
+     * Look up an attribute's value by Namespace name.
+     *
+     * <p>See {@link #getValue(int) getValue(int)} for a description
+     * of the possible values.</p>
+     *
+     * @param uri The Namespace URI, or the empty String if the
+     *        name has no Namespace URI.
+     * @param localName The local name of the attribute.
+     * @return The attribute value as a string, or null if the
+     *         attribute is not in the list.
+     */
+    public abstract String getValue (String uri, String localName);
+
+
+    /**
+     * Look up an attribute's value by XML qualified (prefixed) name.
+     *
+     * <p>See {@link #getValue(int) getValue(int)} for a description
+     * of the possible values.</p>
+     *
+     * @param qName The XML qualified name.
+     * @return The attribute value as a string, or null if the
+     *         attribute is not in the list or if qualified names
+     *         are not available.
+     */
+    public abstract String getValue (String qName);
+
+}
+
+// end of Attributes.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/ContentHandler.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// ContentHandler.java - handle main document content.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: ContentHandler.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Receive notification of the logical content of a document.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is the main interface that most SAX applications
+ * implement: if the application needs to be informed of basic parsing
+ * events, it implements this interface and registers an instance with
+ * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler
+ * setContentHandler} method.  The parser uses the instance to report
+ * basic document-related events like the start and end of elements
+ * and character data.</p>
+ *
+ * <p>The order of events in this interface is very important, and
+ * mirrors the order of information in the document itself.  For
+ * example, all of an element's content (character data, processing
+ * instructions, and/or subelements) will appear, in order, between
+ * the startElement event and the corresponding endElement event.</p>
+ *
+ * <p>This interface is similar to the now-deprecated SAX 1.0
+ * DocumentHandler interface, but it adds support for Namespaces
+ * and for reporting skipped entities (in non-validating XML
+ * processors).</p>
+ *
+ * <p>Implementors should note that there is also a
+ * <code>ContentHandler</code> class in the <code>java.net</code>
+ * package; that means that it's probably a bad idea to do</p>
+ *
+ * <pre>import java.net.*;
+ * import org.xml.sax.*;
+ * </pre>
+ *
+ * <p>In fact, "import ...*" is usually a sign of sloppy programming
+ * anyway, so the user should consider this a feature rather than a
+ * bug.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public interface ContentHandler
+{
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     *
+     * <p>SAX parsers are strongly encouraged (though not absolutely
+     * required) to supply a locator: if it does so, it must supply
+     * the locator to the application by invoking this method before
+     * invoking any of the other methods in the ContentHandler
+     * interface.</p>
+     *
+     * <p>The locator allows the application to determine the end
+     * position of any document-related event, even if the parser is
+     * not reporting an error.  Typically, the application will
+     * use this information for reporting its own errors (such as
+     * character content that does not match an application's
+     * business rules).  The information returned by the locator
+     * is probably not sufficient for use with a search engine.</p>
+     *
+     * <p>Note that the locator will return correct information only
+     * during the invocation SAX event callbacks after
+     * {@link #startDocument startDocument} returns and before
+     * {@link #endDocument endDocument} is called.  The
+     * application should not attempt to use it at any other time.</p>
+     *
+     * @param locator an object that can return the location of
+     *                any SAX document event
+     * @see org.xml.sax.Locator
+     */
+    public void setDocumentLocator (Locator locator);
+
+
+    /**
+     * Receive notification of the beginning of a document.
+     *
+     * <p>The SAX parser will invoke this method only once, before any
+     * other event callbacks (except for {@link #setDocumentLocator
+     * setDocumentLocator}).</p>
+     *
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see #endDocument
+     */
+    public void startDocument ()
+        throws SAXException;
+
+
+    /**
+     * Receive notification of the end of a document.
+     *
+     * <p><strong>There is an apparent contradiction between the
+     * documentation for this method and the documentation for {@link
+     * org.xml.sax.ErrorHandler#fatalError}.  Until this ambiguity is
+     * resolved in a future major release, clients should make no
+     * assumptions about whether endDocument() will or will not be
+     * invoked when the parser has reported a fatalError() or thrown
+     * an exception.</strong></p>
+     *
+     * <p>The SAX parser will invoke this method only once, and it will
+     * be the last method invoked during the parse.  The parser shall
+     * not invoke this method until it has either abandoned parsing
+     * (because of an unrecoverable error) or reached the end of
+     * input.</p>
+     *
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see #startDocument
+     */
+    public void endDocument()
+        throws SAXException;
+
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * <p>The information from this event is not necessary for
+     * normal Namespace processing: the SAX XML reader will
+     * automatically replace prefixes for element and attribute
+     * names when the <code>http://xml.org/sax/features/namespaces</code>
+     * feature is <var>true</var> (the default).</p>
+     *
+     * <p>There are cases, however, when applications need to
+     * use prefixes in character data or in attribute values,
+     * where they cannot safely be expanded automatically; the
+     * start/endPrefixMapping event supplies the information
+     * to the application to expand prefixes in those contexts
+     * itself, if necessary.</p>
+     *
+     * <p>Note that start/endPrefixMapping events are not
+     * guaranteed to be properly nested relative to each other:
+     * all startPrefixMapping events will occur immediately before the
+     * corresponding {@link #startElement startElement} event,
+     * and all {@link #endPrefixMapping endPrefixMapping}
+     * events will occur immediately after the corresponding
+     * {@link #endElement endElement} event,
+     * but their order is not otherwise
+     * guaranteed.</p>
+     *
+     * <p>There should never be start/endPrefixMapping events for the
+     * "xml" prefix, since it is predeclared and immutable.</p>
+     *
+     * @param prefix the Namespace prefix being declared.
+     *  An empty string is used for the default element namespace,
+     *  which has no prefix.
+     * @param uri the Namespace URI the prefix is mapped to
+     * @throws org.xml.sax.SAXException the client may throw
+     *            an exception during processing
+     * @see #endPrefixMapping
+     * @see #startElement
+     */
+    public void startPrefixMapping (String prefix, String uri)
+        throws SAXException;
+
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     *
+     * <p>See {@link #startPrefixMapping startPrefixMapping} for
+     * details.  These events will always occur immediately after the
+     * corresponding {@link #endElement endElement} event, but the order of
+     * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
+     * guaranteed.</p>
+     *
+     * @param prefix the prefix that was being mapped.
+     *  This is the empty string when a default mapping scope ends.
+     * @throws org.xml.sax.SAXException the client may throw
+     *            an exception during processing
+     * @see #startPrefixMapping
+     * @see #endElement
+     */
+    public void endPrefixMapping (String prefix)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * <p>The Parser will invoke this method at the beginning of every
+     * element in the XML document; there will be a corresponding
+     * {@link #endElement endElement} event for every startElement event
+     * (even when the element is empty). All of the element's content will be
+     * reported, in order, before the corresponding endElement
+     * event.</p>
+     *
+     * <p>This event allows up to three name components for each
+     * element:</p>
+     *
+     * <ol>
+     * <li>the Namespace URI;</li>
+     * <li>the local name; and</li>
+     * <li>the qualified (prefixed) name.</li>
+     * </ol>
+     *
+     * <p>Any or all of these may be provided, depending on the
+     * values of the <var>http://xml.org/sax/features/namespaces</var>
+     * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+     * properties:</p>
+     *
+     * <ul>
+     * <li>the Namespace URI and local name are required when
+     * the namespaces property is <var>true</var> (the default), and are
+     * optional when the namespaces property is <var>false</var> (if one is
+     * specified, both must be);</li>
+     * <li>the qualified name is required when the namespace-prefixes property
+     * is <var>true</var>, and is optional when the namespace-prefixes property
+     * is <var>false</var> (the default).</li>
+     * </ul>
+     *
+     * <p>Note that the attribute list provided will contain only
+     * attributes with explicit values (specified or defaulted):
+     * #IMPLIED attributes will be omitted.  The attribute list
+     * will contain attributes used for Namespace declarations
+     * (xmlns* attributes) only if the
+     * <code>http://xml.org/sax/features/namespace-prefixes</code>
+     * property is true (it is false by default, and support for a
+     * true value is optional).</p>
+     *
+     * <p>Like {@link #characters characters()}, attribute values may have
+     * characters that need more than one <code>char</code> value.  </p>
+     *
+     * @param uri the Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed
+     * @param localName the local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed
+     * @param qName the qualified name (with prefix), or the
+     *        empty string if qualified names are not available
+     * @param atts the attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.  The value of this object after
+     *        startElement returns is undefined
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see #endElement
+     * @see org.xml.sax.Attributes
+     * @see org.xml.sax.helpers.AttributesImpl
+     */
+    public void startElement (String uri, String localName,
+                              String qName, Attributes atts)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * <p>The SAX parser will invoke this method at the end of every
+     * element in the XML document; there will be a corresponding
+     * {@link #startElement startElement} event for every endElement
+     * event (even when the element is empty).</p>
+     *
+     * <p>For information on the names, see startElement.</p>
+     *
+     * @param uri the Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed
+     * @param localName the local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed
+     * @param qName the qualified XML name (with prefix), or the
+     *        empty string if qualified names are not available
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    public void endElement (String uri, String localName,
+                            String qName)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of character data.
+     *
+     * <p>The Parser will call this method to report each chunk of
+     * character data.  SAX parsers may return all contiguous character
+     * data in a single chunk, or they may split it into several
+     * chunks; however, all of the characters in any single event
+     * must come from the same external entity so that the Locator
+     * provides useful information.</p>
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * <p>Individual characters may consist of more than one Java
+     * <code>char</code> value.  There are two important cases where this
+     * happens, because characters can't be represented in just sixteen bits.
+     * In one case, characters are represented in a <em>Surrogate Pair</em>,
+     * using two special Unicode values. Such characters are in the so-called
+     * "Astral Planes", with a code point above U+FFFF.  A second case involves
+     * composite characters, such as a base character combining with one or
+     * more accent characters. </p>
+     *
+     * <p> Your code should not assume that algorithms using
+     * <code>char</code>-at-a-time idioms will be working in character
+     * units; in some cases they will split characters.  This is relevant
+     * wherever XML permits arbitrary characters, such as attribute values,
+     * processing instruction data, and comments as well as in data reported
+     * from this method.  It's also generally relevant whenever Java code
+     * manipulates internationalized text; the issue isn't unique to XML.</p>
+     *
+     * <p>Note that some parsers will report whitespace in element
+     * content using the {@link #ignorableWhitespace ignorableWhitespace}
+     * method rather than this one (validating parsers <em>must</em>
+     * do so).</p>
+     *
+     * @param ch the characters from the XML document
+     * @param start the start position in the array
+     * @param length the number of characters to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see #ignorableWhitespace
+     * @see org.xml.sax.Locator
+     */
+    public void characters (char ch[], int start, int length)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * <p>Validating Parsers must use this method to report each chunk
+     * of whitespace in element content (see the W3C XML 1.0
+     * recommendation, section 2.10): non-validating parsers may also
+     * use this method if they are capable of parsing and using
+     * content models.</p>
+     *
+     * <p>SAX parsers may return all contiguous whitespace in a single
+     * chunk, or they may split it into several chunks; however, all of
+     * the characters in any single event must come from the same
+     * external entity, so that the Locator provides useful
+     * information.</p>
+     *
+     * <p>The application must not attempt to read from the array
+     * outside of the specified range.</p>
+     *
+     * @param ch the characters from the XML document
+     * @param start the start position in the array
+     * @param length the number of characters to read from the array
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     * @see #characters
+     */
+    public void ignorableWhitespace (char ch[], int start, int length)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * <p>The Parser will invoke this method once for each processing
+     * instruction found: note that processing instructions may occur
+     * before or after the main document element.</p>
+     *
+     * <p>A SAX parser must never report an XML declaration (XML 1.0,
+     * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+     * using this method.</p>
+     *
+     * <p>Like {@link #characters characters()}, processing instruction
+     * data may have characters that need more than one <code>char</code>
+     * value. </p>
+     *
+     * @param target the processing instruction target
+     * @param data the processing instruction data, or null if
+     *        none was supplied.  The data does not include any
+     *        whitespace separating it from the target
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    public void processingInstruction (String target, String data)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of a skipped entity.
+     * This is not called for entity references within markup constructs
+     * such as element start tags or markup declarations.  (The XML
+     * recommendation requires reporting skipped external entities.
+     * SAX also reports internal entity expansion/non-expansion, except
+     * within markup constructs.)
+     *
+     * <p>The Parser will invoke this method each time the entity is
+     * skipped.  Non-validating processors may skip entities if they
+     * have not seen the declarations (because, for example, the
+     * entity was declared in an external DTD subset).  All processors
+     * may skip external entities, depending on the values of the
+     * <code>http://xml.org/sax/features/external-general-entities</code>
+     * and the
+     * <code>http://xml.org/sax/features/external-parameter-entities</code>
+     * properties.</p>
+     *
+     * @param name the name of the skipped entity.  If it is a
+     *        parameter entity, the name will begin with '%', and if
+     *        it is the external DTD subset, it will be the string
+     *        "[dtd]"
+     * @throws org.xml.sax.SAXException any SAX exception, possibly
+     *            wrapping another exception
+     */
+    public void skippedEntity (String name)
+        throws SAXException;
+}
+
+// end of ContentHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/DTDHandler.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX DTD handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DTDHandler.java,v 1.2 2004/11/03 22:44:51 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Receive notification of basic DTD-related events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs information about notations and
+ * unparsed entities, then the application implements this
+ * interface and registers an instance with the SAX parser using
+ * the parser's setDTDHandler method.  The parser uses the
+ * instance to report notation and unparsed entity declarations to
+ * the application.</p>
+ *
+ * <p>Note that this interface includes only those DTD events that
+ * the XML recommendation <em>requires</em> processors to report:
+ * notation and unparsed entity declarations.</p>
+ *
+ * <p>The SAX parser may report these events in any order, regardless
+ * of the order in which the notations and unparsed entities were
+ * declared; however, all DTD events must be reported after the
+ * document handler's startDocument event, and before the first
+ * startElement event.
+ * (If the {@link org.xml.sax.ext.LexicalHandler LexicalHandler} is
+ * used, these events must also be reported before the endDTD event.)
+ * </p>
+ *
+ * <p>It is up to the application to store the information for
+ * future use (perhaps in a hash table or object tree).
+ * If the application encounters attributes of type "NOTATION",
+ * "ENTITY", or "ENTITIES", it can use the information that it
+ * obtained through this interface to find the entity and/or
+ * notation corresponding with the attribute value.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setDTDHandler
+ */
+public interface DTDHandler {
+
+
+    /**
+     * Receive notification of a notation declaration event.
+     *
+     * <p>It is up to the application to record the notation for later
+     * reference, if necessary;
+     * notations may appear as attribute values and in unparsed entity
+     * declarations, and are sometime used with processing instruction
+     * target names.</p>
+     *
+     * <p>At least one of publicId and systemId must be non-null.
+     * If a system identifier is present, and it is a URL, the SAX
+     * parser must resolve it fully before passing it to the
+     * application through this event.</p>
+     *
+     * <p>There is no guarantee that the notation declaration will be
+     * reported before any unparsed entities that use it.</p>
+     *
+     * @param name The notation name.
+     * @param publicId The notation's public identifier, or null if
+     *        none was given.
+     * @param systemId The notation's system identifier, or null if
+     *        none was given.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #unparsedEntityDecl
+     * @see org.xml.sax.Attributes
+     */
+    public abstract void notationDecl (String name,
+                                       String publicId,
+                                       String systemId)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of an unparsed entity declaration event.
+     *
+     * <p>Note that the notation name corresponds to a notation
+     * reported by the {@link #notationDecl notationDecl} event.
+     * It is up to the application to record the entity for later
+     * reference, if necessary;
+     * unparsed entities may appear as attribute values.
+     * </p>
+     *
+     * <p>If the system identifier is a URL, the parser must resolve it
+     * fully before passing it to the application.</p>
+     *
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @param name The unparsed entity's name.
+     * @param publicId The entity's public identifier, or null if none
+     *        was given.
+     * @param systemId The entity's system identifier.
+     * @param notationName The name of the associated notation.
+     * @see #notationDecl
+     * @see org.xml.sax.Attributes
+     */
+    public abstract void unparsedEntityDecl (String name,
+                                             String publicId,
+                                             String systemId,
+                                             String notationName)
+        throws SAXException;
+
+}
+
+// end of DTDHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/EntityResolver.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver.java,v 1.2 2004/11/03 22:44:52 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Basic interface for resolving entities.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized handling
+ * for external entities, it must implement this interface and
+ * register an instance with the SAX driver using the
+ * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver}
+ * method.</p>
+ *
+ * <p>The XML reader will then allow the application to intercept any
+ * external entities (including the external DTD subset and external
+ * parameter entities, if any) before including them.</p>
+ *
+ * <p>Many SAX applications will not need to implement this interface,
+ * but it will be especially useful for applications that build
+ * XML documents from databases or other specialised input sources,
+ * or for applications that use URI types other than URLs.</p>
+ *
+ * <p>The following resolver would provide the application
+ * with a special character stream for the entity with the system
+ * identifier "http://www.myhost.com/today":</p>
+ *
+ * <pre>
+ * import org.xml.sax.EntityResolver;
+ * import org.xml.sax.InputSource;
+ *
+ * public class MyResolver implements EntityResolver {
+ *   public InputSource resolveEntity (String publicId, String systemId)
+ *   {
+ *     if (systemId.equals("http://www.myhost.com/today")) {
+ *              // return a special input source
+ *       MyReader reader = new MyReader();
+ *       return new InputSource(reader);
+ *     } else {
+ *              // use the default behaviour
+ *       return null;
+ *     }
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>The application can also use this interface to redirect system
+ * identifiers to local URIs or to look up replacements in a catalog
+ * (possibly by using the public identifier).</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ * @see org.xml.sax.InputSource
+ */
+public interface EntityResolver {
+
+
+    /**
+     * Allow the application to resolve external entities.
+     *
+     * <p>The parser will call this method before opening any external
+     * entity except the top-level document entity.  Such entities include
+     * the external DTD subset and external parameter entities referenced
+     * within the DTD (in either case, only if the parser reads external
+     * parameter entities), and external general entities referenced
+     * within the document element (if the parser reads external general
+     * entities).  The application may request that the parser locate
+     * the entity itself, that it use an alternative URI, or that it
+     * use data provided by the application (as a character or byte
+     * input stream).</p>
+     *
+     * <p>Application writers can use this method to redirect external
+     * system identifiers to secure and/or local URIs, to look up
+     * public identifiers in a catalogue, or to read an entity from a
+     * database or other input source (including, for example, a dialog
+     * box).  Neither XML nor SAX specifies a preferred policy for using
+     * public or system IDs to resolve resources.  However, SAX specifies
+     * how to interpret any InputSource returned by this method, and that
+     * if none is returned, then the system ID will be dereferenced as
+     * a URL.  </p>
+     *
+     * <p>If the system identifier is a URL, the SAX parser must
+     * resolve it fully before reporting it to the application.</p>
+     *
+     * @param publicId The public identifier of the external entity
+     *        being referenced, or null if none was supplied.
+     * @param systemId The system identifier of the external entity
+     *        being referenced.
+     * @return An InputSource object describing the new input source,
+     *         or null to request that the parser open a regular
+     *         URI connection to the system identifier.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @exception java.io.IOException A Java-specific IO exception,
+     *            possibly the result of creating a new InputStream
+     *            or Reader for the InputSource.
+     * @see org.xml.sax.InputSource
+     */
+    public abstract InputSource resolveEntity (String publicId,
+                                               String systemId)
+        throws SAXException, IOException;
+
+}
+
+// end of EntityResolver.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/ErrorHandler.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX error handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ErrorHandler.java,v 1.2 2004/11/03 22:44:52 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Basic interface for SAX error handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized error
+ * handling, it must implement this interface and then register an
+ * instance with the XML reader using the
+ * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler}
+ * method.  The parser will then report all errors and warnings
+ * through this interface.</p>
+ *
+ * <p><strong>WARNING:</strong> If an application does <em>not</em>
+ * register an ErrorHandler, XML parsing errors will go unreported,
+ * except that <em>SAXParseException</em>s will be thrown for fatal errors.
+ * In order to detect validity errors, an ErrorHandler that does something
+ * with {@link #error error()} calls must be registered.</p>
+ *
+ * <p>For XML processing errors, a SAX driver must use this interface
+ * in preference to throwing an exception: it is up to the application
+ * to decide whether to throw an exception for different types of
+ * errors and warnings.  Note, however, that there is no requirement that
+ * the parser continue to report additional errors after a call to
+ * {@link #fatalError fatalError}.  In other words, a SAX driver class
+ * may throw an exception after reporting any fatalError.
+ * Also parsers may throw appropriate exceptions for non-XML errors.
+ * For example, {@link XMLReader#parse XMLReader.parse()} would throw
+ * an IOException for errors accessing entities or the document.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#setErrorHandler
+ * @see org.xml.sax.SAXParseException
+ */
+public interface ErrorHandler {
+
+
+    /**
+     * Receive notification of a warning.
+     *
+     * <p>SAX parsers will use this method to report conditions that
+     * are not errors or fatal errors as defined by the XML
+     * recommendation.  The default behaviour is to take no
+     * action.</p>
+     *
+     * <p>The SAX parser must continue to provide normal parsing events
+     * after invoking this method: it should still be possible for the
+     * application to process the document through to the end.</p>
+     *
+     * <p>Filters may use this method to report other, non-XML warnings
+     * as well.</p>
+     *
+     * @param exception The warning information encapsulated in a
+     *                  SAX parse exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.SAXParseException
+     */
+    public abstract void warning (SAXParseException exception)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of a recoverable error.
+     *
+     * <p>This corresponds to the definition of "error" in section 1.2
+     * of the W3C XML 1.0 Recommendation.  For example, a validating
+     * parser would use this callback to report the violation of a
+     * validity constraint.  The default behaviour is to take no
+     * action.</p>
+     *
+     * <p>The SAX parser must continue to provide normal parsing
+     * events after invoking this method: it should still be possible
+     * for the application to process the document through to the end.
+     * If the application cannot do so, then the parser should report
+     * a fatal error even if the XML recommendation does not require
+     * it to do so.</p>
+     *
+     * <p>Filters may use this method to report other, non-XML errors
+     * as well.</p>
+     *
+     * @param exception The error information encapsulated in a
+     *                  SAX parse exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.SAXParseException
+     */
+    public abstract void error (SAXParseException exception)
+        throws SAXException;
+
+
+    /**
+     * Receive notification of a non-recoverable error.
+     *
+     * <p><strong>There is an apparent contradiction between the
+     * documentation for this method and the documentation for {@link
+     * org.xml.sax.ContentHandler#endDocument}.  Until this ambiguity
+     * is resolved in a future major release, clients should make no
+     * assumptions about whether endDocument() will or will not be
+     * invoked when the parser has reported a fatalError() or thrown
+     * an exception.</strong></p>
+     *
+     * <p>This corresponds to the definition of "fatal error" in
+     * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
+     * parser would use this callback to report the violation of a
+     * well-formedness constraint.</p>
+     *
+     * <p>The application must assume that the document is unusable
+     * after the parser has invoked this method, and should continue
+     * (if at all) only for the sake of collecting additional error
+     * messages: in fact, SAX parsers are free to stop reporting any
+     * other events once this method has been invoked.</p>
+     *
+     * @param exception The error information encapsulated in a
+     *                  SAX parse exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.SAXParseException
+     */
+    public abstract void fatalError (SAXParseException exception)
+        throws SAXException;
+
+}
+
+// end of ErrorHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/InputSource.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX input source.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: InputSource.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.Reader;
+import java.io.InputStream;
+
+/**
+ * A single input source for an XML entity.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class allows a SAX application to encapsulate information
+ * about an input source in a single object, which may include
+ * a public identifier, a system identifier, a byte stream (possibly
+ * with a specified encoding), and/or a character stream.</p>
+ *
+ * <p>There are two places that the application can deliver an
+ * input source to the parser: as the argument to the Parser.parse
+ * method, or as the return value of the EntityResolver.resolveEntity
+ * method.</p>
+ *
+ * <p>The SAX parser will use the InputSource object to determine how
+ * to read XML input.  If there is a character stream available, the
+ * parser will read that stream directly, disregarding any text
+ * encoding declaration found in that stream.
+ * If there is no character stream, but there is
+ * a byte stream, the parser will use that byte stream, using the
+ * encoding specified in the InputSource or else (if no encoding is
+ * specified) autodetecting the character encoding using an algorithm
+ * such as the one in the XML specification.  If neither a character
+ * stream nor a
+ * byte stream is available, the parser will attempt to open a URI
+ * connection to the resource identified by the system
+ * identifier.</p>
+ *
+ * <p>An InputSource object belongs to the application: the SAX parser
+ * shall never modify it in any way (it may modify a copy if
+ * necessary).  However, standard processing of both byte and
+ * character streams is to close them on as part of end-of-parse cleanup,
+ * so applications should not attempt to re-use such streams after they
+ * have been handed to a parser.  </p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ * @see java.io.InputStream
+ * @see java.io.Reader
+ */
+public class InputSource {
+
+    /**
+     * Zero-argument default constructor.
+     *
+     * @see #setPublicId
+     * @see #setSystemId
+     * @see #setByteStream
+     * @see #setCharacterStream
+     * @see #setEncoding
+     */
+    public InputSource ()
+    {
+    }
+
+
+    /**
+     * Create a new input source with a system identifier.
+     *
+     * <p>Applications may use setPublicId to include a
+     * public identifier as well, or setEncoding to specify
+     * the character encoding, if known.</p>
+     *
+     * <p>If the system identifier is a URL, it must be fully
+     * resolved (it may not be a relative URL).</p>
+     *
+     * @param systemId The system identifier (URI).
+     * @see #setPublicId
+     * @see #setSystemId
+     * @see #setByteStream
+     * @see #setEncoding
+     * @see #setCharacterStream
+     */
+    public InputSource (String systemId)
+    {
+        setSystemId(systemId);
+    }
+
+
+    /**
+     * Create a new input source with a byte stream.
+     *
+     * <p>Application writers should use setSystemId() to provide a base
+     * for resolving relative URIs, may use setPublicId to include a
+     * public identifier, and may use setEncoding to specify the object's
+     * character encoding.</p>
+     *
+     * @param byteStream The raw byte stream containing the document.
+     * @see #setPublicId
+     * @see #setSystemId
+     * @see #setEncoding
+     * @see #setByteStream
+     * @see #setCharacterStream
+     */
+    public InputSource (InputStream byteStream)
+    {
+        setByteStream(byteStream);
+    }
+
+
+    /**
+     * Create a new input source with a character stream.
+     *
+     * <p>Application writers should use setSystemId() to provide a base
+     * for resolving relative URIs, and may use setPublicId to include a
+     * public identifier.</p>
+     *
+     * <p>The character stream shall not include a byte order mark.</p>
+     *
+     * @see #setPublicId
+     * @see #setSystemId
+     * @see #setByteStream
+     * @see #setCharacterStream
+     */
+    public InputSource (Reader characterStream)
+    {
+        setCharacterStream(characterStream);
+    }
+
+
+    /**
+     * Set the public identifier for this input source.
+     *
+     * <p>The public identifier is always optional: if the application
+     * writer includes one, it will be provided as part of the
+     * location information.</p>
+     *
+     * @param publicId The public identifier as a string.
+     * @see #getPublicId
+     * @see org.xml.sax.Locator#getPublicId
+     * @see org.xml.sax.SAXParseException#getPublicId
+     */
+    public void setPublicId (String publicId)
+    {
+        this.publicId = publicId;
+    }
+
+
+    /**
+     * Get the public identifier for this input source.
+     *
+     * @return The public identifier, or null if none was supplied.
+     * @see #setPublicId
+     */
+    public String getPublicId ()
+    {
+        return publicId;
+    }
+
+
+    /**
+     * Set the system identifier for this input source.
+     *
+     * <p>The system identifier is optional if there is a byte stream
+     * or a character stream, but it is still useful to provide one,
+     * since the application can use it to resolve relative URIs
+     * and can include it in error messages and warnings (the parser
+     * will attempt to open a connection to the URI only if
+     * there is no byte stream or character stream specified).</p>
+     *
+     * <p>If the application knows the character encoding of the
+     * object pointed to by the system identifier, it can register
+     * the encoding using the setEncoding method.</p>
+     *
+     * <p>If the system identifier is a URL, it must be fully
+     * resolved (it may not be a relative URL).</p>
+     *
+     * @param systemId The system identifier as a string.
+     * @see #setEncoding
+     * @see #getSystemId
+     * @see org.xml.sax.Locator#getSystemId
+     * @see org.xml.sax.SAXParseException#getSystemId
+     */
+    public void setSystemId (String systemId)
+    {
+        this.systemId = systemId;
+    }
+
+
+    /**
+     * Get the system identifier for this input source.
+     *
+     * <p>The getEncoding method will return the character encoding
+     * of the object pointed to, or null if unknown.</p>
+     *
+     * <p>If the system ID is a URL, it will be fully resolved.</p>
+     *
+     * @return The system identifier, or null if none was supplied.
+     * @see #setSystemId
+     * @see #getEncoding
+     */
+    public String getSystemId ()
+    {
+        return systemId;
+    }
+
+
+    /**
+     * Set the byte stream for this input source.
+     *
+     * <p>The SAX parser will ignore this if there is also a character
+     * stream specified, but it will use a byte stream in preference
+     * to opening a URI connection itself.</p>
+     *
+     * <p>If the application knows the character encoding of the
+     * byte stream, it should set it with the setEncoding method.</p>
+     *
+     * @param byteStream A byte stream containing an XML document or
+     *        other entity.
+     * @see #setEncoding
+     * @see #getByteStream
+     * @see #getEncoding
+     * @see java.io.InputStream
+     */
+    public void setByteStream (InputStream byteStream)
+    {
+        this.byteStream = byteStream;
+    }
+
+
+    /**
+     * Get the byte stream for this input source.
+     *
+     * <p>The getEncoding method will return the character
+     * encoding for this byte stream, or null if unknown.</p>
+     *
+     * @return The byte stream, or null if none was supplied.
+     * @see #getEncoding
+     * @see #setByteStream
+     */
+    public InputStream getByteStream ()
+    {
+        return byteStream;
+    }
+
+
+    /**
+     * Set the character encoding, if known.
+     *
+     * <p>The encoding must be a string acceptable for an
+     * XML encoding declaration (see section 4.3.3 of the XML 1.0
+     * recommendation).</p>
+     *
+     * <p>This method has no effect when the application provides a
+     * character stream.</p>
+     *
+     * @param encoding A string describing the character encoding.
+     * @see #setSystemId
+     * @see #setByteStream
+     * @see #getEncoding
+     */
+    public void setEncoding (String encoding)
+    {
+        this.encoding = encoding;
+    }
+
+
+    /**
+     * Get the character encoding for a byte stream or URI.
+     * This value will be ignored when the application provides a
+     * character stream.
+     *
+     * @return The encoding, or null if none was supplied.
+     * @see #setByteStream
+     * @see #getSystemId
+     * @see #getByteStream
+     */
+    public String getEncoding ()
+    {
+        return encoding;
+    }
+
+
+    /**
+     * Set the character stream for this input source.
+     *
+     * <p>If there is a character stream specified, the SAX parser
+     * will ignore any byte stream and will not attempt to open
+     * a URI connection to the system identifier.</p>
+     *
+     * @param characterStream The character stream containing the
+     *        XML document or other entity.
+     * @see #getCharacterStream
+     * @see java.io.Reader
+     */
+    public void setCharacterStream (Reader characterStream)
+    {
+        this.characterStream = characterStream;
+    }
+
+
+    /**
+     * Get the character stream for this input source.
+     *
+     * @return The character stream, or null if none was supplied.
+     * @see #setCharacterStream
+     */
+    public Reader getCharacterStream ()
+    {
+        return characterStream;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private String publicId;
+    private String systemId;
+    private InputStream byteStream;
+    private String encoding;
+    private Reader characterStream;
+
+}
+
+// end of InputSource.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/Locator.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX locator interface for document events.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Locator.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Interface for associating a SAX event with a document location.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX parser provides location information to the SAX
+ * application, it does so by implementing this interface and then
+ * passing an instance to the application using the content
+ * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator
+ * setDocumentLocator} method.  The application can use the
+ * object to obtain the location of any other SAX event
+ * in the XML source document.</p>
+ *
+ * <p>Note that the results returned by the object will be valid only
+ * during the scope of each callback method: the application
+ * will receive unpredictable results if it attempts to use the
+ * locator at any other time, or after parsing completes.</p>
+ *
+ * <p>SAX parsers are not required to supply a locator, but they are
+ * very strongly encouraged to do so.  If the parser supplies a
+ * locator, it must do so before reporting any other document events.
+ * If no locator has been set by the time the application receives
+ * the {@link org.xml.sax.ContentHandler#startDocument startDocument}
+ * event, the application should assume that a locator is not
+ * available.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ */
+public interface Locator {
+
+
+    /**
+     * Return the public identifier for the current document event.
+     *
+     * <p>The return value is the public identifier of the document
+     * entity or of the external parsed entity in which the markup
+     * triggering the event appears.</p>
+     *
+     * @return A string containing the public identifier, or
+     *         null if none is available.
+     * @see #getSystemId
+     */
+    public abstract String getPublicId ();
+
+
+    /**
+     * Return the system identifier for the current document event.
+     *
+     * <p>The return value is the system identifier of the document
+     * entity or of the external parsed entity in which the markup
+     * triggering the event appears.</p>
+     *
+     * <p>If the system identifier is a URL, the parser must resolve it
+     * fully before passing it to the application.  For example, a file
+     * name must always be provided as a <em>file:...</em> URL, and other
+     * kinds of relative URI are also resolved against their bases.</p>
+     *
+     * @return A string containing the system identifier, or null
+     *         if none is available.
+     * @see #getPublicId
+     */
+    public abstract String getSystemId ();
+
+
+    /**
+     * Return the line number where the current document event ends.
+     * Lines are delimited by line ends, which are defined in
+     * the XML specification.
+     *
+     * <p><strong>Warning:</strong> The return value from the method
+     * is intended only as an approximation for the sake of diagnostics;
+     * it is not intended to provide sufficient information
+     * to edit the character content of the original XML document.
+     * In some cases, these "line" numbers match what would be displayed
+     * as columns, and in others they may not match the source text
+     * due to internal entity expansion.  </p>
+     *
+     * <p>The return value is an approximation of the line number
+     * in the document entity or external parsed entity where the
+     * markup triggering the event appears.</p>
+     *
+     * <p>If possible, the SAX driver should provide the line position
+     * of the first character after the text associated with the document
+     * event.  The first line is line 1.</p>
+     *
+     * @return The line number, or -1 if none is available.
+     * @see #getColumnNumber
+     */
+    public abstract int getLineNumber ();
+
+
+    /**
+     * Return the column number where the current document event ends.
+     * This is one-based number of Java <code>char</code> values since
+     * the last line end.
+     *
+     * <p><strong>Warning:</strong> The return value from the method
+     * is intended only as an approximation for the sake of diagnostics;
+     * it is not intended to provide sufficient information
+     * to edit the character content of the original XML document.
+     * For example, when lines contain combining character sequences, wide
+     * characters, surrogate pairs, or bi-directional text, the value may
+     * not correspond to the column in a text editor's display. </p>
+     *
+     * <p>The return value is an approximation of the column number
+     * in the document entity or external parsed entity where the
+     * markup triggering the event appears.</p>
+     *
+     * <p>If possible, the SAX driver should provide the line position
+     * of the first character after the text associated with the document
+     * event.  The first column in each line is column 1.</p>
+     *
+     * @return The column number, or -1 if none is available.
+     * @see #getLineNumber
+     */
+    public abstract int getColumnNumber ();
+
+}
+
+// end of Locator.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/SAXException.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXException.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Encapsulate a general SAX error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class can contain basic error or warning information from
+ * either the XML parser or the application: a parser writer or
+ * application writer can subclass it to provide additional
+ * functionality.  SAX handlers may throw this exception or
+ * any exception subclassed from it.</p>
+ *
+ * <p>If the application needs to pass through other types of
+ * exceptions, it must wrap those exceptions in a SAXException
+ * or an exception derived from a SAXException.</p>
+ *
+ * <p>If the parser or application needs to include information about a
+ * specific location in an XML document, it should use the
+ * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXParseException
+ */
+public class SAXException extends Exception {
+
+
+    /**
+     * Create a new SAXException.
+     */
+    public SAXException ()
+    {
+        super();
+        this.exception = null;
+    }
+
+
+    /**
+     * Create a new SAXException.
+     *
+     * @param message The error or warning message.
+     */
+    public SAXException (String message) {
+        super(message);
+        this.exception = null;
+    }
+
+
+    /**
+     * Create a new SAXException wrapping an existing exception.
+     *
+     * <p>The existing exception will be embedded in the new
+     * one, and its message will become the default message for
+     * the SAXException.</p>
+     *
+     * @param e The exception to be wrapped in a SAXException.
+     */
+    public SAXException (Exception e)
+    {
+        super();
+        this.exception = e;
+    }
+
+
+    /**
+     * Create a new SAXException from an existing exception.
+     *
+     * <p>The existing exception will be embedded in the new
+     * one, but the new exception will have its own message.</p>
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped in a SAXException.
+     */
+    public SAXException (String message, Exception e)
+    {
+        super(message);
+        this.exception = e;
+    }
+
+
+    /**
+     * Return a detail message for this exception.
+     *
+     * <p>If there is an embedded exception, and if the SAXException
+     * has no detail message of its own, this method will return
+     * the detail message from the embedded exception.</p>
+     *
+     * @return The error or warning message.
+     */
+    public String getMessage ()
+    {
+        String message = super.getMessage();
+
+        if (message == null && exception != null) {
+            return exception.getMessage();
+        } else {
+            return message;
+        }
+    }
+
+
+    /**
+     * Return the embedded exception, if any.
+     *
+     * @return The embedded exception, or null if there is none.
+     */
+    public Exception getException ()
+    {
+        return exception;
+    }
+
+    /**
+     * Return the cause of the exception
+     *
+     * @return Return the cause of the exception
+     */
+    public Throwable getCause() {
+        return exception;
+    }
+
+    /**
+     * Override toString to pick up any embedded exception.
+     *
+     * @return A string representation of this exception.
+     */
+    public String toString ()
+    {
+        if (exception != null) {
+            return super.toString() + "\n" + exception.toString();
+        } else {
+            return super.toString();
+        }
+    }
+
+
+
+    //////////////////////////////////////////////////////////////////////
+    // Internal state.
+    //////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * @serial The embedded exception if tunnelling, or null.
+     */
+    private Exception exception;
+
+    // Added serialVersionUID to preserve binary compatibility
+    static final long serialVersionUID = 583241635256073760L;
+}
+
+// end of SAXException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/SAXNotRecognizedException.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAXNotRecognizedException.java - unrecognized feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: SAXNotRecognizedException.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+
+/**
+ * Exception class for an unrecognized identifier.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it finds an
+ * unrecognized feature or property identifier; SAX applications and
+ * extensions may use this class for other, similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.SAXNotSupportedException
+ */
+public class SAXNotRecognizedException extends SAXException
+{
+
+    /**
+     * Default constructor.
+     */
+    public SAXNotRecognizedException ()
+    {
+        super();
+    }
+
+
+    /**
+     * Construct a new exception with the given message.
+     *
+     * @param message The text message of the exception.
+     */
+    public SAXNotRecognizedException (String message)
+    {
+        super(message);
+    }
+
+    // Added serialVersionUID to preserve binary compatibility
+    static final long serialVersionUID = 5440506620509557213L;
+}
+
+// end of SAXNotRecognizedException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/SAXNotSupportedException.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAXNotSupportedException.java - unsupported feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: SAXNotSupportedException.java,v 1.4 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Exception class for an unsupported operation.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it recognizes a
+ * feature or property identifier, but cannot perform the requested
+ * operation (setting a state or value).  Other SAX2 applications and
+ * extensions may use this class for similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.SAXNotRecognizedException
+ */
+public class SAXNotSupportedException extends SAXException
+{
+
+    /**
+     * Construct a new exception with no message.
+     */
+    public SAXNotSupportedException ()
+    {
+        super();
+    }
+
+
+    /**
+     * Construct a new exception with the given message.
+     *
+     * @param message The text message of the exception.
+     */
+    public SAXNotSupportedException (String message)
+    {
+        super(message);
+    }
+
+    // Added serialVersionUID to preserve binary compatibility
+    static final long serialVersionUID = -1422818934641823846L;
+}
+
+// end of SAXNotSupportedException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/SAXParseException.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXParseException.java,v 1.2 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+/**
+ * Encapsulate an XML parse error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This exception may include information for locating the error
+ * in the original XML document, as if it came from a {@link Locator}
+ * object.  Note that although the application
+ * will receive a SAXParseException as the argument to the handlers
+ * in the {@link org.xml.sax.ErrorHandler ErrorHandler} interface,
+ * the application is not actually required to throw the exception;
+ * instead, it can simply read the information in it and take a
+ * different action.</p>
+ *
+ * <p>Since this exception is a subclass of {@link org.xml.sax.SAXException
+ * SAXException}, it inherits the ability to wrap another exception.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXException
+ * @see org.xml.sax.Locator
+ * @see org.xml.sax.ErrorHandler
+ */
+public class SAXParseException extends SAXException {
+
+
+    //////////////////////////////////////////////////////////////////////
+    // Constructors.
+    //////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new SAXParseException from a message and a Locator.
+     *
+     * <p>This constructor is especially useful when an application is
+     * creating its own exception from within a {@link org.xml.sax.ContentHandler
+     * ContentHandler} callback.</p>
+     *
+     * @param message The error or warning message.
+     * @param locator The locator object for the error or warning (may be
+     *        null).
+     * @see org.xml.sax.Locator
+     */
+    public SAXParseException (String message, Locator locator) {
+        super(message);
+        if (locator != null) {
+            init(locator.getPublicId(), locator.getSystemId(),
+                 locator.getLineNumber(), locator.getColumnNumber());
+        } else {
+            init(null, null, -1, -1);
+        }
+    }
+
+
+    /**
+     * Wrap an existing exception in a SAXParseException.
+     *
+     * <p>This constructor is especially useful when an application is
+     * creating its own exception from within a {@link org.xml.sax.ContentHandler
+     * ContentHandler} callback, and needs to wrap an existing exception that is not a
+     * subclass of {@link org.xml.sax.SAXException SAXException}.</p>
+     *
+     * @param message The error or warning message, or null to
+     *                use the message from the embedded exception.
+     * @param locator The locator object for the error or warning (may be
+     *        null).
+     * @param e Any exception.
+     * @see org.xml.sax.Locator
+     */
+    public SAXParseException (String message, Locator locator,
+                              Exception e) {
+        super(message, e);
+        if (locator != null) {
+            init(locator.getPublicId(), locator.getSystemId(),
+                 locator.getLineNumber(), locator.getColumnNumber());
+        } else {
+            init(null, null, -1, -1);
+        }
+    }
+
+
+    /**
+     * Create a new SAXParseException.
+     *
+     * <p>This constructor is most useful for parser writers.</p>
+     *
+     * <p>All parameters except the message are as if
+     * they were provided by a {@link Locator}.  For example, if the
+     * system identifier is a URL (including relative filename), the
+     * caller must resolve it fully before creating the exception.</p>
+     *
+     *
+     * @param message The error or warning message.
+     * @param publicId The public identifier of the entity that generated
+     *                 the error or warning.
+     * @param systemId The system identifier of the entity that generated
+     *                 the error or warning.
+     * @param lineNumber The line number of the end of the text that
+     *                   caused the error or warning.
+     * @param columnNumber The column number of the end of the text that
+     *                     cause the error or warning.
+     */
+    public SAXParseException (String message, String publicId, String systemId,
+                              int lineNumber, int columnNumber)
+    {
+        super(message);
+        init(publicId, systemId, lineNumber, columnNumber);
+    }
+
+
+    /**
+     * Create a new SAXParseException with an embedded exception.
+     *
+     * <p>This constructor is most useful for parser writers who
+     * need to wrap an exception that is not a subclass of
+     * {@link org.xml.sax.SAXException SAXException}.</p>
+     *
+     * <p>All parameters except the message and exception are as if
+     * they were provided by a {@link Locator}.  For example, if the
+     * system identifier is a URL (including relative filename), the
+     * caller must resolve it fully before creating the exception.</p>
+     *
+     * @param message The error or warning message, or null to use
+     *                the message from the embedded exception.
+     * @param publicId The public identifier of the entity that generated
+     *                 the error or warning.
+     * @param systemId The system identifier of the entity that generated
+     *                 the error or warning.
+     * @param lineNumber The line number of the end of the text that
+     *                   caused the error or warning.
+     * @param columnNumber The column number of the end of the text that
+     *                     cause the error or warning.
+     * @param e Another exception to embed in this one.
+     */
+    public SAXParseException (String message, String publicId, String systemId,
+                              int lineNumber, int columnNumber, Exception e)
+    {
+        super(message, e);
+        init(publicId, systemId, lineNumber, columnNumber);
+    }
+
+
+    /**
+     * Internal initialization method.
+     *
+     * @param publicId The public identifier of the entity which generated the exception,
+     *        or null.
+     * @param systemId The system identifier of the entity which generated the exception,
+     *        or null.
+     * @param lineNumber The line number of the error, or -1.
+     * @param columnNumber The column number of the error, or -1.
+     */
+    private void init (String publicId, String systemId,
+                       int lineNumber, int columnNumber)
+    {
+        this.publicId = publicId;
+        this.systemId = systemId;
+        this.lineNumber = lineNumber;
+        this.columnNumber = columnNumber;
+    }
+
+
+    /**
+     * Get the public identifier of the entity where the exception occurred.
+     *
+     * @return A string containing the public identifier, or null
+     *         if none is available.
+     * @see org.xml.sax.Locator#getPublicId
+     */
+    public String getPublicId ()
+    {
+        return this.publicId;
+    }
+
+
+    /**
+     * Get the system identifier of the entity where the exception occurred.
+     *
+     * <p>If the system identifier is a URL, it will have been resolved
+     * fully.</p>
+     *
+     * @return A string containing the system identifier, or null
+     *         if none is available.
+     * @see org.xml.sax.Locator#getSystemId
+     */
+    public String getSystemId ()
+    {
+        return this.systemId;
+    }
+
+
+    /**
+     * The line number of the end of the text where the exception occurred.
+     *
+     * <p>The first line is line 1.</p>
+     *
+     * @return An integer representing the line number, or -1
+     *         if none is available.
+     * @see org.xml.sax.Locator#getLineNumber
+     */
+    public int getLineNumber ()
+    {
+        return this.lineNumber;
+    }
+
+
+    /**
+     * The column number of the end of the text where the exception occurred.
+     *
+     * <p>The first column in a line is position 1.</p>
+     *
+     * @return An integer representing the column number, or -1
+     *         if none is available.
+     * @see org.xml.sax.Locator#getColumnNumber
+     */
+    public int getColumnNumber ()
+    {
+        return this.columnNumber;
+    }
+
+    /**
+     * Override toString to provide more detailed error message.
+     *
+     * @return A string representation of this exception.
+     */
+    public String toString() {
+        StringBuilder buf = new StringBuilder(getClass().getName());
+        String message = getLocalizedMessage();
+        if (publicId!=null)    buf.append("publicId: ").append(publicId);
+        if (systemId!=null)    buf.append("; systemId: ").append(systemId);
+        if (lineNumber!=-1)    buf.append("; lineNumber: ").append(lineNumber);
+        if (columnNumber!=-1)  buf.append("; columnNumber: ").append(columnNumber);
+
+       //append the exception message at the end
+        if (message!=null)     buf.append("; ").append(message);
+        return buf.toString();
+    }
+
+    //////////////////////////////////////////////////////////////////////
+    // Internal state.
+    //////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * @serial The public identifier, or null.
+     * @see #getPublicId
+     */
+    private String publicId;
+
+
+    /**
+     * @serial The system identifier, or null.
+     * @see #getSystemId
+     */
+    private String systemId;
+
+
+    /**
+     * @serial The line number, or -1.
+     * @see #getLineNumber
+     */
+    private int lineNumber;
+
+
+    /**
+     * @serial The column number, or -1.
+     * @see #getColumnNumber
+     */
+    private int columnNumber;
+
+    // Added serialVersionUID to preserve binary compatibility
+    static final long serialVersionUID = -5651165872476709336L;
+}
+
+// end of SAXParseException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/XMLReader.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// XMLReader.java - read an XML document.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: XMLReader.java,v 1.3 2004/11/03 22:55:32 jsuttor Exp $
+
+package jdk.internal.org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Interface for reading an XML document using callbacks.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p><strong>Note:</strong> despite its name, this interface does
+ * <em>not</em> extend the standard Java {@link java.io.Reader Reader}
+ * interface, because reading XML is a fundamentally different activity
+ * than reading character data.</p>
+ *
+ * <p>XMLReader is the interface that an XML parser's SAX2 driver must
+ * implement.  This interface allows an application to set and
+ * query features and properties in the parser, to register
+ * event handlers for document processing, and to initiate
+ * a document parse.</p>
+ *
+ * <p>All SAX interfaces are assumed to be synchronous: the
+ * {@link #parse parse} methods must not return until parsing
+ * is complete, and readers must wait for an event-handler callback
+ * to return before reporting the next event.</p>
+ *
+ * <p>This interface replaces the (now deprecated) SAX 1.0 {@link
+ * org.xml.sax.Parser Parser} interface.  The XMLReader interface
+ * contains two important enhancements over the old Parser
+ * interface (as well as some minor ones):</p>
+ *
+ * <ol>
+ * <li>it adds a standard way to query and set features and
+ *  properties; and</li>
+ * <li>it adds Namespace support, which is required for many
+ *  higher-level XML standards.</li>
+ * </ol>
+ *
+ * <p>There are adapters available to convert a SAX1 Parser to
+ * a SAX2 XMLReader and vice-versa.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @see org.xml.sax.XMLFilter
+ * @see org.xml.sax.helpers.ParserAdapter
+ * @see org.xml.sax.helpers.XMLReaderAdapter
+ */
+public interface XMLReader
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Configuration.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Look up the value of a feature flag.
+     *
+     * <p>The feature name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a feature name but
+     * temporarily be unable to return its value.
+     * Some feature values may be available only in specific
+     * contexts, such as before, during, or after a parse.
+     * Also, some feature values may not be programmatically accessible.
+     * (In the case of an adapter for SAX1 {@link Parser}, there is no
+     * implementation-independent way to expose whether the underlying
+     * parser is performing validation, expanding external entities,
+     * and so forth.) </p>
+     *
+     * <p>All XMLReaders are required to recognize the
+     * http://xml.org/sax/features/namespaces and the
+     * http://xml.org/sax/features/namespace-prefixes feature names.</p>
+     *
+     * <p>Typical usage is something like this:</p>
+     *
+     * <pre>
+     * XMLReader r = new MySAXDriver();
+     *
+     *                         // try to activate validation
+     * try {
+     *   r.setFeature("http://xml.org/sax/features/validation", true);
+     * } catch (SAXException e) {
+     *   System.err.println("Cannot activate validation.");
+     * }
+     *
+     *                         // register event handlers
+     * r.setContentHandler(new MyContentHandler());
+     * r.setErrorHandler(new MyErrorHandler());
+     *
+     *                         // parse the first document
+     * try {
+     *   r.parse("http://www.foo.com/mydoc.xml");
+     * } catch (IOException e) {
+     *   System.err.println("I/O exception reading XML document");
+     * } catch (SAXException e) {
+     *   System.err.println("XML exception reading document.");
+     * }
+     * </pre>
+     *
+     * <p>Implementors are free (and encouraged) to invent their own features,
+     * using names built on their own URIs.</p>
+     *
+     * @param name The feature name, which is a fully-qualified URI.
+     * @return The current value of the feature (true or false).
+     * @exception org.xml.sax.SAXNotRecognizedException If the feature
+     *            value can't be assigned or retrieved.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            XMLReader recognizes the feature name but
+     *            cannot determine its value at this time.
+     * @see #setFeature
+     */
+    public boolean getFeature (String name)
+        throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+    /**
+     * Set the value of a feature flag.
+     *
+     * <p>The feature name is any fully-qualified URI.  It is
+     * possible for an XMLReader to expose a feature value but
+     * to be unable to change the current value.
+     * Some feature values may be immutable or mutable only
+     * in specific contexts, such as before, during, or after
+     * a parse.</p>
+     *
+     * <p>All XMLReaders are required to support setting
+     * http://xml.org/sax/features/namespaces to true and
+     * http://xml.org/sax/features/namespace-prefixes to false.</p>
+     *
+     * @param name The feature name, which is a fully-qualified URI.
+     * @param value The requested value of the feature (true or false).
+     * @exception org.xml.sax.SAXNotRecognizedException If the feature
+     *            value can't be assigned or retrieved.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            XMLReader recognizes the feature name but
+     *            cannot set the requested value.
+     * @see #getFeature
+     */
+    public void setFeature (String name, boolean value)
+        throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+    /**
+     * Look up the value of a property.
+     *
+     * <p>The property name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a property name but
+     * temporarily be unable to return its value.
+     * Some property values may be available only in specific
+     * contexts, such as before, during, or after a parse.</p>
+     *
+     * <p>XMLReaders are not required to recognize any specific
+     * property names, though an initial core set is documented for
+     * SAX2.</p>
+     *
+     * <p>Implementors are free (and encouraged) to invent their own properties,
+     * using names built on their own URIs.</p>
+     *
+     * @param name The property name, which is a fully-qualified URI.
+     * @return The current value of the property.
+     * @exception org.xml.sax.SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            XMLReader recognizes the property name but
+     *            cannot determine its value at this time.
+     * @see #setProperty
+     */
+    public Object getProperty (String name)
+        throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+    /**
+     * Set the value of a property.
+     *
+     * <p>The property name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a property name but
+     * to be unable to change the current value.
+     * Some property values may be immutable or mutable only
+     * in specific contexts, such as before, during, or after
+     * a parse.</p>
+     *
+     * <p>XMLReaders are not required to recognize setting
+     * any specific property names, though a core set is defined by
+     * SAX2.</p>
+     *
+     * <p>This method is also the standard mechanism for setting
+     * extended handlers.</p>
+     *
+     * @param name The property name, which is a fully-qualified URI.
+     * @param value The requested value for the property.
+     * @exception org.xml.sax.SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            XMLReader recognizes the property name but
+     *            cannot set the requested value.
+     */
+    public void setProperty (String name, Object value)
+        throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Event handlers.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Allow an application to register an entity resolver.
+     *
+     * <p>If the application does not register an entity resolver,
+     * the XMLReader will perform its own default resolution.</p>
+     *
+     * <p>Applications may register a new or different resolver in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * resolver immediately.</p>
+     *
+     * @param resolver The entity resolver.
+     * @see #getEntityResolver
+     */
+    public void setEntityResolver (EntityResolver resolver);
+
+
+    /**
+     * Return the current entity resolver.
+     *
+     * @return The current entity resolver, or null if none
+     *         has been registered.
+     * @see #setEntityResolver
+     */
+    public EntityResolver getEntityResolver ();
+
+
+    /**
+     * Allow an application to register a DTD event handler.
+     *
+     * <p>If the application does not register a DTD handler, all DTD
+     * events reported by the SAX parser will be silently ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The DTD handler.
+     * @see #getDTDHandler
+     */
+    public void setDTDHandler (DTDHandler handler);
+
+
+    /**
+     * Return the current DTD handler.
+     *
+     * @return The current DTD handler, or null if none
+     *         has been registered.
+     * @see #setDTDHandler
+     */
+    public DTDHandler getDTDHandler ();
+
+
+    /**
+     * Allow an application to register a content event handler.
+     *
+     * <p>If the application does not register a content handler, all
+     * content events reported by the SAX parser will be silently
+     * ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The content handler.
+     * @see #getContentHandler
+     */
+    public void setContentHandler (ContentHandler handler);
+
+
+    /**
+     * Return the current content handler.
+     *
+     * @return The current content handler, or null if none
+     *         has been registered.
+     * @see #setContentHandler
+     */
+    public ContentHandler getContentHandler ();
+
+
+    /**
+     * Allow an application to register an error event handler.
+     *
+     * <p>If the application does not register an error handler, all
+     * error events reported by the SAX parser will be silently
+     * ignored; however, normal processing may not continue.  It is
+     * highly recommended that all SAX applications implement an
+     * error handler to avoid unexpected bugs.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The error handler.
+     * @see #getErrorHandler
+     */
+    public void setErrorHandler (ErrorHandler handler);
+
+
+    /**
+     * Return the current error handler.
+     *
+     * @return The current error handler, or null if none
+     *         has been registered.
+     * @see #setErrorHandler
+     */
+    public ErrorHandler getErrorHandler ();
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Parsing.
+    ////////////////////////////////////////////////////////////////////
+
+    /**
+     * Parse an XML document.
+     *
+     * <p>The application can use this method to instruct the XML
+     * reader to begin parsing an XML document from any valid input
+     * source (a character stream, a byte stream, or a URI).</p>
+     *
+     * <p>Applications may not invoke this method while a parse is in
+     * progress (they should create a new XMLReader instead for each
+     * nested XML document).  Once a parse is complete, an
+     * application may reuse the same XMLReader object, possibly with a
+     * different input source.
+     * Configuration of the XMLReader object (such as handler bindings and
+     * values established for feature flags and properties) is unchanged
+     * by completion of a parse, unless the definition of that aspect of
+     * the configuration explicitly specifies other behavior.
+     * (For example, feature flags or properties exposing
+     * characteristics of the document being parsed.)
+     * </p>
+     *
+     * <p>During the parse, the XMLReader will provide information
+     * about the XML document through the registered event
+     * handlers.</p>
+     *
+     * <p>This method is synchronous: it will not return until parsing
+     * has ended.  If a client application wants to terminate
+     * parsing early, it should throw an exception.</p>
+     *
+     * @param input The input source for the top-level of the
+     *        XML document.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @exception java.io.IOException An IO exception from the parser,
+     *            possibly from a byte stream or character stream
+     *            supplied by the application.
+     * @see org.xml.sax.InputSource
+     * @see #parse(java.lang.String)
+     * @see #setEntityResolver
+     * @see #setDTDHandler
+     * @see #setContentHandler
+     * @see #setErrorHandler
+     */
+    public void parse (InputSource input)
+        throws IOException, SAXException;
+
+
+    /**
+     * Parse an XML document from a system identifier (URI).
+     *
+     * <p>This method is a shortcut for the common case of reading a
+     * document from a system identifier.  It is the exact
+     * equivalent of the following:</p>
+     *
+     * <pre>
+     * parse(new InputSource(systemId));
+     * </pre>
+     *
+     * <p>If the system identifier is a URL, it must be fully resolved
+     * by the application before it is passed to the parser.</p>
+     *
+     * @param systemId The system identifier (URI).
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @exception java.io.IOException An IO exception from the parser,
+     *            possibly from a byte stream or character stream
+     *            supplied by the application.
+     * @see #parse(org.xml.sax.InputSource)
+     */
+    public void parse (String systemId)
+        throws IOException, SAXException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/org/xml/sax/helpers/DefaultHandler.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// DefaultHandler.java - default implementation of the core handlers.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: DefaultHandler.java,v 1.3 2006/04/13 02:06:32 jeffsuttor Exp $
+
+package jdk.internal.org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.Locator;
+import jdk.internal.org.xml.sax.Attributes;
+import jdk.internal.org.xml.sax.EntityResolver;
+import jdk.internal.org.xml.sax.DTDHandler;
+import jdk.internal.org.xml.sax.ContentHandler;
+import jdk.internal.org.xml.sax.ErrorHandler;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+
+
+/**
+ * Default base class for SAX2 event handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class is available as a convenience base class for SAX2
+ * applications: it provides default implementations for all of the
+ * callbacks in the four core SAX2 handler classes:</p>
+ *
+ * <ul>
+ * <li>{@link org.xml.sax.EntityResolver EntityResolver}</li>
+ * <li>{@link org.xml.sax.DTDHandler DTDHandler}</li>
+ * <li>{@link org.xml.sax.ContentHandler ContentHandler}</li>
+ * <li>{@link org.xml.sax.ErrorHandler ErrorHandler}</li>
+ * </ul>
+ *
+ * <p>Application writers can extend this class when they need to
+ * implement only part of an interface; parser writers can
+ * instantiate this class to provide default handlers when the
+ * application has not supplied its own.</p>
+ *
+ * <p>This class replaces the deprecated SAX1
+ * {@link org.xml.sax.HandlerBase HandlerBase} class.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson,
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ContentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class DefaultHandler
+    implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Default implementation of the EntityResolver interface.
+    ////////////////////////////////////////////////////////////////////
+
+    /**
+     * Resolve an external entity.
+     *
+     * <p>Always return null, so that the parser will use the system
+     * identifier provided in the XML document.  This method implements
+     * the SAX default behaviour: application writers can override it
+     * in a subclass to do special translations such as catalog lookups
+     * or URI redirection.</p>
+     *
+     * @param publicId The public identifier, or null if none is
+     *                 available.
+     * @param systemId The system identifier provided in the XML
+     *                 document.
+     * @return The new input source, or null to require the
+     *         default behaviour.
+     * @exception java.io.IOException If there is an error setting
+     *            up the new input source.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.EntityResolver#resolveEntity
+     */
+    public InputSource resolveEntity (String publicId, String systemId)
+        throws IOException, SAXException
+    {
+        return null;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Default implementation of DTDHandler interface.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Receive notification of a notation declaration.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass if they wish to keep track of the notations
+     * declared in a document.</p>
+     *
+     * @param name The notation name.
+     * @param publicId The notation public identifier, or null if not
+     *                 available.
+     * @param systemId The notation system identifier.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.DTDHandler#notationDecl
+     */
+    public void notationDecl (String name, String publicId, String systemId)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of an unparsed entity declaration.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to keep track of the unparsed entities
+     * declared in a document.</p>
+     *
+     * @param name The entity name.
+     * @param publicId The entity public identifier, or null if not
+     *                 available.
+     * @param systemId The entity system identifier.
+     * @param notationName The name of the associated notation.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void unparsedEntityDecl (String name, String publicId,
+                                    String systemId, String notationName)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Default implementation of ContentHandler interface.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Receive a Locator object for document events.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass if they wish to store the locator for use
+     * with other document events.</p>
+     *
+     * @param locator A locator for all SAX document events.
+     * @see org.xml.sax.ContentHandler#setDocumentLocator
+     * @see org.xml.sax.Locator
+     */
+    public void setDocumentLocator (Locator locator)
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the beginning of the document.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the beginning
+     * of a document (such as allocating the root node of a tree or
+     * creating an output file).</p>
+     *
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#startDocument
+     */
+    public void startDocument ()
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the end of the document.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the end
+     * of a document (such as finalising a tree or closing an output
+     * file).</p>
+     *
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#endDocument
+     */
+    public void endDocument ()
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the start of a Namespace mapping.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the start of
+     * each Namespace prefix scope (such as storing the prefix mapping).</p>
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI mapped to the prefix.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#startPrefixMapping
+     */
+    public void startPrefixMapping (String prefix, String uri)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the end of a Namespace mapping.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the end of
+     * each prefix mapping.</p>
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#endPrefixMapping
+     */
+    public void endPrefixMapping (String prefix)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the start of an element.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the start of
+     * each element (such as allocating a new tree node or writing
+     * output to a file).</p>
+     *
+     * @param uri The Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed.
+     * @param localName The local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed.
+     * @param qName The qualified name (with prefix), or the
+     *        empty string if qualified names are not available.
+     * @param attributes The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#startElement
+     */
+    public void startElement (String uri, String localName,
+                              String qName, Attributes attributes)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions at the end of
+     * each element (such as finalising a tree node or writing
+     * output to a file).</p>
+     *
+     * @param uri The Namespace URI, or the empty string if the
+     *        element has no Namespace URI or if Namespace
+     *        processing is not being performed.
+     * @param localName The local name (without prefix), or the
+     *        empty string if Namespace processing is not being
+     *        performed.
+     * @param qName The qualified name (with prefix), or the
+     *        empty string if qualified names are not available.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#endElement
+     */
+    public void endElement (String uri, String localName, String qName)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of character data inside an element.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method to take specific actions for each chunk of character data
+     * (such as adding the data to a node or buffer, or printing it to
+     * a file).</p>
+     *
+     * @param ch The characters.
+     * @param start The start position in the character array.
+     * @param length The number of characters to use from the
+     *               character array.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#characters
+     */
+    public void characters (char ch[], int start, int length)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method to take specific actions for each chunk of ignorable
+     * whitespace (such as adding data to a node or buffer, or printing
+     * it to a file).</p>
+     *
+     * @param ch The whitespace characters.
+     * @param start The start position in the character array.
+     * @param length The number of characters to use from the
+     *               character array.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace
+     */
+    public void ignorableWhitespace (char ch[], int start, int length)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions for each
+     * processing instruction, such as setting status variables or
+     * invoking other methods.</p>
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if
+     *             none is supplied.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#processingInstruction
+     */
+    public void processingInstruction (String target, String data)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * <p>By default, do nothing.  Application writers may override this
+     * method in a subclass to take specific actions for each
+     * processing instruction, such as setting status variables or
+     * invoking other methods.</p>
+     *
+     * @param name The name of the skipped entity.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ContentHandler#processingInstruction
+     */
+    public void skippedEntity (String name)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Default implementation of the ErrorHandler interface.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Receive notification of a parser warning.
+     *
+     * <p>The default implementation does nothing.  Application writers
+     * may override this method in a subclass to take specific actions
+     * for each warning, such as inserting the message in a log file or
+     * printing it to the console.</p>
+     *
+     * @param e The warning information encoded as an exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ErrorHandler#warning
+     * @see org.xml.sax.SAXParseException
+     */
+    public void warning (SAXParseException e)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Receive notification of a recoverable parser error.
+     *
+     * <p>The default implementation does nothing.  Application writers
+     * may override this method in a subclass to take specific actions
+     * for each error, such as inserting the message in a log file or
+     * printing it to the console.</p>
+     *
+     * @param e The error information encoded as an exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ErrorHandler#warning
+     * @see org.xml.sax.SAXParseException
+     */
+    public void error (SAXParseException e)
+        throws SAXException
+    {
+        // no op
+    }
+
+
+    /**
+     * Report a fatal XML parsing error.
+     *
+     * <p>The default implementation throws a SAXParseException.
+     * Application writers may override this method in a subclass if
+     * they need to take specific actions for each fatal error (such as
+     * collecting all of the errors into a single report): in any case,
+     * the application must stop all regular processing when this
+     * method is invoked, since the document is no longer reliable, and
+     * the parser may no longer report parsing events.</p>
+     *
+     * @param e The error information encoded as an exception.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.ErrorHandler#fatalError
+     * @see org.xml.sax.SAXParseException
+     */
+    public void fatalError (SAXParseException e)
+        throws SAXException
+    {
+        throw e;
+    }
+
+}
+
+// end of DefaultHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+import java.io.*;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Properties;
+import jdk.internal.org.xml.sax.Attributes;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+import jdk.internal.util.xml.impl.SAXParserImpl;
+import jdk.internal.util.xml.impl.XMLStreamWriterImpl;
+
+/**
+ * A class used to aid in Properties load and save in XML. This class is
+ * re-implemented using a subset of SAX
+ *
+ * @author Joe Wang
+ * @since 8
+ */
+public class PropertiesDefaultHandler extends DefaultHandler {
+
+    // Elements specified in the properties.dtd
+    private static final String ELEMENT_ROOT = "properties";
+    private static final String ELEMENT_COMMENT = "comment";
+    private static final String ELEMENT_ENTRY = "entry";
+    private static final String ATTR_KEY = "key";
+    // The required DTD URI for exported properties
+    private static final String PROPS_DTD_DECL =
+            "<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">";
+    private static final String PROPS_DTD_URI =
+            "http://java.sun.com/dtd/properties.dtd";
+    private static final String PROPS_DTD =
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+            + "<!-- DTD for properties -->"
+            + "<!ELEMENT properties ( comment?, entry* ) >"
+            + "<!ATTLIST properties"
+            + " version CDATA #FIXED \"1.0\">"
+            + "<!ELEMENT comment (#PCDATA) >"
+            + "<!ELEMENT entry (#PCDATA) >"
+            + "<!ATTLIST entry "
+            + " key CDATA #REQUIRED>";
+    /**
+     * Version number for the format of exported properties files.
+     */
+    private static final String EXTERNAL_XML_VERSION = "1.0";
+    private Properties properties;
+
+    public void load(Properties props, InputStream in)
+        throws IOException, InvalidPropertiesFormatException, UnsupportedEncodingException
+    {
+        this.properties = props;
+
+        try {
+            SAXParser parser = new SAXParserImpl();
+            parser.parse(in, this);
+        } catch (SAXException saxe) {
+            throw new InvalidPropertiesFormatException(saxe);
+        }
+
+        /**
+         * String xmlVersion = propertiesElement.getAttribute("version"); if
+         * (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) throw new
+         * InvalidPropertiesFormatException( "Exported Properties file format
+         * version " + xmlVersion + " is not supported. This java installation
+         * can read" + " versions " + EXTERNAL_XML_VERSION + " or older. You" +
+         * " may need to install a newer version of JDK.");
+         */
+    }
+
+    public void store(Properties props, OutputStream os, String comment, String encoding)
+        throws IOException
+    {
+        try {
+            XMLStreamWriter writer = new XMLStreamWriterImpl(os, encoding);
+            writer.writeStartDocument();
+            writer.writeDTD(PROPS_DTD_DECL);
+            writer.writeStartElement(ELEMENT_ROOT);
+            if (comment != null && comment.length() > 0) {
+                writer.writeStartElement(ELEMENT_COMMENT);
+                writer.writeCharacters(comment);
+                writer.writeEndElement();
+            }
+
+            for (String key : props.stringPropertyNames()) {
+                String val = props.getProperty(key);
+                writer.writeStartElement(ELEMENT_ENTRY);
+                writer.writeAttribute(ATTR_KEY, key);
+                writer.writeCharacters(val);
+                writer.writeEndElement();
+            }
+
+            writer.writeEndElement();
+            writer.writeEndDocument();
+            writer.close();
+        } catch (XMLStreamException e) {
+            if (e.getCause() instanceof UnsupportedEncodingException) {
+                throw (UnsupportedEncodingException) e.getCause();
+            }
+            throw new IOException(e);
+        }
+
+    }
+    ////////////////////////////////////////////////////////////////////
+    // Validate while parsing
+    ////////////////////////////////////////////////////////////////////
+    final static String ALLOWED_ELEMENTS = "properties, comment, entry";
+    final static String ALLOWED_COMMENT = "comment";
+    ////////////////////////////////////////////////////////////////////
+    // Handler methods
+    ////////////////////////////////////////////////////////////////////
+    StringBuffer buf = new StringBuffer();
+    boolean sawComment = false;
+    boolean validEntry = false;
+    int rootElem = 0;
+    String key;
+    String rootElm;
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes)
+        throws SAXException
+    {
+        if (rootElem < 2) {
+            rootElem++;
+        }
+
+        if (rootElm == null) {
+            fatalError(new SAXParseException("An XML properties document must contain"
+                    + " the DOCTYPE declaration as defined by java.util.Properties.", null));
+        }
+
+        if (rootElem == 1 && !rootElm.equals(qName)) {
+            fatalError(new SAXParseException("Document root element \"" + qName
+                    + "\", must match DOCTYPE root \"" + rootElm + "\"", null));
+        }
+        if (!ALLOWED_ELEMENTS.contains(qName)) {
+            fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
+        }
+        if (qName.equals(ELEMENT_ENTRY)) {
+            validEntry = true;
+            key = attributes.getValue(ATTR_KEY);
+            if (key == null) {
+                fatalError(new SAXParseException("Attribute \"key\" is required and must be specified for element type \"entry\"", null));
+            }
+        } else if (qName.equals(ALLOWED_COMMENT)) {
+            if (sawComment) {
+                fatalError(new SAXParseException("Only one comment element may be allowed. "
+                        + "The content of element type \"properties\" must match \"(comment?,entry*)\"", null));
+            }
+            sawComment = true;
+        }
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        if (validEntry) {
+            buf.append(ch, start, length);
+        }
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (!ALLOWED_ELEMENTS.contains(qName)) {
+            fatalError(new SAXParseException("Element: " + qName + " is invalid, must match  \"(comment?,entry*)\".", null));
+        }
+
+        if (validEntry) {
+            properties.setProperty(key, buf.toString());
+            buf.delete(0, buf.length());
+            validEntry = false;
+        }
+    }
+
+    @Override
+    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
+        rootElm = name;
+    }
+
+    @Override
+    public InputSource resolveEntity(String pubid, String sysid)
+            throws SAXException, IOException {
+        {
+            if (sysid.equals(PROPS_DTD_URI)) {
+                InputSource is;
+                is = new InputSource(new StringReader(PROPS_DTD));
+                is.setSystemId(PROPS_DTD_URI);
+                return is;
+            }
+            throw new SAXException("Invalid system identifier: " + sysid);
+        }
+    }
+
+    @Override
+    public void error(SAXParseException x) throws SAXException {
+        throw x;
+    }
+
+    @Override
+    public void fatalError(SAXParseException x) throws SAXException {
+        throw x;
+    }
+
+    @Override
+    public void warning(SAXParseException x) throws SAXException {
+        throw x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/SAXParser.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * Defines the API that wraps an {@link org.xml.sax.XMLReader}
+ * implementation class. In JAXP 1.0, this class wrapped the
+ * {@link org.xml.sax.Parser} interface, however this interface was
+ * replaced by the {@link org.xml.sax.XMLReader}. For ease
+ * of transition, this class continues to support the same name
+ * and interface as well as supporting new methods.
+ *
+ * An instance of this class can be obtained from the
+ * {@link javax.xml.parsers.SAXParserFactory#newSAXParser()} method.
+ * Once an instance of this class is obtained, XML can be parsed from
+ * a variety of input sources. These input sources are InputStreams,
+ * Files, URLs, and SAX InputSources.<p>
+ *
+ * This static method creates a new factory instance based
+ * on a system property setting or uses the platform default
+ * if no property has been defined.<p>
+ *
+ * The system property that controls which Factory implementation
+ * to create is named <code>&quot;javax.xml.parsers.SAXParserFactory&quot;</code>.
+ * This property names a class that is a concrete subclass of this
+ * abstract class. If no property is defined, a platform default
+ * will be used.</p>
+ *
+ * As the content is parsed by the underlying parser, methods of the
+ * given
+ * {@link org.xml.sax.helpers.DefaultHandler} are called.<p>
+ *
+ * Implementors of this class which wrap an underlaying implementation
+ * can consider using the {@link org.xml.sax.helpers.ParserAdapter}
+ * class to initially adapt their SAX1 implementation to work under
+ * this revised class.
+ *
+ * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
+ * @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:09 $
+ *
+ * @author Joe Wang
+ * This is a subset of that in JAXP, javax.xml.parsers.SAXParser
+ *
+ */
+public abstract class SAXParser {
+
+    /**
+     * <p>Protected constructor to prevent instantiation.</p>
+     */
+    protected SAXParser() {
+    }
+
+    /**
+     * Parse the content of the given {@link java.io.InputStream}
+     * instance as XML using the specified
+     * {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param is InputStream containing the content to be parsed.
+     * @param dh The SAX DefaultHandler to use.
+     *
+     * @throws IllegalArgumentException If the given InputStream is null.
+     * @throws IOException If any IO errors occur.
+     * @throws SAXException If any SAX errors occur during processing.
+     *
+     * @see org.xml.sax.DocumentHandler
+     */
+    public void parse(InputStream is, DefaultHandler dh)
+        throws SAXException, IOException
+    {
+        if (is == null) {
+            throw new IllegalArgumentException("InputStream cannot be null");
+        }
+
+        InputSource input = new InputSource(is);
+        this.parse(input, dh);
+    }
+
+    /**
+     * Parse the content described by the giving Uniform Resource
+     * Identifier (URI) as XML using the specified
+     * {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param uri The location of the content to be parsed.
+     * @param dh The SAX DefaultHandler to use.
+     *
+     * @throws IllegalArgumentException If the uri is null.
+     * @throws IOException If any IO errors occur.
+     * @throws SAXException If any SAX errors occur during processing.
+     *
+     * @see org.xml.sax.DocumentHandler
+     */
+    public void parse(String uri, DefaultHandler dh)
+        throws SAXException, IOException
+    {
+        if (uri == null) {
+            throw new IllegalArgumentException("uri cannot be null");
+        }
+
+        InputSource input = new InputSource(uri);
+        this.parse(input, dh);
+    }
+
+    /**
+     * Parse the content of the file specified as XML using the
+     * specified {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param f The file containing the XML to parse
+     * @param dh The SAX DefaultHandler to use.
+     *
+     * @throws IllegalArgumentException If the File object is null.
+     * @throws IOException If any IO errors occur.
+     * @throws SAXException If any SAX errors occur during processing.
+     *
+     * @see org.xml.sax.DocumentHandler
+     */
+    public void parse(File f, DefaultHandler dh)
+        throws SAXException, IOException
+    {
+        if (f == null) {
+            throw new IllegalArgumentException("File cannot be null");
+        }
+
+        //convert file to appropriate URI, f.toURI().toASCIIString()
+        //converts the URI to string as per rule specified in
+        //RFC 2396,
+        InputSource input = new InputSource(f.toURI().toASCIIString());
+        this.parse(input, dh);
+    }
+
+    /**
+     * Parse the content given {@link org.xml.sax.InputSource}
+     * as XML using the specified
+     * {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param is The InputSource containing the content to be parsed.
+     * @param dh The SAX DefaultHandler to use.
+     *
+     * @throws IllegalArgumentException If the <code>InputSource</code> object
+     *   is <code>null</code>.
+     * @throws IOException If any IO errors occur.
+     * @throws SAXException If any SAX errors occur during processing.
+     *
+     * @see org.xml.sax.DocumentHandler
+     */
+    public void parse(InputSource is, DefaultHandler dh)
+        throws SAXException, IOException
+    {
+        if (is == null) {
+            throw new IllegalArgumentException("InputSource cannot be null");
+        }
+
+        XMLReader reader = this.getXMLReader();
+        if (dh != null) {
+            reader.setContentHandler(dh);
+            reader.setEntityResolver(dh);
+            reader.setErrorHandler(dh);
+            reader.setDTDHandler(dh);
+        }
+        reader.parse(is);
+    }
+
+    /**
+     * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the
+     * implementation of this class.
+     *
+     * @return The XMLReader that is encapsulated by the
+     *         implementation of this class.
+     *
+     * @throws SAXException If any SAX errors occur during processing.
+     */
+    public abstract XMLReader getXMLReader() throws SAXException;
+
+    /**
+     * Indicates whether or not this parser is configured to
+     * understand namespaces.
+     *
+     * @return true if this parser is configured to
+     *         understand namespaces; false otherwise.
+     */
+    public abstract boolean isNamespaceAware();
+
+    /**
+     * Indicates whether or not this parser is configured to
+     * validate XML documents.
+     *
+     * @return true if this parser is configured to
+     *         validate XML documents; false otherwise.
+     */
+    public abstract boolean isValidating();
+
+    /**
+     * <p>Get the XInclude processing mode for this parser.</p>
+     *
+     * @return
+     *      the return value of
+     *      the {@link SAXParserFactory#isXIncludeAware()}
+     *      when this parser was created from factory.
+     *
+     * @throws UnsupportedOperationException When implementation does not
+     *   override this method
+     *
+     * @since 1.5
+     *
+     * @see SAXParserFactory#setXIncludeAware(boolean)
+     */
+    public boolean isXIncludeAware() {
+        throw new UnsupportedOperationException(
+                "This parser does not support specification \""
+                + this.getClass().getPackage().getSpecificationTitle()
+                + "\" version \""
+                + this.getClass().getPackage().getSpecificationVersion()
+                + "\"");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/XMLStreamException.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+/**
+ * A copy of the StAX XMLStreamException without Location support
+ *
+ * The base exception for unexpected processing errors.  This Exception
+ * class is used to report well-formedness errors as well as unexpected
+ * processing conditions.
+ * @version 1.0
+ * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved.
+ * @since 1.6
+ */
+
+public class XMLStreamException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+
+    protected Throwable nested;
+
+    /**
+     * Default constructor
+     */
+    public XMLStreamException() {
+        super();
+    }
+
+    /**
+     * Construct an exception with the assocated message.
+     *
+     * @param msg the message to report
+     */
+    public XMLStreamException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct an exception with the assocated exception
+     *
+     * @param th a nested exception
+     */
+    public XMLStreamException(Throwable th) {
+        super(th);
+        nested = th;
+    }
+
+    /**
+     * Construct an exception with the assocated message and exception
+     *
+     * @param th a nested exception
+     * @param msg the message to report
+     */
+    public XMLStreamException(String msg, Throwable th) {
+        super(msg, th);
+        nested = th;
+    }
+
+    /**
+     * Gets the nested exception.
+     *
+     * @return Nested exception
+     */
+    public Throwable getNestedException() {
+        return nested;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/XMLStreamWriter.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml;
+
+/**
+ * Basic XMLStreamWriter for writing simple XML files such as those
+ * defined in java.util.Properties
+ *
+ * This is a subset of javax.xml.stream.XMLStreamWriter
+ *
+ * @author Joe Wang
+ */
+public  interface XMLStreamWriter {
+
+    //Defaults the XML version to 1.0, and the encoding to utf-8
+    public final static String DEFAULT_XML_VERSION = "1.0";
+    public final static String DEFAULT_ENCODING = "UTF-8";
+
+    /**
+     * Writes a start tag to the output.  All writeStartElement methods
+     * open a new scope in the internal namespace context.  Writing the
+     * corresponding EndElement causes the scope to be closed.
+     * @param localName local name of the tag, may not be null
+     * @throws XMLStreamException
+     */
+    public void writeStartElement(String localName) throws XMLStreamException;
+
+    /**
+     * Writes an empty element tag to the output
+     * @param localName local name of the tag, may not be null
+     * @throws XMLStreamException
+     */
+    public void writeEmptyElement(String localName) throws XMLStreamException;
+
+    /**
+     * Writes an end tag to the output relying on the internal
+     * state of the writer to determine the prefix and local name
+     * of the event.
+     * @throws XMLStreamException
+     */
+    public void writeEndElement() throws XMLStreamException;
+
+    /**
+     * Closes any start tags and writes corresponding end tags.
+     * @throws XMLStreamException
+     */
+    public void writeEndDocument() throws XMLStreamException;
+
+    /**
+     * Close this writer and free any resources associated with the
+     * writer.  This must not close the underlying output stream.
+     * @throws XMLStreamException
+     */
+    public void close() throws XMLStreamException;
+
+    /**
+     * Write any cached data to the underlying output mechanism.
+     * @throws XMLStreamException
+     */
+    public void flush() throws XMLStreamException;
+
+    /**
+     * Writes an attribute to the output stream without
+     * a prefix.
+     * @param localName the local name of the attribute
+     * @param value the value of the attribute
+     * @throws IllegalStateException if the current state does not allow Attribute writing
+     * @throws XMLStreamException
+     */
+    public void writeAttribute(String localName, String value)
+            throws XMLStreamException;
+
+    /**
+     * Writes a CData section
+     * @param data the data contained in the CData Section, may not be null
+     * @throws XMLStreamException
+     */
+    public void writeCData(String data) throws XMLStreamException;
+
+    /**
+     * Write a DTD section.  This string represents the entire doctypedecl production
+     * from the XML 1.0 specification.
+     *
+     * @param dtd the DTD to be written
+     * @throws XMLStreamException
+     */
+    public void writeDTD(String dtd) throws XMLStreamException;
+
+    /**
+     * Write the XML Declaration. Defaults the XML version to 1.0, and the encoding to utf-8
+     * @throws XMLStreamException
+     */
+    public void writeStartDocument() throws XMLStreamException;
+
+    /**
+     * Write the XML Declaration. Defaults the the encoding to utf-8
+     * @param version version of the xml document
+     * @throws XMLStreamException
+     */
+    public void writeStartDocument(String version) throws XMLStreamException;
+
+    /**
+     * Write the XML Declaration.  Note that the encoding parameter does
+     * not set the actual encoding of the underlying output.  That must
+     * be set when the instance of the XMLStreamWriter is created using the
+     * XMLOutputFactory
+     * @param encoding encoding of the xml declaration
+     * @param version version of the xml document
+     * @throws XMLStreamException If given encoding does not match encoding
+     * of the underlying stream
+     */
+    public void writeStartDocument(String encoding, String version)
+        throws XMLStreamException;
+
+    /**
+     * Write text to the output
+     * @param text the value to write
+     * @throws XMLStreamException
+     */
+    public void writeCharacters(String text) throws XMLStreamException;
+
+    /**
+     * Write text to the output
+     * @param text the value to write
+     * @param start the starting position in the array
+     * @param len the number of characters to write
+     * @throws XMLStreamException
+     */
+    public void writeCharacters(char[] text, int start, int len)
+        throws XMLStreamException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/Attrs.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import jdk.internal.org.xml.sax.Attributes;
+
+public class Attrs implements Attributes {
+
+    /**
+     * Attributes string array. Each individual attribute is represented by four
+     * strings: namespace URL(+0), qname(+1), local name(+2), value(+3),
+     * type(+4), declared["d"] and default["D"](+5). In order to find attribute
+     * by the attrubute index, the attribute index MUST be multiplied by 8. The
+     * result will point to the attribute namespace URL.
+     */
+    /* pkg */ String[] mItems;
+    /**
+     * Number of attributes in the attributes string array.
+     */
+    private char mLength;
+    /**
+     * current index
+     */
+    private char mAttrIdx = 0;
+
+    /**
+     * Constructor.
+     */
+    public Attrs() {
+        //              The default number of attributies capacity is 8.
+        mItems = new String[(8 << 3)];
+    }
+
+    /**
+     * Sets up the number of attributes and ensure the capacity of the attribute
+     * string array.
+     *
+     * @param length The number of attributes in the object.
+     */
+    public void setLength(char length) {
+        if (length > ((char) (mItems.length >> 3))) {
+            mItems = new String[length << 3];
+        }
+        mLength = length;
+    }
+
+    /**
+     * Return the number of attributes in the list.
+     *
+     * <p>Once you know the number of attributes, you can iterate through the
+     * list.</p>
+     *
+     * @return The number of attributes in the list.
+     * @see #getURI(int)
+     * @see #getLocalName(int)
+     * @see #getQName(int)
+     * @see #getType(int)
+     * @see #getValue(int)
+     */
+    public int getLength() {
+        return mLength;
+    }
+
+    /**
+     * Look up an attribute's Namespace URI by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The Namespace URI, or the empty string if none is available, or
+     * null if the index is out of range.
+     * @see #getLength
+     */
+    public String getURI(int index) {
+        return ((index >= 0) && (index < mLength))
+                ? (mItems[index << 3])
+                : null;
+    }
+
+    /**
+     * Look up an attribute's local name by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The local name, or the empty string if Namespace processing is
+     * not being performed, or null if the index is out of range.
+     * @see #getLength
+     */
+    public String getLocalName(int index) {
+        return ((index >= 0) && (index < mLength))
+                ? (mItems[(index << 3) + 2])
+                : null;
+    }
+
+    /**
+     * Look up an attribute's XML 1.0 qualified name by index.
+     *
+     * @param index The attribute index (zero-based).
+     * @return The XML 1.0 qualified name, or the empty string if none is
+     * available, or null if the index is out of range.
+     * @see #getLength
+     */
+    public String getQName(int index) {
+        if ((index < 0) || (index >= mLength)) {
+            return null;
+        }
+        return mItems[(index << 3) + 1];
+    }
+
+    /**
+     * Look up an attribute's type by index.
+     *
+     * <p>The attribute type is one of the strings "CDATA", "ID", "IDREF",
+     * "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION"
+     * (always in upper case).</p>
+     *
+     * <p>If the parser has not read a declaration for the attribute, or if the
+     * parser does not report attribute types, then it must return the value
+     * "CDATA" as stated in the XML 1.0 Recommentation (clause 3.3.3,
+     * "Attribute-Value Normalization").</p>
+     *
+     * <p>For an enumerated attribute that is not a notation, the parser will
+     * report the type as "NMTOKEN".</p>
+     *
+     * @param index The attribute index (zero-based).
+     * @return The attribute's type as a string, or null if the index is out of
+     * range.
+     * @see #getLength
+     */
+    public String getType(int index) {
+        return ((index >= 0) && (index < (mItems.length >> 3)))
+                ? (mItems[(index << 3) + 4])
+                : null;
+    }
+
+    /**
+     * Look up an attribute's value by index.
+     *
+     * <p>If the attribute value is a list of tokens (IDREFS, ENTITIES, or
+     * NMTOKENS), the tokens will be concatenated into a single string with each
+     * token separated by a single space.</p>
+     *
+     * @param index The attribute index (zero-based).
+     * @return The attribute's value as a string, or null if the index is out of
+     * range.
+     * @see #getLength
+     */
+    public String getValue(int index) {
+        return ((index >= 0) && (index < mLength))
+                ? (mItems[(index << 3) + 3])
+                : null;
+    }
+
+    /**
+     * Look up the index of an attribute by Namespace name.
+     *
+     * @param uri The Namespace URI, or the empty string if the name has no
+     * Namespace URI.
+     * @param localName The attribute's local name.
+     * @return The index of the attribute, or -1 if it does not appear in the
+     * list.
+     */
+    public int getIndex(String uri, String localName) {
+        char len = mLength;
+        for (char idx = 0; idx < len; idx++) {
+            if ((mItems[idx << 3]).equals(uri)
+                    && mItems[(idx << 3) + 2].equals(localName)) {
+                return idx;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Look up the index of an attribute by Namespace name.
+     *
+     * @param uri The Namespace URI, or the empty string if the name has no
+     * Namespace URI. <code>null</code> value enforce the search by the local
+     * name only.
+     * @param localName The attribute's local name.
+     * @return The index of the attribute, or -1 if it does not appear in the
+     * list.
+     */
+    /* pkg */ int getIndexNullNS(String uri, String localName) {
+        char len = mLength;
+        if (uri != null) {
+            for (char idx = 0; idx < len; idx++) {
+                if ((mItems[idx << 3]).equals(uri)
+                        && mItems[(idx << 3) + 2].equals(localName)) {
+                    return idx;
+                }
+            }
+        } else {
+            for (char idx = 0; idx < len; idx++) {
+                if (mItems[(idx << 3) + 2].equals(localName)) {
+                    return idx;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Look up the index of an attribute by XML 1.0 qualified name.
+     *
+     * @param qName The qualified (prefixed) name.
+     * @return The index of the attribute, or -1 if it does not appear in the
+     * list.
+     */
+    public int getIndex(String qName) {
+        char len = mLength;
+        for (char idx = 0; idx < len; idx++) {
+            if (mItems[(idx << 3) + 1].equals(qName)) {
+                return idx;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Look up an attribute's type by Namespace name.
+     *
+     * <p>See {@link #getType(int) getType(int)} for a description of the
+     * possible types.</p>
+     *
+     * @param uri The Namespace URI, or the empty String if the name has no
+     * Namespace URI.
+     * @param localName The local name of the attribute.
+     * @return The attribute type as a string, or null if the attribute is not
+     * in the list or if Namespace processing is not being performed.
+     */
+    public String getType(String uri, String localName) {
+        int idx = getIndex(uri, localName);
+        return (idx >= 0) ? (mItems[(idx << 3) + 4]) : null;
+    }
+
+    /**
+     * Look up an attribute's type by XML 1.0 qualified name.
+     *
+     * <p>See {@link #getType(int) getType(int)} for a description of the
+     * possible types.</p>
+     *
+     * @param qName The XML 1.0 qualified name.
+     * @return The attribute type as a string, or null if the attribute is not
+     * in the list or if qualified names are not available.
+     */
+    public String getType(String qName) {
+        int idx = getIndex(qName);
+        return (idx >= 0) ? (mItems[(idx << 3) + 4]) : null;
+    }
+
+    /**
+     * Look up an attribute's value by Namespace name.
+     *
+     * <p>See {@link #getValue(int) getValue(int)} for a description of the
+     * possible values.</p>
+     *
+     * @param uri The Namespace URI, or the empty String if the name has no
+     * Namespace URI.
+     * @param localName The local name of the attribute.
+     * @return The attribute value as a string, or null if the attribute is not
+     * in the list.
+     */
+    public String getValue(String uri, String localName) {
+        int idx = getIndex(uri, localName);
+        return (idx >= 0) ? (mItems[(idx << 3) + 3]) : null;
+    }
+
+    /**
+     * Look up an attribute's value by XML 1.0 qualified name.
+     *
+     * <p>See {@link #getValue(int) getValue(int)} for a description of the
+     * possible values.</p>
+     *
+     * @param qName The XML 1.0 qualified name.
+     * @return The attribute value as a string, or null if the attribute is not
+     * in the list or if qualified names are not available.
+     */
+    public String getValue(String qName) {
+        int idx = getIndex(qName);
+        return (idx >= 0) ? (mItems[(idx << 3) + 3]) : null;
+    }
+
+    /**
+     * Returns false unless the attribute was declared in the DTD. This helps
+     * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+     * were declared (and hence are usually valid), and those that were not (and
+     * which are never valid).
+     *
+     * @param index The attribute index (zero-based).
+     * @return true if the attribute was declared in the DTD, false otherwise.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the supplied
+     * index does not identify an attribute.
+     */
+    public boolean isDeclared(int index) {
+        if ((index < 0) || (index >= mLength)) {
+            throw new ArrayIndexOutOfBoundsException("");
+        }
+
+        return ((mItems[(index << 3) + 5]) != null);
+    }
+
+    /**
+     * Returns false unless the attribute was declared in the DTD. This helps
+     * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+     * were declared (and hence are usually valid), and those that were not (and
+     * which are never valid).
+     *
+     * @param qName The XML qualified (prefixed) name.
+     * @return true if the attribute was declared in the DTD, false otherwise.
+     * @exception java.lang.IllegalArgumentException When the supplied name does
+     * not identify an attribute.
+     */
+    public boolean isDeclared(String qName) {
+        int idx = getIndex(qName);
+        if (idx < 0) {
+            throw new IllegalArgumentException("");
+        }
+
+        return ((mItems[(idx << 3) + 5]) != null);
+    }
+
+    /**
+     * Returns false unless the attribute was declared in the DTD. This helps
+     * distinguish two kinds of attributes that SAX reports as CDATA: ones that
+     * were declared (and hence are usually valid), and those that were not (and
+     * which are never valid).
+     *
+     * <p>Remember that since DTDs do not "understand" namespaces, the namespace
+     * URI associated with an attribute may not have come from the DTD. The
+     * declaration will have applied to the attribute's <em>qName</em>.
+     *
+     * @param uri The Namespace URI, or the empty string if the name has no
+     * Namespace URI.
+     * @param localName The attribute's local name.
+     * @return true if the attribute was declared in the DTD, false otherwise.
+     * @exception java.lang.IllegalArgumentException When the supplied names do
+     * not identify an attribute.
+     */
+    public boolean isDeclared(String uri, String localName) {
+        int idx = getIndex(uri, localName);
+        if (idx < 0) {
+            throw new IllegalArgumentException("");
+        }
+
+        return ((mItems[(idx << 3) + 5]) != null);
+    }
+
+    /**
+     * Returns true unless the attribute value was provided by DTD defaulting.
+     *
+     * @param index The attribute index (zero-based).
+     * @return true if the value was found in the XML text, false if the value
+     * was provided by DTD defaulting.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the supplied
+     * index does not identify an attribute.
+     */
+    public boolean isSpecified(int index) {
+        if ((index < 0) || (index >= mLength)) {
+            throw new ArrayIndexOutOfBoundsException("");
+        }
+
+        String str = mItems[(index << 3) + 5];
+        return ((str != null) ? (str.charAt(0) == 'd') : true);
+    }
+
+    /**
+     * Returns true unless the attribute value was provided by DTD defaulting.
+     *
+     * <p>Remember that since DTDs do not "understand" namespaces, the namespace
+     * URI associated with an attribute may not have come from the DTD. The
+     * declaration will have applied to the attribute's <em>qName</em>.
+     *
+     * @param uri The Namespace URI, or the empty string if the name has no
+     * Namespace URI.
+     * @param localName The attribute's local name.
+     * @return true if the value was found in the XML text, false if the value
+     * was provided by DTD defaulting.
+     * @exception java.lang.IllegalArgumentException When the supplied names do
+     * not identify an attribute.
+     */
+    public boolean isSpecified(String uri, String localName) {
+        int idx = getIndex(uri, localName);
+        if (idx < 0) {
+            throw new IllegalArgumentException("");
+        }
+
+        String str = mItems[(idx << 3) + 5];
+        return ((str != null) ? (str.charAt(0) == 'd') : true);
+    }
+
+    /**
+     * Returns true unless the attribute value was provided by DTD defaulting.
+     *
+     * @param qName The XML qualified (prefixed) name.
+     * @return true if the value was found in the XML text, false if the value
+     * was provided by DTD defaulting.
+     * @exception java.lang.IllegalArgumentException When the supplied name does
+     * not identify an attribute.
+     */
+    public boolean isSpecified(String qName) {
+        int idx = getIndex(qName);
+        if (idx < 0) {
+            throw new IllegalArgumentException("");
+        }
+
+        String str = mItems[(idx << 3) + 5];
+        return ((str != null) ? (str.charAt(0) == 'd') : true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/Input.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+
+/**
+ * A parsed entity input state.
+ *
+ * This class represents a parsed entity input state. The parser uses
+ * an instance of this class to manage input.
+ */
+
+public class Input {
+
+    /** The entity public identifier or null. */
+    public String pubid;
+    /** The entity systen identifier or null. */
+    public String sysid;
+    /** The encoding from XML declaration or null */
+    public String xmlenc;
+    /** The XML version from XML declaration or 0x0000 */
+    public char xmlver;
+    /** The entity reader. */
+    public Reader src;
+    /** The character buffer. */
+    public char[] chars;
+    /** The length of the character buffer. */
+    public int chLen;
+    /** The index of the next character to read. */
+    public int chIdx;
+    /** The next input in a chain. */
+    public Input next;
+
+    /**
+     * Constructor.
+     *
+     * @param buffsize The input buffer size.
+     */
+    public Input(int buffsize) {
+        chars = new char[buffsize];
+        chLen = chars.length;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param buff The input buffer.
+     */
+    public Input(char[] buff) {
+        chars = buff;
+        chLen = chars.length;
+    }
+
+    /**
+     * Constructor.
+     */
+    public Input() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/Pair.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+
+/**
+ * A name with value pair.
+ *
+ * This class keeps name with value pair with additional information and
+ * supports pair chaining.
+ */
+public class Pair {
+
+    /** The pair name. */
+    public String name;
+    /** The pair value. */
+    public String value;
+    /** The pair numeric value. */
+    public int num;
+    /** The characters of name. */
+    public char[] chars;
+    /** The pair identifier. */
+    public int id;
+    /** The list of associated pairs. */
+    public Pair list;
+    /** The next pair in a chain. */
+    public Pair next;
+
+    /**
+     * Creates a qualified name string from qualified name.
+     *
+     * @return The qualified name string.
+     */
+    public String qname() {
+        return new String(chars, 1, chars.length - 1);
+    }
+
+    /**
+     * Creates a local name string from qualified name.
+     *
+     * @return The local name string.
+     */
+    public String local() {
+        if (chars[0] != 0) {
+            return new String(chars, chars[0] + 1, chars.length - chars[0] - 1);
+        }
+        return new String(chars, 1, chars.length - 1);
+    }
+
+    /**
+     * Creates a prefix string from qualified name.
+     *
+     * @return The prefix string.
+     */
+    public String pref() {
+        if (chars[0] != 0) {
+            return new String(chars, 1, chars[0] - 1);
+        }
+        return "";
+    }
+
+    /**
+     * Compares two qualified name prefixes.
+     *
+     * @param qname A qualified name.
+     * @return true if prefixes are equal.
+     */
+    public boolean eqpref(char[] qname) {
+        if (chars[0] == qname[0]) {
+            char len = chars[0];
+            for (char i = 1; i < len; i += 1) {
+                if (chars[i] != qname[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Compares two qualified names.
+     *
+     * @param qname A qualified name.
+     * @return true if qualified names are equal.
+     */
+    public boolean eqname(char[] qname) {
+        char len = (char) chars.length;
+        if (len == qname.length) {
+            for (char i = 0; i < len; i += 1) {
+                if (chars[i] != qname[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/Parser.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,3367 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+
+/**
+ * XML non-validating parser engine.
+ */
+public abstract class Parser {
+
+    public final static String FAULT = "";
+    protected final static int BUFFSIZE_READER = 512;
+    protected final static int BUFFSIZE_PARSER = 128;
+    /**
+     * The end of stream character.
+     */
+    public final static char EOS = 0xffff;
+    private Pair mNoNS; // there is no namespace
+    private Pair mXml;  // the xml namespace
+    private Map<String, Input> mEnt;  // the entities look up table
+    private Map<String, Input> mPEnt; // the parmeter entities look up table
+    protected boolean mIsSAlone;     // xml decl standalone flag
+    protected boolean mIsSAloneSet;  // standalone is explicitely set
+    protected boolean mIsNSAware;    // if true - namespace aware mode
+    protected int mPh;  // current phase of document processing
+    protected final static int PH_BEFORE_DOC = -1;  // before parsing
+    protected final static int PH_DOC_START = 0;   // document start
+    protected final static int PH_MISC_DTD = 1;   // misc before DTD
+    protected final static int PH_DTD = 2;   // DTD
+    protected final static int PH_DTD_MISC = 3;   // misc after DTD
+    protected final static int PH_DOCELM = 4;   // document's element
+    protected final static int PH_DOCELM_MISC = 5;   // misc after element
+    protected final static int PH_AFTER_DOC = 6;   // after parsing
+    protected int mEvt;  // current event type
+    protected final static int EV_NULL = 0;   // unknown
+    protected final static int EV_ELM = 1;   // empty element
+    protected final static int EV_ELMS = 2;   // start element
+    protected final static int EV_ELME = 3;   // end element
+    protected final static int EV_TEXT = 4;   // textual content
+    protected final static int EV_WSPC = 5;   // white space content
+    protected final static int EV_PI = 6;   // processing instruction
+    protected final static int EV_CDAT = 7;   // character data
+    protected final static int EV_COMM = 8;   // comment
+    protected final static int EV_DTD = 9;   // document type definition
+    protected final static int EV_ENT = 10;  // skipped entity
+    private char mESt; // built-in entity recognizer state
+    // mESt values:
+    //   0x100   : the initial state
+    //   > 0x100 : unrecognized name
+    //   < 0x100 : replacement character
+    protected char[] mBuff;       // parser buffer
+    protected int mBuffIdx;    // index of the last char
+    protected Pair mPref;       // stack of prefixes
+    protected Pair mElm;        // stack of elements
+    // mAttL.chars - element qname
+    // mAttL.next  - next element
+    // mAttL.list  - list of attributes defined on this element
+    // mAttL.list.chars - attribute qname
+    // mAttL.list.id    - a char representing attribute's type see below
+    // mAttL.list.next  - next attribute defined on the element
+    // mAttL.list.list  - devault value structure or null
+    // mAttL.list.list.chars - "name='value' " chars array for Input
+    //
+    // Attribute type character values:
+    // 'i' - "ID"
+    // 'r' - "IDREF"
+    // 'R' - "IDREFS"
+    // 'n' - "ENTITY"
+    // 'N' - "ENTITIES"
+    // 't' - "NMTOKEN"
+    // 'T' - "NMTOKENS"
+    // 'u' - enumeration type
+    // 'o' - "NOTATION"
+    // 'c' - "CDATA"
+    // see also: bkeyword() and atype()
+    //
+    protected Pair mAttL;       // list of defined attrs by element name
+    protected Input mDoc;        // document entity
+    protected Input mInp;        // stack of entities
+    private char[] mChars;      // reading buffer
+    private int mChLen;      // current capacity
+    private int mChIdx;      // index to the next char
+    protected Attrs mAttrs;      // attributes of the curr. element
+    private String[] mItems;      // attributes array of the curr. element
+    private char mAttrIdx;    // attributes counter/index
+    private String mUnent;  // unresolved entity name
+    private Pair mDltd;   // deleted objects for reuse
+    /**
+     * Default prefixes
+     */
+    private final static char NONS[];
+    private final static char XML[];
+    private final static char XMLNS[];
+
+    static {
+        NONS = new char[1];
+        NONS[0] = (char) 0;
+
+        XML = new char[4];
+        XML[0] = (char) 4;
+        XML[1] = 'x';
+        XML[2] = 'm';
+        XML[3] = 'l';
+
+        XMLNS = new char[6];
+        XMLNS[0] = (char) 6;
+        XMLNS[1] = 'x';
+        XMLNS[2] = 'm';
+        XMLNS[3] = 'l';
+        XMLNS[4] = 'n';
+        XMLNS[5] = 's';
+    }
+    /**
+     * ASCII character type array.
+     *
+     * This array maps an ASCII (7 bit) character to the character type.<br />
+     * Possible character type values are:<br /> - ' ' for any kind of white
+     * space character;<br /> - 'a' for any lower case alphabetical character
+     * value;<br /> - 'A' for any upper case alphabetical character value;<br />
+     * - 'd' for any decimal digit character value;<br /> - 'z' for any
+     * character less then ' ' except '\t', '\n', '\r';<br /> An ASCII (7 bit)
+     * character which does not fall in any category listed above is mapped to
+     * it self.
+     */
+    private static final byte asctyp[];
+    /**
+     * NMTOKEN character type array.
+     *
+     * This array maps an ASCII (7 bit) character to the character type.<br />
+     * Possible character type values are:<br /> - 0 for underscore ('_') or any
+     * lower and upper case alphabetical character value;<br /> - 1 for colon
+     * (':') character;<br /> - 2 for dash ('-') and dot ('.') or any decimal
+     * digit character value;<br /> - 3 for any kind of white space character<br
+     * /> An ASCII (7 bit) character which does not fall in any category listed
+     * above is mapped to 0xff.
+     */
+    private static final byte nmttyp[];
+
+    /**
+     * Static constructor.
+     *
+     * Sets up the ASCII character type array which is used by
+     * {@link #asctyp asctyp} method and NMTOKEN character type array.
+     */
+    static {
+        short i = 0;
+
+        asctyp = new byte[0x80];
+        while (i < ' ') {
+            asctyp[i++] = (byte) 'z';
+        }
+        asctyp['\t'] = (byte) ' ';
+        asctyp['\r'] = (byte) ' ';
+        asctyp['\n'] = (byte) ' ';
+        while (i < '0') {
+            asctyp[i] = (byte) i++;
+        }
+        while (i <= '9') {
+            asctyp[i++] = (byte) 'd';
+        }
+        while (i < 'A') {
+            asctyp[i] = (byte) i++;
+        }
+        while (i <= 'Z') {
+            asctyp[i++] = (byte) 'A';
+        }
+        while (i < 'a') {
+            asctyp[i] = (byte) i++;
+        }
+        while (i <= 'z') {
+            asctyp[i++] = (byte) 'a';
+        }
+        while (i < 0x80) {
+            asctyp[i] = (byte) i++;
+        }
+
+        nmttyp = new byte[0x80];
+        for (i = 0; i < '0'; i++) {
+            nmttyp[i] = (byte) 0xff;
+        }
+        while (i <= '9') {
+            nmttyp[i++] = (byte) 2;  // digits
+        }
+        while (i < 'A') {
+            nmttyp[i++] = (byte) 0xff;
+        }
+        // skiped upper case alphabetical character are already 0
+        for (i = '['; i < 'a'; i++) {
+            nmttyp[i] = (byte) 0xff;
+        }
+        // skiped lower case alphabetical character are already 0
+        for (i = '{'; i < 0x80; i++) {
+            nmttyp[i] = (byte) 0xff;
+        }
+        nmttyp['_'] = 0;
+        nmttyp[':'] = 1;
+        nmttyp['.'] = 2;
+        nmttyp['-'] = 2;
+        nmttyp[' '] = 3;
+        nmttyp['\t'] = 3;
+        nmttyp['\r'] = 3;
+        nmttyp['\n'] = 3;
+    }
+
+    /**
+     * Constructor.
+     */
+    protected Parser() {
+        mPh = PH_BEFORE_DOC;  // before parsing
+
+        //              Initialize the parser
+        mBuff = new char[BUFFSIZE_PARSER];
+        mAttrs = new Attrs();
+
+        //              Default namespace
+        mPref = pair(mPref);
+        mPref.name = "";
+        mPref.value = "";
+        mPref.chars = NONS;
+        mNoNS = mPref;  // no namespace
+        //              XML namespace
+        mPref = pair(mPref);
+        mPref.name = "xml";
+        mPref.value = "http://www.w3.org/XML/1998/namespace";
+        mPref.chars = XML;
+        mXml = mPref;  // XML namespace
+    }
+
+    /**
+     * Initializes parser's internals. Note, current input has to be set before
+     * this method is called.
+     */
+    protected void init() {
+        mUnent = null;
+        mElm = null;
+        mPref = mXml;
+        mAttL = null;
+        mPEnt = new HashMap<>();
+        mEnt = new HashMap<>();
+        mDoc = mInp;          // current input is document entity
+        mChars = mInp.chars;    // use document entity buffer
+        mPh = PH_DOC_START;  // the begining of the document
+    }
+
+    /**
+     * Cleans up parser internal resources.
+     */
+    protected void cleanup() {
+        //              Default attributes
+        while (mAttL != null) {
+            while (mAttL.list != null) {
+                if (mAttL.list.list != null) {
+                    del(mAttL.list.list);
+                }
+                mAttL.list = del(mAttL.list);
+            }
+            mAttL = del(mAttL);
+        }
+        //              Element stack
+        while (mElm != null) {
+            mElm = del(mElm);
+        }
+        //              Namespace prefixes
+        while (mPref != mXml) {
+            mPref = del(mPref);
+        }
+        //              Inputs
+        while (mInp != null) {
+            pop();
+        }
+        //              Document reader
+        if ((mDoc != null) && (mDoc.src != null)) {
+            try {
+                mDoc.src.close();
+            } catch (IOException ioe) {
+            }
+        }
+        mPEnt = null;
+        mEnt = null;
+        mDoc = null;
+        mPh = PH_AFTER_DOC;  // before documnet processing
+    }
+
+    /**
+     * Processes a portion of document. This method returns one of EV_*
+     * constants as an identifier of the portion of document have been read.
+     *
+     * @return Identifier of processed document portion.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    protected int step() throws Exception {
+        mEvt = EV_NULL;
+        int st = 0;
+        while (mEvt == EV_NULL) {
+            char ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+            switch (st) {
+                case 0:     // all sorts of markup (dispetcher)
+                    if (ch != '<') {
+                        bkch();
+                        mBuffIdx = -1;  // clean parser buffer
+                        st = 1;
+                        break;
+                    }
+                    switch (getch()) {
+                        case '/':  // the end of the element content
+                            mEvt = EV_ELME;
+                            if (mElm == null) {
+                                panic(FAULT);
+                            }
+                            //          Check element's open/close tags balance
+                            mBuffIdx = -1;  // clean parser buffer
+                            bname(mIsNSAware);
+                            char[] chars = mElm.chars;
+                            if (chars.length == (mBuffIdx + 1)) {
+                                for (char i = 1; i <= mBuffIdx; i += 1) {
+                                    if (chars[i] != mBuff[i]) {
+                                        panic(FAULT);
+                                    }
+                                }
+                            } else {
+                                panic(FAULT);
+                            }
+                            //          Skip white spaces before '>'
+                            if (wsskip() != '>') {
+                                panic(FAULT);
+                            }
+                            getch();  // read '>'
+                            break;
+
+                        case '!':  // a comment or a CDATA
+                            ch = getch();
+                            bkch();
+                            switch (ch) {
+                                case '-':  // must be a comment
+                                    mEvt = EV_COMM;
+                                    comm();
+                                    break;
+
+                                case '[':  // must be a CDATA section
+                                    mEvt = EV_CDAT;
+                                    cdat();
+                                    break;
+
+                                default:   // must be 'DOCTYPE'
+                                    mEvt = EV_DTD;
+                                    dtd();
+                                    break;
+                            }
+                            break;
+
+                        case '?':  // processing instruction
+                            mEvt = EV_PI;
+                            pi();
+                            break;
+
+                        default:  // must be the first char of an xml name
+                            bkch();
+                            //          Read an element name and put it on top of the
+                            //          element stack
+                            mElm = pair(mElm);  // add new element to the stack
+                            mElm.chars = qname(mIsNSAware);
+                            mElm.name = mElm.local();
+                            mElm.id = (mElm.next != null) ? mElm.next.id : 0;  // flags
+                            mElm.num = 0;     // namespace counter
+                            //          Find the list of defined attributs of the current
+                            //          element
+                            Pair elm = find(mAttL, mElm.chars);
+                            mElm.list = (elm != null) ? elm.list : null;
+                            //          Read attributes till the end of the element tag
+                            mAttrIdx = 0;
+                            Pair att = pair(null);
+                            att.num = 0;  // clear attribute's flags
+                            attr(att);     // get all attributes inc. defaults
+                            del(att);
+                            mElm.value = (mIsNSAware) ? rslv(mElm.chars) : null;
+                            //          Skip white spaces before '>'
+                            switch (wsskip()) {
+                                case '>':
+                                    getch();  // read '>'
+                                    mEvt = EV_ELMS;
+                                    break;
+
+                                case '/':
+                                    getch();  // read '/'
+                                    if (getch() != '>') // read '>'
+                                    {
+                                        panic(FAULT);
+                                    }
+                                    mEvt = EV_ELM;
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                            }
+                            break;
+                    }
+                    break;
+
+                case 1:     // read white space
+                    switch (ch) {
+                        case ' ':
+                        case '\t':
+                        case '\n':
+                            bappend(ch);
+                            break;
+
+                        case '\r':              // EOL processing [#2.11]
+                            if (getch() != '\n') {
+                                bkch();
+                            }
+                            bappend('\n');
+                            break;
+
+                        case '<':
+                            mEvt = EV_WSPC;
+                            bkch();
+                            bflash_ws();
+                            break;
+
+                        default:
+                            bkch();
+                            st = 2;
+                            break;
+                    }
+                    break;
+
+                case 2:     // read the text content of the element
+                    switch (ch) {
+                        case '&':
+                            if (mUnent == null) {
+                                //              There was no unresolved entity on previous step.
+                                if ((mUnent = ent('x')) != null) {
+                                    mEvt = EV_TEXT;
+                                    bkch();      // move back to ';' after entity name
+                                    setch('&');  // parser must be back on next step
+                                    bflash();
+                                }
+                            } else {
+                                //              There was unresolved entity on previous step.
+                                mEvt = EV_ENT;
+                                skippedEnt(mUnent);
+                                mUnent = null;
+                            }
+                            break;
+
+                        case '<':
+                            mEvt = EV_TEXT;
+                            bkch();
+                            bflash();
+                            break;
+
+                        case '\r':  // EOL processing [#2.11]
+                            if (getch() != '\n') {
+                                bkch();
+                            }
+                            bappend('\n');
+                            break;
+
+                        case EOS:
+                            panic(FAULT);
+
+                        default:
+                            bappend(ch);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+
+        return mEvt;
+    }
+
+    /**
+     * Parses the document type declaration.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void dtd() throws Exception {
+        char ch;
+        String str = null;
+        String name = null;
+        Pair psid = null;
+        // read 'DOCTYPE'
+        if ("DOCTYPE".equals(name(false)) != true) {
+            panic(FAULT);
+        }
+        mPh = PH_DTD;  // DTD
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // read the document type name
+                    if (chtyp(ch) != ' ') {
+                        bkch();
+                        name = name(mIsNSAware);
+                        wsskip();
+                        st = 1;  // read 'PUPLIC' or 'SYSTEM'
+                    }
+                    break;
+
+                case 1:     // read 'PUPLIC' or 'SYSTEM'
+                    switch (chtyp(ch)) {
+                        case 'A':
+                            bkch();
+                            psid = pubsys(' ');
+                            st = 2;  // skip spaces before internal subset
+                            docType(name, psid.name, psid.value);
+                            break;
+
+                        case '[':
+                            bkch();
+                            st = 2;    // skip spaces before internal subset
+                            docType(name, null, null);
+                            break;
+
+                        case '>':
+                            bkch();
+                            st = 3;    // skip spaces after internal subset
+                            docType(name, null, null);
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 2:     // skip spaces before internal subset
+                    switch (chtyp(ch)) {
+                        case '[':
+                            //          Process internal subset
+                            dtdsub();
+                            st = 3;  // skip spaces after internal subset
+                            break;
+
+                        case '>':
+                            //          There is no internal subset
+                            bkch();
+                            st = 3;  // skip spaces after internal subset
+                            break;
+
+                        case ' ':
+                            // skip white spaces
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 3:     // skip spaces after internal subset
+                    switch (chtyp(ch)) {
+                        case '>':
+                            if (psid != null) {
+                                //              Report the DTD external subset
+                                InputSource is = resolveEnt(name, psid.name, psid.value);
+                                if (is != null) {
+                                    if (mIsSAlone == false) {
+                                        //              Set the end of DTD external subset char
+                                        bkch();
+                                        setch(']');
+                                        //              Set the DTD external subset InputSource
+                                        push(new Input(BUFFSIZE_READER));
+                                        setinp(is);
+                                        mInp.pubid = psid.name;
+                                        mInp.sysid = psid.value;
+                                        //              Parse the DTD external subset
+                                        dtdsub();
+                                    } else {
+                                        //              Unresolved DTD external subset
+                                        skippedEnt("[dtd]");
+                                        //              Release reader and stream
+                                        if (is.getCharacterStream() != null) {
+                                            try {
+                                                is.getCharacterStream().close();
+                                            } catch (IOException ioe) {
+                                            }
+                                        }
+                                        if (is.getByteStream() != null) {
+                                            try {
+                                                is.getByteStream().close();
+                                            } catch (IOException ioe) {
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    //          Unresolved DTD external subset
+                                    skippedEnt("[dtd]");
+                                }
+                                del(psid);
+                            }
+                            st = -1;  // end of DTD
+                            break;
+
+                        case ' ':
+                            // skip white spaces
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Parses the document type declaration subset.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void dtdsub() throws Exception {
+        char ch;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // skip white spaces before a declaration
+                    switch (chtyp(ch)) {
+                        case '<':
+                            ch = getch();
+                            switch (ch) {
+                                case '?':
+                                    pi();
+                                    break;
+
+                                case '!':
+                                    ch = getch();
+                                    bkch();
+                                    if (ch == '-') {
+                                        comm();
+                                        break;
+                                    }
+                                    //          A markup or an entity declaration
+                                    bntok();
+                                    switch (bkeyword()) {
+                                        case 'n':
+                                            dtdent();
+                                            break;
+
+                                        case 'a':
+                                            dtdattl();    // parse attributes declaration
+                                            break;
+
+                                        case 'e':
+                                            dtdelm();     // parse element declaration
+                                            break;
+
+                                        case 'o':
+                                            dtdnot();     // parse notation declaration
+                                            break;
+
+                                        default:
+                                            panic(FAULT); // unsupported markup declaration
+                                            break;
+                                    }
+                                    st = 1;  // read the end of declaration
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            break;
+
+                        case '%':
+                            //          A parameter entity reference
+                            pent(' ');
+                            break;
+
+                        case ']':
+                            //          End of DTD subset
+                            st = -1;
+                            break;
+
+                        case ' ':
+                            //          Skip white spaces
+                            break;
+
+                        case 'Z':
+                            //          End of stream
+                            if (getch() != ']') {
+                                panic(FAULT);
+                            }
+                            st = -1;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 1:     // read the end of declaration
+                    switch (ch) {
+                        case '>':   // there is no notation
+                            st = 0; // skip white spaces before a declaration
+                            break;
+
+                        case ' ':
+                        case '\n':
+                        case '\r':
+                        case '\t':
+                            //          Skip white spaces
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Parses an entity declaration. This method fills the general (
+     * <code>mEnt</code>) and parameter
+     * (
+     * <code>mPEnt</code>) entity look up table.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void dtdent() throws Exception {
+        String str = null;
+        char[] val = null;
+        Input inp = null;
+        Pair ids = null;
+        char ch;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // skip white spaces before entity name
+                    switch (chtyp(ch)) {
+                        case ' ':
+                            //          Skip white spaces
+                            break;
+
+                        case '%':
+                            //          Parameter entity or parameter entity declaration.
+                            ch = getch();
+                            bkch();
+                            if (chtyp(ch) == ' ') {
+                                //              Parameter entity declaration.
+                                wsskip();
+                                str = name(false);
+                                switch (chtyp(wsskip())) {
+                                    case 'A':
+                                        //              Read the external identifier
+                                        ids = pubsys(' ');
+                                        if (wsskip() == '>') {
+                                            //          External parsed entity
+                                            if (mPEnt.containsKey(str) == false) {      // [#4.2]
+                                                inp = new Input();
+                                                inp.pubid = ids.name;
+                                                inp.sysid = ids.value;
+                                                mPEnt.put(str, inp);
+                                            }
+                                        } else {
+                                            panic(FAULT);
+                                        }
+                                        del(ids);
+                                        st = -1;  // the end of declaration
+                                        break;
+
+                                    case '\"':
+                                    case '\'':
+                                        //              Read the parameter entity value
+                                        bqstr('d');
+                                        //              Create the parameter entity value
+                                        val = new char[mBuffIdx + 1];
+                                        System.arraycopy(mBuff, 1, val, 1, val.length - 1);
+                                        //              Add surrounding spaces [#4.4.8]
+                                        val[0] = ' ';
+                                        //              Add the entity to the entity look up table
+                                        if (mPEnt.containsKey(str) == false) {  // [#4.2]
+                                            inp = new Input(val);
+                                            inp.pubid = mInp.pubid;
+                                            inp.sysid = mInp.sysid;
+                                            inp.xmlenc = mInp.xmlenc;
+                                            inp.xmlver = mInp.xmlver;
+                                            mPEnt.put(str, inp);
+                                        }
+                                        st = -1;  // the end of declaration
+                                        break;
+
+                                    default:
+                                        panic(FAULT);
+                                        break;
+                                }
+                            } else {
+                                //              Parameter entity reference.
+                                pent(' ');
+                            }
+                            break;
+
+                        default:
+                            bkch();
+                            str = name(false);
+                            st = 1;  // read entity declaration value
+                            break;
+                    }
+                    break;
+
+                case 1:     // read entity declaration value
+                    switch (chtyp(ch)) {
+                        case '\"':  // internal entity
+                        case '\'':
+                            bkch();
+                            bqstr('d');  // read a string into the buffer
+                            if (mEnt.get(str) == null) {
+                                //              Create general entity value
+                                val = new char[mBuffIdx];
+                                System.arraycopy(mBuff, 1, val, 0, val.length);
+                                //              Add the entity to the entity look up table
+                                if (mEnt.containsKey(str) == false) {   // [#4.2]
+                                    inp = new Input(val);
+                                    inp.pubid = mInp.pubid;
+                                    inp.sysid = mInp.sysid;
+                                    inp.xmlenc = mInp.xmlenc;
+                                    inp.xmlver = mInp.xmlver;
+                                    mEnt.put(str, inp);
+                                }
+                            }
+                            st = -1;  // the end of declaration
+                            break;
+
+                        case 'A':  // external entity
+                            bkch();
+                            ids = pubsys(' ');
+                            switch (wsskip()) {
+                                case '>':  // external parsed entity
+                                    if (mEnt.containsKey(str) == false) {  // [#4.2]
+                                        inp = new Input();
+                                        inp.pubid = ids.name;
+                                        inp.sysid = ids.value;
+                                        mEnt.put(str, inp);
+                                    }
+                                    break;
+
+                                case 'N':  // external general unparsed entity
+                                    if ("NDATA".equals(name(false)) == true) {
+                                        wsskip();
+                                        unparsedEntDecl(str, ids.name, ids.value, name(false));
+                                        break;
+                                    }
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            del(ids);
+                            st = -1;  // the end of declaration
+                            break;
+
+                        case ' ':
+                            //          Skip white spaces
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Parses an element declaration.
+     *
+     * This method parses the declaration up to the closing angle bracket.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void dtdelm() throws Exception {
+        //              This is stub implementation which skips an element
+        //              declaration.
+        wsskip();
+        name(mIsNSAware);
+
+        char ch;
+        while (true) {
+            ch = getch();
+            switch (ch) {
+                case '>':
+                    bkch();
+                    return;
+
+                case EOS:
+                    panic(FAULT);
+
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Parses an attribute list declaration.
+     *
+     * This method parses the declaration up to the closing angle bracket.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void dtdattl() throws Exception {
+        char elmqn[] = null;
+        Pair elm = null;
+        char ch;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // read the element name
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case '_':
+                        case 'X':
+                        case ':':
+                            bkch();
+                            //          Get the element from the list or add a new one.
+                            elmqn = qname(mIsNSAware);
+                            elm = find(mAttL, elmqn);
+                            if (elm == null) {
+                                elm = pair(mAttL);
+                                elm.chars = elmqn;
+                                mAttL = elm;
+                            }
+                            st = 1;  // read an attribute declaration
+                            break;
+
+                        case ' ':
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                case 1:     // read an attribute declaration
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case '_':
+                        case 'X':
+                        case ':':
+                            bkch();
+                            dtdatt(elm);
+                            if (wsskip() == '>') {
+                                return;
+                            }
+                            break;
+
+                        case ' ':
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Parses an attribute declaration.
+     *
+     * The attribute uses the following fields of Pair object: chars - characters
+     * of qualified name id - the type identifier of the attribute list - a pair
+     * which holds the default value (chars field)
+     *
+     * @param elm An object which represents all defined attributes on an
+     * element.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void dtdatt(Pair elm) throws Exception {
+        char attqn[] = null;
+        Pair att = null;
+        char ch;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // the attribute name
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case '_':
+                        case 'X':
+                        case ':':
+                            bkch();
+                            //          Get the attribut from the list or add a new one.
+                            attqn = qname(mIsNSAware);
+                            att = find(elm.list, attqn);
+                            if (att == null) {
+                                //              New attribute declaration
+                                att = pair(elm.list);
+                                att.chars = attqn;
+                                elm.list = att;
+                            } else {
+                                //              Do not override the attribute declaration [#3.3]
+                                att = pair(null);
+                                att.chars = attqn;
+                                att.id = 'c';
+                            }
+                            wsskip();
+                            st = 1;
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        case ' ':
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                case 1:     // the attribute type
+                    switch (chtyp(ch)) {
+                        case '(':
+                            att.id = 'u';  // enumeration type
+                            st = 2;        // read the first element of the list
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        case ' ':
+                            break;
+
+                        default:
+                            bkch();
+                            bntok();  // read type id
+                            att.id = bkeyword();
+                            switch (att.id) {
+                                case 'o':   // NOTATION
+                                    if (wsskip() != '(') {
+                                        panic(FAULT);
+                                    }
+                                    ch = getch();
+                                    st = 2;  // read the first element of the list
+                                    break;
+
+                                case 'i':     // ID
+                                case 'r':     // IDREF
+                                case 'R':     // IDREFS
+                                case 'n':     // ENTITY
+                                case 'N':     // ENTITIES
+                                case 't':     // NMTOKEN
+                                case 'T':     // NMTOKENS
+                                case 'c':     // CDATA
+                                    wsskip();
+                                    st = 4;  // read default declaration
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            break;
+                    }
+                    break;
+
+                case 2:     // read the first element of the list
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case 'd':
+                        case '.':
+                        case ':':
+                        case '-':
+                        case '_':
+                        case 'X':
+                            bkch();
+                            switch (att.id) {
+                                case 'u':  // enumeration type
+                                    bntok();
+                                    break;
+
+                                case 'o':  // NOTATION
+                                    mBuffIdx = -1;
+                                    bname(false);
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            wsskip();
+                            st = 3;  // read next element of the list
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        case ' ':
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                case 3:     // read next element of the list
+                    switch (ch) {
+                        case ')':
+                            wsskip();
+                            st = 4;  // read default declaration
+                            break;
+
+                        case '|':
+                            wsskip();
+                            switch (att.id) {
+                                case 'u':  // enumeration type
+                                    bntok();
+                                    break;
+
+                                case 'o':  // NOTATION
+                                    mBuffIdx = -1;
+                                    bname(false);
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            wsskip();
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                case 4:     // read default declaration
+                    switch (ch) {
+                        case '#':
+                            bntok();
+                            switch (bkeyword()) {
+                                case 'F':  // FIXED
+                                    switch (wsskip()) {
+                                        case '\"':
+                                        case '\'':
+                                            st = 5;  // read the default value
+                                            break;
+
+                                        case EOS:
+                                            panic(FAULT);
+
+                                        default:
+                                            st = -1;
+                                            break;
+                                    }
+                                    break;
+
+                                case 'Q':  // REQUIRED
+                                case 'I':  // IMPLIED
+                                    st = -1;
+                                    break;
+
+                                default:
+                                    panic(FAULT);
+                                    break;
+                            }
+                            break;
+
+                        case '\"':
+                        case '\'':
+                            bkch();
+                            st = 5;  // read the default value
+                            break;
+
+                        case ' ':
+                        case '\n':
+                        case '\r':
+                        case '\t':
+                            break;
+
+                        case '%':
+                            pent(' ');
+                            break;
+
+                        default:
+                            bkch();
+                            st = -1;
+                            break;
+                    }
+                    break;
+
+                case 5:     // read the default value
+                    switch (ch) {
+                        case '\"':
+                        case '\'':
+                            bkch();
+                            bqstr('d');  // the value in the mBuff now
+                            att.list = pair(null);
+                            //          Create a string like "attqname='value' "
+                            att.list.chars = new char[att.chars.length + mBuffIdx + 3];
+                            System.arraycopy(
+                                    att.chars, 1, att.list.chars, 0, att.chars.length - 1);
+                            att.list.chars[att.chars.length - 1] = '=';
+                            att.list.chars[att.chars.length] = ch;
+                            System.arraycopy(
+                                    mBuff, 1, att.list.chars, att.chars.length + 1, mBuffIdx);
+                            att.list.chars[att.chars.length + mBuffIdx + 1] = ch;
+                            att.list.chars[att.chars.length + mBuffIdx + 2] = ' ';
+                            st = -1;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Parses a notation declaration.
+     *
+     * This method parses the declaration up to the closing angle bracket.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void dtdnot() throws Exception {
+        wsskip();
+        String name = name(false);
+        wsskip();
+        Pair ids = pubsys('N');
+        notDecl(name, ids.name, ids.value);
+        del(ids);
+    }
+
+    /**
+     * Parses an attribute.
+     *
+     * This recursive method is responsible for prefix addition
+     * (
+     * <code>mPref</code>) on the way down. The element's start tag end triggers
+     * the return process. The method then on it's way back resolves prefixes
+     * and accumulates attributes.
+     *
+     * <p><code>att.num</code> carries attribute flags where: 0x1 - attribute is
+     * declared in DTD (attribute decalration had been read); 0x2 - attribute's
+     * default value is used.</p>
+     *
+     * @param att An object which reprecents current attribute.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void attr(Pair att) throws Exception {
+        switch (wsskip()) {
+            case '/':
+            case '>':
+                if ((att.num & 0x2) == 0) {  // all attributes have been read
+                    att.num |= 0x2;  // set default attribute flag
+                    Input inp = mInp;
+                    //          Go through all attributes defined on current element.
+                    for (Pair def = mElm.list; def != null; def = def.next) {
+                        if (def.list == null) // no default value
+                        {
+                            continue;
+                        }
+                        //              Go through all attributes defined on current
+                        //              element and add defaults.
+                        Pair act = find(att.next, def.chars);
+                        if (act == null) {
+                            push(new Input(def.list.chars));
+                        }
+                    }
+                    if (mInp != inp) {  // defaults have been added
+                        attr(att);
+                        return;
+                    }
+                }
+                //              Ensure the attribute string array capacity
+                mAttrs.setLength(mAttrIdx);
+                mItems = mAttrs.mItems;
+                return;
+
+            case EOS:
+                panic(FAULT);
+
+            default:
+                //              Read the attribute name and value
+                att.chars = qname(mIsNSAware);
+                att.name = att.local();
+                String type = atype(att);  // sets attribute's type on att.id
+                wsskip();
+                if (getch() != '=') {
+                    panic(FAULT);
+                }
+                bqstr((char) att.id);   // read the value with normalization.
+                String val = new String(mBuff, 1, mBuffIdx);
+                Pair next = pair(att);
+                next.num = (att.num & ~0x1);  // inherit attribute flags
+                //              Put a namespace declaration on top of the prefix stack
+                if ((mIsNSAware == false) || (isdecl(att, val) == false)) {
+                    //          An ordinary attribute
+                    mAttrIdx++;
+                    attr(next);     // recursive call to parse the next attribute
+                    mAttrIdx--;
+                    //          Add the attribute to the attributes string array
+                    char idx = (char) (mAttrIdx << 3);
+                    mItems[idx + 1] = att.qname();  // attr qname
+                    mItems[idx + 2] = (mIsNSAware) ? att.name : ""; // attr local name
+                    mItems[idx + 3] = val;          // attr value
+                    mItems[idx + 4] = type;         // attr type
+                    switch (att.num & 0x3) {
+                        case 0x0:
+                            mItems[idx + 5] = null;
+                            break;
+
+                        case 0x1:  // declared attribute
+                            mItems[idx + 5] = "d";
+                            break;
+
+                        default:  // 0x2, 0x3 - default attribute always declared
+                            mItems[idx + 5] = "D";
+                            break;
+                    }
+                    //          Resolve the prefix if any and report the attribute
+                    //          NOTE: The attribute does not accept the default namespace.
+                    mItems[idx + 0] = (att.chars[0] != 0) ? rslv(att.chars) : "";
+                } else {
+                    //          A namespace declaration. mPref.name contains prefix and
+                    //          mPref.value contains namespace URI set by isdecl method.
+                    //          Report a start of the new mapping
+                    newPrefix();
+                    //          Recursive call to parse the next attribute
+                    attr(next);
+                    //          NOTE: The namespace declaration is not reported.
+                }
+                del(next);
+                break;
+        }
+    }
+
+    /**
+     * Retrieves attribute type.
+     *
+     * This method sets the type of normalization in the attribute
+     * <code>id</code> field and returns the name of attribute type.
+     *
+     * @param att An object which represents current attribute.
+     * @return The name of the attribute type.
+     * @exception Exception is parser specific exception form panic method.
+     */
+    private String atype(Pair att)
+            throws Exception {
+        Pair attr;
+
+        // CDATA-type normalization by default [#3.3.3]
+        att.id = 'c';
+        if (mElm.list == null || (attr = find(mElm.list, att.chars)) == null) {
+            return "CDATA";
+        }
+
+        att.num |= 0x1;  // attribute is declared
+
+        // Non-CDATA normalization except when the attribute type is CDATA.
+        att.id = 'i';
+        switch (attr.id) {
+            case 'i':
+                return "ID";
+
+            case 'r':
+                return "IDREF";
+
+            case 'R':
+                return "IDREFS";
+
+            case 'n':
+                return "ENTITY";
+
+            case 'N':
+                return "ENTITIES";
+
+            case 't':
+                return "NMTOKEN";
+
+            case 'T':
+                return "NMTOKENS";
+
+            case 'u':
+                return "NMTOKEN";
+
+            case 'o':
+                return "NOTATION";
+
+            case 'c':
+                att.id = 'c';
+                return "CDATA";
+
+            default:
+                panic(FAULT);
+        }
+        return null;
+    }
+
+    /**
+     * Parses a comment.
+     *
+     * The &apos;&lt;!&apos; part is read in dispatcher so the method starts
+     * with first &apos;-&apos; after &apos;&lt;!&apos;.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     */
+    @SuppressWarnings("fallthrough")
+    private void comm() throws Exception {
+        if (mPh == PH_DOC_START) {
+            mPh = PH_MISC_DTD;  // misc before DTD
+        }               // '<!' has been already read by dispetcher.
+        char ch;
+        mBuffIdx = -1;
+        for (short st = 0; st >= 0;) {
+            ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+            if (ch == EOS) {
+                panic(FAULT);
+            }
+            switch (st) {
+                case 0:     // first '-' of the comment open
+                    if (ch == '-') {
+                        st = 1;
+                    } else {
+                        panic(FAULT);
+                    }
+                    break;
+
+                case 1:     // secind '-' of the comment open
+                    if (ch == '-') {
+                        st = 2;
+                    } else {
+                        panic(FAULT);
+                    }
+                    break;
+
+                case 2:     // skip the comment body
+                    switch (ch) {
+                        case '-':
+                            st = 3;
+                            break;
+
+                        default:
+                            bappend(ch);
+                            break;
+                    }
+                    break;
+
+                case 3:     // second '-' of the comment close
+                    switch (ch) {
+                        case '-':
+                            st = 4;
+                            break;
+
+                        default:
+                            bappend('-');
+                            bappend(ch);
+                            st = 2;
+                            break;
+                    }
+                    break;
+
+                case 4:     // '>' of the comment close
+                    if (ch == '>') {
+                        comm(mBuff, mBuffIdx + 1);
+                        st = -1;
+                        break;
+                    }
+                // else - panic [#2.5 compatibility note]
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Parses a processing instruction.
+     *
+     * The &apos;&lt;?&apos; is read in dispatcher so the method starts with
+     * first character of PI target name after &apos;&lt;?&apos;.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void pi() throws Exception {
+        // '<?' has been already read by dispetcher.
+        char ch;
+        String str = null;
+        mBuffIdx = -1;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            if (ch == EOS) {
+                panic(FAULT);
+            }
+            switch (st) {
+                case 0:     // read the PI target name
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case '_':
+                        case ':':
+                        case 'X':
+                            bkch();
+                            str = name(false);
+                            //          PI target name may not be empty string [#2.6]
+                            //          PI target name 'XML' is reserved [#2.6]
+                            if ((str.length() == 0)
+                                    || (mXml.name.equals(str.toLowerCase()) == true)) {
+                                panic(FAULT);
+                            }
+                            //          This is processing instruction
+                            if (mPh == PH_DOC_START) // the begining of the document
+                            {
+                                mPh = PH_MISC_DTD;    // misc before DTD
+                            }
+                            wsskip();  // skip spaces after the PI target name
+                            st = 1;    // accumulate the PI body
+                            mBuffIdx = -1;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 1:     // accumulate the PI body
+                    switch (ch) {
+                        case '?':
+                            st = 2;  // end of the PI body
+                            break;
+
+                        default:
+                            bappend(ch);
+                            break;
+                    }
+                    break;
+
+                case 2:     // end of the PI body
+                    switch (ch) {
+                        case '>':
+                            //          PI has been read.
+                            pi(str, new String(mBuff, 0, mBuffIdx + 1));
+                            st = -1;
+                            break;
+
+                        case '?':
+                            bappend('?');
+                            break;
+
+                        default:
+                            bappend('?');
+                            bappend(ch);
+                            st = 1;  // accumulate the PI body
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Parses a character data.
+     *
+     * The &apos;&lt;!&apos; part is read in dispatcher so the method starts
+     * with first &apos;[&apos; after &apos;&lt;!&apos;.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void cdat()
+            throws Exception {
+        // '<!' has been already read by dispetcher.
+        char ch;
+        mBuffIdx = -1;
+        for (short st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // the first '[' of the CDATA open
+                    if (ch == '[') {
+                        st = 1;
+                    } else {
+                        panic(FAULT);
+                    }
+                    break;
+
+                case 1:     // read "CDATA"
+                    if (chtyp(ch) == 'A') {
+                        bappend(ch);
+                    } else {
+                        if ("CDATA".equals(
+                                new String(mBuff, 0, mBuffIdx + 1)) != true) {
+                            panic(FAULT);
+                        }
+                        bkch();
+                        st = 2;
+                    }
+                    break;
+
+                case 2:     // the second '[' of the CDATA open
+                    if (ch != '[') {
+                        panic(FAULT);
+                    }
+                    mBuffIdx = -1;
+                    st = 3;
+                    break;
+
+                case 3:     // read data before the first ']'
+                    if (ch != ']') {
+                        bappend(ch);
+                    } else {
+                        st = 4;
+                    }
+                    break;
+
+                case 4:     // read the second ']' or continue to read the data
+                    if (ch != ']') {
+                        bappend(']');
+                        bappend(ch);
+                        st = 3;
+                    } else {
+                        st = 5;
+                    }
+                    break;
+
+                case 5:     // read '>' or continue to read the data
+                    switch (ch) {
+                        case ']':
+                            bappend(']');
+                            break;
+
+                        case '>':
+                            bflash();
+                            st = -1;
+                            break;
+
+                        default:
+                            bappend(']');
+                            bappend(']');
+                            bappend(ch);
+                            st = 3;
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Reads a xml name.
+     *
+     * The xml name must conform "Namespaces in XML" specification. Therefore
+     * the ':' character is not allowed in the name. This method should be used
+     * for PI and entity names which may not have a namespace according to the
+     * specification mentioned above.
+     *
+     * @param ns The true value turns namespace conformance on.
+     * @return The name has been read.
+     * @exception Exception When incorrect character appear in the name.
+     * @exception IOException
+     */
+    protected String name(boolean ns)
+            throws Exception {
+        mBuffIdx = -1;
+        bname(ns);
+        return new String(mBuff, 1, mBuffIdx);
+    }
+
+    /**
+     * Reads a qualified xml name.
+     *
+     * The characters of a qualified name is an array of characters. The first
+     * (chars[0]) character is the index of the colon character which separates
+     * the prefix from the local name. If the index is zero, the name does not
+     * contain separator or the parser works in the namespace unaware mode. The
+     * length of qualified name is the length of the array minus one.
+     *
+     * @param ns The true value turns namespace conformance on.
+     * @return The characters of a qualified name.
+     * @exception Exception When incorrect character appear in the name.
+     * @exception IOException
+     */
+    protected char[] qname(boolean ns)
+            throws Exception {
+        mBuffIdx = -1;
+        bname(ns);
+        char chars[] = new char[mBuffIdx + 1];
+        System.arraycopy(mBuff, 0, chars, 0, mBuffIdx + 1);
+        return chars;
+    }
+
+    /**
+     * Reads the public or/and system identifiers.
+     *
+     * @param inp The input object.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void pubsys(Input inp)
+            throws Exception {
+        Pair pair = pubsys(' ');
+        inp.pubid = pair.name;
+        inp.sysid = pair.value;
+        del(pair);
+    }
+
+    /**
+     * Reads the public or/and system identifiers.
+     *
+     * @param flag The 'N' allows public id be without system id.
+     * @return The public or/and system identifiers pair.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private Pair pubsys(char flag) throws Exception {
+        Pair ids = pair(null);
+        String str = name(false);
+        if ("PUBLIC".equals(str) == true) {
+            bqstr('i');  // non-CDATA normalization [#4.2.2]
+            ids.name = new String(mBuff, 1, mBuffIdx);
+            switch (wsskip()) {
+                case '\"':
+                case '\'':
+                    bqstr(' ');
+                    ids.value = new String(mBuff, 1, mBuffIdx);
+                    break;
+
+                case EOS:
+                    panic(FAULT);
+
+                default:
+                    if (flag != 'N') // [#4.7]
+                    {
+                        panic(FAULT);
+                    }
+                    ids.value = null;
+                    break;
+            }
+            return ids;
+        } else if ("SYSTEM".equals(str) == true) {
+            ids.name = null;
+            bqstr(' ');
+            ids.value = new String(mBuff, 1, mBuffIdx);
+            return ids;
+        }
+        panic(FAULT);
+        return null;
+    }
+
+    /**
+     * Reads an attribute value.
+     *
+     * The grammar which this method can read is:<br />
+     * <code>eqstr := S &quot;=&quot; qstr</code><br />
+     * <code>qstr  := S (&quot;'&quot; string &quot;'&quot;) |
+     *  ('&quot;' string '&quot;')</code><br /> This method resolves entities
+     * inside a string unless the parser parses DTD.
+     *
+     * @param flag The '=' character forces the method to accept the '='
+     * character before quoted string and read the following string as not an
+     * attribute ('-'), 'c' - CDATA, 'i' - non CDATA, ' ' - no normalization;
+     * '-' - not an attribute value; 'd' - in DTD context.
+     * @return The content of the quoted strign as a string.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    protected String eqstr(char flag) throws Exception {
+        if (flag == '=') {
+            wsskip();
+            if (getch() != '=') {
+                panic(FAULT);
+            }
+        }
+        bqstr((flag == '=') ? '-' : flag);
+        return new String(mBuff, 1, mBuffIdx);
+    }
+
+    /**
+     * Resoves an entity.
+     *
+     * This method resolves built-in and character entity references. It is also
+     * reports external entities to the application.
+     *
+     * @param flag The 'x' character forces the method to report a skipped
+     * entity; 'i' character - indicates non-CDATA normalization.
+     * @return Name of unresolved entity or <code>null</code> if entity had been
+     * resolved successfully.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private String ent(char flag) throws Exception {
+        char ch;
+        int idx = mBuffIdx + 1;
+        Input inp = null;
+        String str = null;
+        mESt = 0x100;  // reset the built-in entity recognizer
+        bappend('&');
+        for (short st = 0; st >= 0;) {
+            ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+            switch (st) {
+                case 0:     // the first character of the entity name
+                case 1:     // read built-in entity name
+                    switch (chtyp(ch)) {
+                        case 'd':
+                        case '.':
+                        case '-':
+                            if (st != 1) {
+                                panic(FAULT);
+                            }
+                        case 'a':
+                        case 'A':
+                        case '_':
+                        case 'X':
+                            bappend(ch);
+                            eappend(ch);
+                            st = 1;
+                            break;
+
+                        case ':':
+                            if (mIsNSAware != false) {
+                                panic(FAULT);
+                            }
+                            bappend(ch);
+                            eappend(ch);
+                            st = 1;
+                            break;
+
+                        case ';':
+                            if (mESt < 0x100) {
+                                //              The entity is a built-in entity
+                                mBuffIdx = idx - 1;
+                                bappend(mESt);
+                                st = -1;
+                                break;
+                            } else if (mPh == PH_DTD) {
+                                //              In DTD entity declaration has to resolve character
+                                //              entities and include "as is" others. [#4.4.7]
+                                bappend(';');
+                                st = -1;
+                                break;
+                            }
+                            //          Convert an entity name to a string
+                            str = new String(mBuff, idx + 1, mBuffIdx - idx);
+                            inp = mEnt.get(str);
+                            //          Restore the buffer offset
+                            mBuffIdx = idx - 1;
+                            if (inp != null) {
+                                if (inp.chars == null) {
+                                    //          External entity
+                                    InputSource is = resolveEnt(str, inp.pubid, inp.sysid);
+                                    if (is != null) {
+                                        push(new Input(BUFFSIZE_READER));
+                                        setinp(is);
+                                        mInp.pubid = inp.pubid;
+                                        mInp.sysid = inp.sysid;
+                                        str = null;  // the entity is resolved
+                                    } else {
+                                        //              Unresolved external entity
+                                        if (flag != 'x') {
+                                            panic(FAULT);  // unknown entity within marckup
+                                        }                                                               //              str is name of unresolved entity
+                                    }
+                                } else {
+                                    //          Internal entity
+                                    push(inp);
+                                    str = null;  // the entity is resolved
+                                }
+                            } else {
+                                //              Unknown or general unparsed entity
+                                if (flag != 'x') {
+                                    panic(FAULT);  // unknown entity within marckup
+                                }                                               //              str is name of unresolved entity
+                            }
+                            st = -1;
+                            break;
+
+                        case '#':
+                            if (st != 0) {
+                                panic(FAULT);
+                            }
+                            st = 2;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 2:     // read character entity
+                    switch (chtyp(ch)) {
+                        case 'd':
+                            bappend(ch);
+                            break;
+
+                        case ';':
+                            //          Convert the character entity to a character
+                            try {
+                                int i = Integer.parseInt(
+                                        new String(mBuff, idx + 1, mBuffIdx - idx), 10);
+                                if (i >= 0xffff) {
+                                    panic(FAULT);
+                                }
+                                ch = (char) i;
+                            } catch (NumberFormatException nfe) {
+                                panic(FAULT);
+                            }
+                            //          Restore the buffer offset
+                            mBuffIdx = idx - 1;
+                            if (ch == ' ' || mInp.next != null) {
+                                bappend(ch, flag);
+                            } else {
+                                bappend(ch);
+                            }
+                            st = -1;
+                            break;
+
+                        case 'a':
+                            //          If the entity buffer is empty and ch == 'x'
+                            if ((mBuffIdx == idx) && (ch == 'x')) {
+                                st = 3;
+                                break;
+                            }
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 3:     // read hex character entity
+                    switch (chtyp(ch)) {
+                        case 'A':
+                        case 'a':
+                        case 'd':
+                            bappend(ch);
+                            break;
+
+                        case ';':
+                            //          Convert the character entity to a character
+                            try {
+                                int i = Integer.parseInt(
+                                        new String(mBuff, idx + 1, mBuffIdx - idx), 16);
+                                if (i >= 0xffff) {
+                                    panic(FAULT);
+                                }
+                                ch = (char) i;
+                            } catch (NumberFormatException nfe) {
+                                panic(FAULT);
+                            }
+                            //          Restore the buffer offset
+                            mBuffIdx = idx - 1;
+                            if (ch == ' ' || mInp.next != null) {
+                                bappend(ch, flag);
+                            } else {
+                                bappend(ch);
+                            }
+                            st = -1;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+
+        return str;
+    }
+
+    /**
+     * Resoves a parameter entity.
+     *
+     * This method resolves a parameter entity references. It is also reports
+     * external entities to the application.
+     *
+     * @param flag The '-' instruct the method to do not set up surrounding
+     * spaces [#4.4.8].
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void pent(char flag) throws Exception {
+        char ch;
+        int idx = mBuffIdx + 1;
+        Input inp = null;
+        String str = null;
+        bappend('%');
+        if (mPh != PH_DTD) // the DTD internal subset
+        {
+            return;         // Not Recognized [#4.4.1]
+        }               //              Read entity name
+        bname(false);
+        str = new String(mBuff, idx + 2, mBuffIdx - idx - 1);
+        if (getch() != ';') {
+            panic(FAULT);
+        }
+        inp = mPEnt.get(str);
+        //              Restore the buffer offset
+        mBuffIdx = idx - 1;
+        if (inp != null) {
+            if (inp.chars == null) {
+                //              External parameter entity
+                InputSource is = resolveEnt(str, inp.pubid, inp.sysid);
+                if (is != null) {
+                    if (flag != '-') {
+                        bappend(' ');  // tail space
+                    }
+                    push(new Input(BUFFSIZE_READER));
+                    // BUG: there is no leading space! [#4.4.8]
+                    setinp(is);
+                    mInp.pubid = inp.pubid;
+                    mInp.sysid = inp.sysid;
+                } else {
+                    //          Unresolved external parameter entity
+                    skippedEnt("%" + str);
+                }
+            } else {
+                //              Internal parameter entity
+                if (flag == '-') {
+                    //          No surrounding spaces
+                    inp.chIdx = 1;
+                } else {
+                    //          Insert surrounding spaces
+                    bappend(' ');  // tail space
+                    inp.chIdx = 0;
+                }
+                push(inp);
+            }
+        } else {
+            //          Unknown parameter entity
+            skippedEnt("%" + str);
+        }
+    }
+
+    /**
+     * Recognizes and handles a namespace declaration.
+     *
+     * This method identifies a type of namespace declaration if any and puts
+     * new mapping on top of prefix stack.
+     *
+     * @param name The attribute qualified name (<code>name.value</code> is a
+     * <code>String</code> object which represents the attribute prefix).
+     * @param value The attribute value.
+     * @return <code>true</code> if a namespace declaration is recognized.
+     */
+    private boolean isdecl(Pair name, String value) {
+        if (name.chars[0] == 0) {
+            if ("xmlns".equals(name.name) == true) {
+                //              New default namespace declaration
+                mPref = pair(mPref);
+                mPref.list = mElm;  // prefix owner element
+                mPref.value = value;
+                mPref.name = "";
+                mPref.chars = NONS;
+                mElm.num++;  // namespace counter
+                return true;
+            }
+        } else {
+            if (name.eqpref(XMLNS) == true) {
+                //              New prefix declaration
+                int len = name.name.length();
+                mPref = pair(mPref);
+                mPref.list = mElm;  // prefix owner element
+                mPref.value = value;
+                mPref.name = name.name;
+                mPref.chars = new char[len + 1];
+                mPref.chars[0] = (char) (len + 1);
+                name.name.getChars(0, len, mPref.chars, 1);
+                mElm.num++;  // namespace counter
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Resolves a prefix.
+     *
+     * @return The namespace assigned to the prefix.
+     * @exception Exception When mapping for specified prefix is not found.
+     */
+    private String rslv(char[] qname)
+            throws Exception {
+        for (Pair pref = mPref; pref != null; pref = pref.next) {
+            if (pref.eqpref(qname) == true) {
+                return pref.value;
+            }
+        }
+        if (qname[0] == 1) {  // QNames like ':local'
+            for (Pair pref = mPref; pref != null; pref = pref.next) {
+                if (pref.chars[0] == 0) {
+                    return pref.value;
+                }
+            }
+        }
+        panic(FAULT);
+        return null;
+    }
+
+    /**
+     * Skips xml white space characters.
+     *
+     * This method skips white space characters (' ', '\t', '\n', '\r') and
+     * looks ahead not white space character.
+     *
+     * @return The first not white space look ahead character.
+     * @exception IOException
+     */
+    protected char wsskip()
+            throws IOException {
+        char ch;
+        while (true) {
+            //          Read next character
+            ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+            if (ch < 0x80) {
+                if (nmttyp[ch] != 3) // [ \t\n\r]
+                {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+        mChIdx--;  // bkch();
+        return ch;
+    }
+
+    /**
+     * Reports document type.
+     *
+     * @param name The name of the entity.
+     * @param pubid The public identifier of the entity or <code>null</code>.
+     * @param sysid The system identifier of the entity or <code>null</code>.
+     */
+    protected abstract void docType(String name, String pubid, String sysid)
+            throws SAXException;
+
+    /**
+     * Reports a comment.
+     *
+     * @param text The comment text starting from first charcater.
+     * @param length The number of characters in comment.
+     */
+    protected abstract void comm(char[] text, int length);
+
+    /**
+     * Reports a processing instruction.
+     *
+     * @param target The processing instruction target name.
+     * @param body The processing instruction body text.
+     */
+    protected abstract void pi(String target, String body)
+            throws Exception;
+
+    /**
+     * Reports new namespace prefix. The Namespace prefix (
+     * <code>mPref.name</code>) being declared and the Namespace URI (
+     * <code>mPref.value</code>) the prefix is mapped to. An empty string is
+     * used for the default element namespace, which has no prefix.
+     */
+    protected abstract void newPrefix()
+            throws Exception;
+
+    /**
+     * Reports skipped entity name.
+     *
+     * @param name The entity name.
+     */
+    protected abstract void skippedEnt(String name)
+            throws Exception;
+
+    /**
+     * Returns an
+     * <code>InputSource</code> for specified entity or
+     * <code>null</code>.
+     *
+     * @param name The name of the entity.
+     * @param pubid The public identifier of the entity.
+     * @param sysid The system identifier of the entity.
+     */
+    protected abstract InputSource resolveEnt(
+            String name, String pubid, String sysid)
+            throws Exception;
+
+    /**
+     * Reports notation declaration.
+     *
+     * @param name The notation's name.
+     * @param pubid The notation's public identifier, or null if none was given.
+     * @param sysid The notation's system identifier, or null if none was given.
+     */
+    protected abstract void notDecl(String name, String pubid, String sysid)
+            throws Exception;
+
+    /**
+     * Reports unparsed entity name.
+     *
+     * @param name The unparsed entity's name.
+     * @param pubid The entity's public identifier, or null if none was given.
+     * @param sysid The entity's system identifier.
+     * @param notation The name of the associated notation.
+     */
+    protected abstract void unparsedEntDecl(
+            String name, String pubid, String sysid, String notation)
+            throws Exception;
+
+    /**
+     * Notifies the handler about fatal parsing error.
+     *
+     * @param msg The problem description message.
+     */
+    protected abstract void panic(String msg)
+            throws Exception;
+
+    /**
+     * Reads a qualified xml name.
+     *
+     * This is low level routine which leaves a qName in the buffer. The
+     * characters of a qualified name is an array of characters. The first
+     * (chars[0]) character is the index of the colon character which separates
+     * the prefix from the local name. If the index is zero, the name does not
+     * contain separator or the parser works in the namespace unaware mode. The
+     * length of qualified name is the length of the array minus one.
+     *
+     * @param ns The true value turns namespace conformance on.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private void bname(boolean ns)
+            throws Exception {
+        char ch;
+        char type;
+        mBuffIdx++;  // allocate a char for colon offset
+        int bqname = mBuffIdx;
+        int bcolon = bqname;
+        int bchidx = bqname + 1;
+        int bstart = bchidx;
+        int cstart = mChIdx;
+        short st = (short) ((ns == true) ? 0 : 2);
+        while (true) {
+            //          Read next character
+            if (mChIdx >= mChLen) {
+                bcopy(cstart, bstart);
+                getch();
+                mChIdx--;  // bkch();
+                cstart = mChIdx;
+                bstart = bchidx;
+            }
+            ch = mChars[mChIdx++];
+            type = (char) 0;  // [X]
+            if (ch < 0x80) {
+                type = (char) nmttyp[ch];
+            } else if (ch == EOS) {
+                panic(FAULT);
+            }
+            //          Parse QName
+            switch (st) {
+                case 0:     // read the first char of the prefix
+                case 2:     // read the first char of the suffix
+                    switch (type) {
+                        case 0:  // [aA_X]
+                            bchidx++;  // append char to the buffer
+                            st++;      // (st == 0)? 1: 3;
+                            break;
+
+                        case 1:  // [:]
+                            mChIdx--;  // bkch();
+                            st++;      // (st == 0)? 1: 3;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 1:     // read the prefix
+                case 3:     // read the suffix
+                    switch (type) {
+                        case 0:  // [aA_X]
+                        case 2:  // [.-d]
+                            bchidx++;  // append char to the buffer
+                            break;
+
+                        case 1:  // [:]
+                            bchidx++;  // append char to the buffer
+                            if (ns == true) {
+                                if (bcolon != bqname) {
+                                    panic(FAULT);  // it must be only one colon
+                                }
+                                bcolon = bchidx - 1;
+                                if (st == 1) {
+                                    st = 2;
+                                }
+                            }
+                            break;
+
+                        default:
+                            mChIdx--;  // bkch();
+                            bcopy(cstart, bstart);
+                            mBuff[bqname] = (char) (bcolon - bqname);
+                            return;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+    }
+
+    /**
+     * Reads a nmtoken.
+     *
+     * This is low level routine which leaves a nmtoken in the buffer.
+     *
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void bntok() throws Exception {
+        char ch;
+        mBuffIdx = -1;
+        bappend((char) 0);  // default offset to the colon char
+        while (true) {
+            ch = getch();
+            switch (chtyp(ch)) {
+                case 'a':
+                case 'A':
+                case 'd':
+                case '.':
+                case ':':
+                case '-':
+                case '_':
+                case 'X':
+                    bappend(ch);
+                    break;
+
+                case 'Z':
+                    panic(FAULT);
+
+                default:
+                    bkch();
+                    return;
+            }
+        }
+    }
+
+    /**
+     * Recognizes a keyword.
+     *
+     * This is low level routine which recognizes one of keywords in the buffer.
+     * Keyword Id ID - i IDREF - r IDREFS - R ENTITY - n ENTITIES - N NMTOKEN -
+     * t NMTOKENS - T ELEMENT - e ATTLIST - a NOTATION - o CDATA - c REQUIRED -
+     * Q IMPLIED - I FIXED - F
+     *
+     * @return an id of a keyword or '?'.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private char bkeyword()
+            throws Exception {
+        String str = new String(mBuff, 1, mBuffIdx);
+        switch (str.length()) {
+            case 2:  // ID
+                return ("ID".equals(str) == true) ? 'i' : '?';
+
+            case 5:  // IDREF, CDATA, FIXED
+                switch (mBuff[1]) {
+                    case 'I':
+                        return ("IDREF".equals(str) == true) ? 'r' : '?';
+                    case 'C':
+                        return ("CDATA".equals(str) == true) ? 'c' : '?';
+                    case 'F':
+                        return ("FIXED".equals(str) == true) ? 'F' : '?';
+                    default:
+                        break;
+                }
+                break;
+
+            case 6:  // IDREFS, ENTITY
+                switch (mBuff[1]) {
+                    case 'I':
+                        return ("IDREFS".equals(str) == true) ? 'R' : '?';
+                    case 'E':
+                        return ("ENTITY".equals(str) == true) ? 'n' : '?';
+                    default:
+                        break;
+                }
+                break;
+
+            case 7:  // NMTOKEN, IMPLIED, ATTLIST, ELEMENT
+                switch (mBuff[1]) {
+                    case 'I':
+                        return ("IMPLIED".equals(str) == true) ? 'I' : '?';
+                    case 'N':
+                        return ("NMTOKEN".equals(str) == true) ? 't' : '?';
+                    case 'A':
+                        return ("ATTLIST".equals(str) == true) ? 'a' : '?';
+                    case 'E':
+                        return ("ELEMENT".equals(str) == true) ? 'e' : '?';
+                    default:
+                        break;
+                }
+                break;
+
+            case 8:  // ENTITIES, NMTOKENS, NOTATION, REQUIRED
+                switch (mBuff[2]) {
+                    case 'N':
+                        return ("ENTITIES".equals(str) == true) ? 'N' : '?';
+                    case 'M':
+                        return ("NMTOKENS".equals(str) == true) ? 'T' : '?';
+                    case 'O':
+                        return ("NOTATION".equals(str) == true) ? 'o' : '?';
+                    case 'E':
+                        return ("REQUIRED".equals(str) == true) ? 'Q' : '?';
+                    default:
+                        break;
+                }
+                break;
+
+            default:
+                break;
+        }
+        return '?';
+    }
+
+    /**
+     * Reads a single or double quotted string in to the buffer.
+     *
+     * This method resolves entities inside a string unless the parser parses
+     * DTD.
+     *
+     * @param flag 'c' - CDATA, 'i' - non CDATA, ' ' - no normalization; '-' -
+     * not an attribute value; 'd' - in DTD context.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    @SuppressWarnings("fallthrough")
+    private void bqstr(char flag) throws Exception {
+        Input inp = mInp;  // remember the original input
+        mBuffIdx = -1;
+        bappend((char) 0);  // default offset to the colon char
+        char ch;
+        for (short st = 0; st >= 0;) {
+            ch = (mChIdx < mChLen) ? mChars[mChIdx++] : getch();
+            switch (st) {
+                case 0:     // read a single or double quote
+                    switch (ch) {
+                        case ' ':
+                        case '\n':
+                        case '\r':
+                        case '\t':
+                            break;
+
+                        case '\'':
+                            st = 2;  // read a single quoted string
+                            break;
+
+                        case '\"':
+                            st = 3;  // read a double quoted string
+                            break;
+
+                        default:
+                            panic(FAULT);
+                            break;
+                    }
+                    break;
+
+                case 2:     // read a single quoted string
+                case 3:     // read a double quoted string
+                    switch (ch) {
+                        case '\'':
+                            if ((st == 2) && (mInp == inp)) {
+                                st = -1;
+                            } else {
+                                bappend(ch);
+                            }
+                            break;
+
+                        case '\"':
+                            if ((st == 3) && (mInp == inp)) {
+                                st = -1;
+                            } else {
+                                bappend(ch);
+                            }
+                            break;
+
+                        case '&':
+                            if (flag != 'd') {
+                                ent(flag);
+                            } else {
+                                bappend(ch);
+                            }
+                            break;
+
+                        case '%':
+                            if (flag == 'd') {
+                                pent('-');
+                            } else {
+                                bappend(ch);
+                            }
+                            break;
+
+                        case '<':
+                            if ((flag == '-') || (flag == 'd')) {
+                                bappend(ch);
+                            } else {
+                                panic(FAULT);
+                            }
+                            break;
+
+                        case EOS:               // EOS before single/double quote
+                            panic(FAULT);
+
+                        case '\r':     // EOL processing [#2.11 & #3.3.3]
+                            if (flag != ' ' && mInp.next == null) {
+                                if (getch() != '\n') {
+                                    bkch();
+                                }
+                                ch = '\n';
+                            }
+                        default:
+                            bappend(ch, flag);
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+        //              There is maximum one space at the end of the string in
+        //              i-mode (non CDATA normalization) and it has to be removed.
+        if ((flag == 'i') && (mBuff[mBuffIdx] == ' ')) {
+            mBuffIdx -= 1;
+        }
+    }
+
+    /**
+     * Reports characters and empties the parser's buffer. This method is called
+     * only if parser is going to return control to the main loop. This means
+     * that this method may use parser buffer to report white space without
+     * copeing characters to temporary buffer.
+     */
+    protected abstract void bflash()
+            throws Exception;
+
+    /**
+     * Reports white space characters and empties the parser's buffer. This
+     * method is called only if parser is going to return control to the main
+     * loop. This means that this method may use parser buffer to report white
+     * space without copeing characters to temporary buffer.
+     */
+    protected abstract void bflash_ws()
+            throws Exception;
+
+    /**
+     * Appends a character to parser's buffer with normalization.
+     *
+     * @param ch The character to append to the buffer.
+     * @param mode The normalization mode.
+     */
+    private void bappend(char ch, char mode) {
+        //              This implements attribute value normalization as
+        //              described in the XML specification [#3.3.3].
+        switch (mode) {
+            case 'i':  // non CDATA normalization
+                switch (ch) {
+                    case ' ':
+                    case '\n':
+                    case '\r':
+                    case '\t':
+                        if ((mBuffIdx > 0) && (mBuff[mBuffIdx] != ' ')) {
+                            bappend(' ');
+                        }
+                        return;
+
+                    default:
+                        break;
+                }
+                break;
+
+            case 'c':  // CDATA normalization
+                switch (ch) {
+                    case '\n':
+                    case '\r':
+                    case '\t':
+                        ch = ' ';
+                        break;
+
+                    default:
+                        break;
+                }
+                break;
+
+            default:  // no normalization
+                break;
+        }
+        mBuffIdx++;
+        if (mBuffIdx < mBuff.length) {
+            mBuff[mBuffIdx] = ch;
+        } else {
+            mBuffIdx--;
+            bappend(ch);
+        }
+    }
+
+    /**
+     * Appends a character to parser's buffer.
+     *
+     * @param ch The character to append to the buffer.
+     */
+    private void bappend(char ch) {
+        try {
+            mBuff[++mBuffIdx] = ch;
+        } catch (Exception exp) {
+            //          Double the buffer size
+            char buff[] = new char[mBuff.length << 1];
+            System.arraycopy(mBuff, 0, buff, 0, mBuff.length);
+            mBuff = buff;
+            mBuff[mBuffIdx] = ch;
+        }
+    }
+
+    /**
+     * Appends (mChIdx - cidx) characters from character buffer (mChars) to
+     * parser's buffer (mBuff).
+     *
+     * @param cidx The character buffer (mChars) start index.
+     * @param bidx The parser buffer (mBuff) start index.
+     */
+    private void bcopy(int cidx, int bidx) {
+        int length = mChIdx - cidx;
+        if ((bidx + length + 1) >= mBuff.length) {
+            //          Expand the buffer
+            char buff[] = new char[mBuff.length + length];
+            System.arraycopy(mBuff, 0, buff, 0, mBuff.length);
+            mBuff = buff;
+        }
+        System.arraycopy(mChars, cidx, mBuff, bidx, length);
+        mBuffIdx += length;
+    }
+
+    /**
+     * Recognizes the built-in entities <i>lt</i>, <i>gt</i>, <i>amp</i>,
+     * <i>apos</i>, <i>quot</i>. The initial state is 0x100. Any state belowe
+     * 0x100 is a built-in entity replacement character.
+     *
+     * @param ch the next character of an entity name.
+     */
+    @SuppressWarnings("fallthrough")
+    private void eappend(char ch) {
+        switch (mESt) {
+            case 0x100:  // "l" or "g" or "a" or "q"
+                switch (ch) {
+                    case 'l':
+                        mESt = 0x101;
+                        break;
+                    case 'g':
+                        mESt = 0x102;
+                        break;
+                    case 'a':
+                        mESt = 0x103;
+                        break;
+                    case 'q':
+                        mESt = 0x107;
+                        break;
+                    default:
+                        mESt = 0x200;
+                        break;
+                }
+                break;
+
+            case 0x101:  // "lt"
+                mESt = (ch == 't') ? '<' : (char) 0x200;
+                break;
+
+            case 0x102:  // "gt"
+                mESt = (ch == 't') ? '>' : (char) 0x200;
+                break;
+
+            case 0x103:  // "am" or "ap"
+                switch (ch) {
+                    case 'm':
+                        mESt = 0x104;
+                        break;
+                    case 'p':
+                        mESt = 0x105;
+                        break;
+                    default:
+                        mESt = 0x200;
+                        break;
+                }
+                break;
+
+            case 0x104:  // "amp"
+                mESt = (ch == 'p') ? '&' : (char) 0x200;
+                break;
+
+            case 0x105:  // "apo"
+                mESt = (ch == 'o') ? (char) 0x106 : (char) 0x200;
+                break;
+
+            case 0x106:  // "apos"
+                mESt = (ch == 's') ? '\'' : (char) 0x200;
+                break;
+
+            case 0x107:  // "qu"
+                mESt = (ch == 'u') ? (char) 0x108 : (char) 0x200;
+                break;
+
+            case 0x108:  // "quo"
+                mESt = (ch == 'o') ? (char) 0x109 : (char) 0x200;
+                break;
+
+            case 0x109:  // "quot"
+                mESt = (ch == 't') ? '\"' : (char) 0x200;
+                break;
+
+            case '<':   // "lt"
+            case '>':   // "gt"
+            case '&':   // "amp"
+            case '\'':  // "apos"
+            case '\"':  // "quot"
+                mESt = 0x200;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Sets up a new input source on the top of the input stack. Note, the first
+     * byte returned by the entity's byte stream has to be the first byte in the
+     * entity. However, the parser does not expect the byte order mask in both
+     * cases when encoding is provided by the input source.
+     *
+     * @param is A new input source to set up.
+     * @exception IOException If any IO errors occur.
+     * @exception Exception is parser specific exception form panic method.
+     */
+    protected void setinp(InputSource is)
+            throws Exception {
+        Reader reader = null;
+        mChIdx = 0;
+        mChLen = 0;
+        mChars = mInp.chars;
+        mInp.src = null;
+        if (mPh < PH_DOC_START) {
+            mIsSAlone = false;  // default [#2.9]
+        }
+        mIsSAloneSet = false;
+        if (is.getCharacterStream() != null) {
+            //          Ignore encoding in the xml text decl.
+            reader = is.getCharacterStream();
+            xml(reader);
+        } else if (is.getByteStream() != null) {
+            String expenc;
+            if (is.getEncoding() != null) {
+                //              Ignore encoding in the xml text decl.
+                expenc = is.getEncoding().toUpperCase();
+                if (expenc.equals("UTF-16")) {
+                    reader = bom(is.getByteStream(), 'U');  // UTF-16 [#4.3.3]
+                } else {
+                    reader = enc(expenc, is.getByteStream());
+                }
+                xml(reader);
+            } else {
+                //              Get encoding from BOM or the xml text decl.
+                reader = bom(is.getByteStream(), ' ');
+                if (reader == null) {
+                    //          Encoding is defined by the xml text decl.
+                    reader = enc("UTF-8", is.getByteStream());
+                    expenc = xml(reader);
+                    if (expenc.startsWith("UTF-16")) {
+                        panic(FAULT);  // UTF-16 must have BOM [#4.3.3]
+                    }
+                    reader = enc(expenc, is.getByteStream());
+                } else {
+                    //          Encoding is defined by the BOM.
+                    xml(reader);
+                }
+            }
+        } else {
+            //          There is no support for public/system identifiers.
+            panic(FAULT);
+        }
+        mInp.src = reader;
+        mInp.pubid = is.getPublicId();
+        mInp.sysid = is.getSystemId();
+    }
+
+    /**
+     * Determines the entity encoding.
+     *
+     * This method gets encoding from Byte Order Mask [#4.3.3] if any. Note, the
+     * first byte returned by the entity's byte stream has to be the first byte
+     * in the entity. Also, there is no support for UCS-4.
+     *
+     * @param is A byte stream of the entity.
+     * @param hint An encoding hint, character U means UTF-16.
+     * @return a reader constructed from the BOM or UTF-8 by default.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private Reader bom(InputStream is, char hint)
+            throws Exception {
+        int val = is.read();
+        switch (val) {
+            case 0xef:     // UTF-8
+                if (hint == 'U') // must be UTF-16
+                {
+                    panic(FAULT);
+                }
+                if (is.read() != 0xbb) {
+                    panic(FAULT);
+                }
+                if (is.read() != 0xbf) {
+                    panic(FAULT);
+                }
+                return new ReaderUTF8(is);
+
+            case 0xfe:     // UTF-16, big-endian
+                if (is.read() != 0xff) {
+                    panic(FAULT);
+                }
+                return new ReaderUTF16(is, 'b');
+
+            case 0xff:     // UTF-16, little-endian
+                if (is.read() != 0xfe) {
+                    panic(FAULT);
+                }
+                return new ReaderUTF16(is, 'l');
+
+            case -1:
+                mChars[mChIdx++] = EOS;
+                return new ReaderUTF8(is);
+
+            default:
+                if (hint == 'U') // must be UTF-16
+                {
+                    panic(FAULT);
+                }
+                //              Read the rest of UTF-8 character
+                switch (val & 0xf0) {
+                    case 0xc0:
+                    case 0xd0:
+                        mChars[mChIdx++] = (char) (((val & 0x1f) << 6) | (is.read() & 0x3f));
+                        break;
+
+                    case 0xe0:
+                        mChars[mChIdx++] = (char) (((val & 0x0f) << 12)
+                                | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f));
+                        break;
+
+                    case 0xf0:  // UCS-4 character
+                        throw new UnsupportedEncodingException();
+
+                    default:
+                        mChars[mChIdx++] = (char) val;
+                        break;
+                }
+                return null;
+        }
+    }
+
+    /**
+     * Parses the xml text declaration.
+     *
+     * This method gets encoding from the xml text declaration [#4.3.1] if any.
+     * The method assumes the buffer (mChars) is big enough to accomodate whole
+     * xml text declaration.
+     *
+     * @param reader is entity reader.
+     * @return The xml text declaration encoding or default UTF-8 encoding.
+     * @exception Exception is parser specific exception form panic method.
+     * @exception IOException
+     */
+    private String xml(Reader reader)
+            throws Exception {
+        String str = null;
+        String enc = "UTF-8";
+        char ch;
+        int val;
+        short st;
+        //              Read the xml text declaration into the buffer
+        if (mChIdx != 0) {
+            //          The bom method have read ONE char into the buffer.
+            st = (short) ((mChars[0] == '<') ? 1 : -1);
+        } else {
+            st = 0;
+        }
+        while (st >= 0 && mChIdx < mChars.length) {
+            ch = ((val = reader.read()) >= 0) ? (char) val : EOS;
+            mChars[mChIdx++] = ch;
+            switch (st) {
+                case 0:     // read '<' of xml declaration
+                    switch (ch) {
+                        case '<':
+                            st = 1;
+                            break;
+
+                        case 0xfeff:    // the byte order mask
+                            ch = ((val = reader.read()) >= 0) ? (char) val : EOS;
+                            mChars[mChIdx - 1] = ch;
+                            st = (short) ((ch == '<') ? 1 : -1);
+                            break;
+
+                        default:
+                            st = -1;
+                            break;
+                    }
+                    break;
+
+                case 1:     // read '?' of xml declaration [#4.3.1]
+                    st = (short) ((ch == '?') ? 2 : -1);
+                    break;
+
+                case 2:     // read 'x' of xml declaration [#4.3.1]
+                    st = (short) ((ch == 'x') ? 3 : -1);
+                    break;
+
+                case 3:     // read 'm' of xml declaration [#4.3.1]
+                    st = (short) ((ch == 'm') ? 4 : -1);
+                    break;
+
+                case 4:     // read 'l' of xml declaration [#4.3.1]
+                    st = (short) ((ch == 'l') ? 5 : -1);
+                    break;
+
+                case 5:     // read white space after 'xml'
+                    switch (ch) {
+                        case ' ':
+                        case '\t':
+                        case '\r':
+                        case '\n':
+                            st = 6;
+                            break;
+
+                        default:
+                            st = -1;
+                            break;
+                    }
+                    break;
+
+                case 6:     // read content of xml declaration
+                    switch (ch) {
+                        case '?':
+                            st = 7;
+                            break;
+
+                        case EOS:
+                            st = -2;
+                            break;
+
+                        default:
+                            break;
+                    }
+                    break;
+
+                case 7:     // read '>' after '?' of xml declaration
+                    switch (ch) {
+                        case '>':
+                        case EOS:
+                            st = -2;
+                            break;
+
+                        default:
+                            st = 6;
+                            break;
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+                    break;
+            }
+        }
+        mChLen = mChIdx;
+        mChIdx = 0;
+        //              If there is no xml text declaration, the encoding is default.
+        if (st == -1) {
+            return enc;
+        }
+        mChIdx = 5;  // the first white space after "<?xml"
+        //              Parse the xml text declaration
+        for (st = 0; st >= 0;) {
+            ch = getch();
+            switch (st) {
+                case 0:     // skip spaces after the xml declaration name
+                    if (chtyp(ch) != ' ') {
+                        bkch();
+                        st = 1;
+                    }
+                    break;
+
+                case 1:     // read xml declaration version
+                case 2:     // read xml declaration encoding or standalone
+                case 3:     // read xml declaration standalone
+                    switch (chtyp(ch)) {
+                        case 'a':
+                        case 'A':
+                        case '_':
+                            bkch();
+                            str = name(false).toLowerCase();
+                            if ("version".equals(str) == true) {
+                                if (st != 1) {
+                                    panic(FAULT);
+                                }
+                                if ("1.0".equals(eqstr('=')) != true) {
+                                    panic(FAULT);
+                                }
+                                mInp.xmlver = 0x0100;
+                                st = 2;
+                            } else if ("encoding".equals(str) == true) {
+                                if (st != 2) {
+                                    panic(FAULT);
+                                }
+                                mInp.xmlenc = eqstr('=').toUpperCase();
+                                enc = mInp.xmlenc;
+                                st = 3;
+                            } else if ("standalone".equals(str) == true) {
+                                if ((st == 1) || (mPh >= PH_DOC_START)) // [#4.3.1]
+                                {
+                                    panic(FAULT);
+                                }
+                                str = eqstr('=').toLowerCase();
+                                //              Check the 'standalone' value and use it [#5.1]
+                                if (str.equals("yes") == true) {
+                                    mIsSAlone = true;
+                                } else if (str.equals("no") == true) {
+                                    mIsSAlone = false;
+                                } else {
+                                    panic(FAULT);
+                                }
+                                mIsSAloneSet = true;
+                                st = 4;
+                            } else {
+                                panic(FAULT);
+                            }
+                            break;
+
+                        case ' ':
+                            break;
+
+                        case '?':
+                            if (st == 1) {
+                                panic(FAULT);
+                            }
+                            bkch();
+                            st = 4;
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                case 4:     // end of xml declaration
+                    switch (chtyp(ch)) {
+                        case '?':
+                            if (getch() != '>') {
+                                panic(FAULT);
+                            }
+                            if (mPh <= PH_DOC_START) {
+                                mPh = PH_MISC_DTD;  // misc before DTD
+                            }
+                            st = -1;
+                            break;
+
+                        case ' ':
+                            break;
+
+                        default:
+                            panic(FAULT);
+                    }
+                    break;
+
+                default:
+                    panic(FAULT);
+            }
+        }
+        return enc;
+    }
+
+    /**
+     * Sets up the document reader.
+     *
+     * @param name an encoding name.
+     * @param is the document byte input stream.
+     * @return a reader constructed from encoding name and input stream.
+     * @exception UnsupportedEncodingException
+     */
+    private Reader enc(String name, InputStream is)
+            throws UnsupportedEncodingException {
+        //              DO NOT CLOSE current reader if any!
+        if (name.equals("UTF-8")) {
+            return new ReaderUTF8(is);
+        } else if (name.equals("UTF-16LE")) {
+            return new ReaderUTF16(is, 'l');
+        } else if (name.equals("UTF-16BE")) {
+            return new ReaderUTF16(is, 'b');
+        } else {
+            return new InputStreamReader(is, name);
+        }
+    }
+
+    /**
+     * Sets up current input on the top of the input stack.
+     *
+     * @param inp A new input to set up.
+     */
+    protected void push(Input inp) {
+        mInp.chLen = mChLen;
+        mInp.chIdx = mChIdx;
+        inp.next = mInp;
+        mInp = inp;
+        mChars = inp.chars;
+        mChLen = inp.chLen;
+        mChIdx = inp.chIdx;
+    }
+
+    /**
+     * Restores previous input on the top of the input stack.
+     */
+    protected void pop() {
+        if (mInp.src != null) {
+            try {
+                mInp.src.close();
+            } catch (IOException ioe) {
+            }
+            mInp.src = null;
+        }
+        mInp = mInp.next;
+        if (mInp != null) {
+            mChars = mInp.chars;
+            mChLen = mInp.chLen;
+            mChIdx = mInp.chIdx;
+        } else {
+            mChars = null;
+            mChLen = 0;
+            mChIdx = 0;
+        }
+    }
+
+    /**
+     * Maps a character to it's type.
+     *
+     * Possible character type values are:<br /> - ' ' for any kind of white
+     * space character;<br /> - 'a' for any lower case alphabetical character
+     * value;<br /> - 'A' for any upper case alphabetical character value;<br />
+     * - 'd' for any decimal digit character value;<br /> - 'z' for any
+     * character less then ' ' except '\t', '\n', '\r';<br /> - 'X' for any not
+     * ASCII character;<br /> - 'Z' for EOS character.<br /> An ASCII (7 bit)
+     * character which does not fall in any category listed above is mapped to
+     * it self.
+     *
+     * @param ch The character to map.
+     * @return The type of character.
+     */
+    protected char chtyp(char ch) {
+        if (ch < 0x80) {
+            return (char) asctyp[ch];
+        }
+        return (ch != EOS) ? 'X' : 'Z';
+    }
+
+    /**
+     * Retrives the next character in the document.
+     *
+     * @return The next character in the document.
+     */
+    protected char getch()
+            throws IOException {
+        if (mChIdx >= mChLen) {
+            if (mInp.src == null) {
+                pop();  // remove internal entity
+                return getch();
+            }
+            //          Read new portion of the document characters
+            int Num = mInp.src.read(mChars, 0, mChars.length);
+            if (Num < 0) {
+                if (mInp != mDoc) {
+                    pop();  // restore the previous input
+                    return getch();
+                } else {
+                    mChars[0] = EOS;
+                    mChLen = 1;
+                }
+            } else {
+                mChLen = Num;
+            }
+            mChIdx = 0;
+        }
+        return mChars[mChIdx++];
+    }
+
+    /**
+     * Puts back the last read character.
+     *
+     * This method <strong>MUST NOT</strong> be called more then once after each
+     * call of {@link #getch getch} method.
+     */
+    protected void bkch()
+            throws Exception {
+        if (mChIdx <= 0) {
+            panic(FAULT);
+        }
+        mChIdx--;
+    }
+
+    /**
+     * Sets the current character.
+     *
+     * @param ch The character to set.
+     */
+    protected void setch(char ch) {
+        mChars[mChIdx] = ch;
+    }
+
+    /**
+     * Finds a pair in the pair chain by a qualified name.
+     *
+     * @param chain The first element of the chain of pairs.
+     * @param qname The qualified name.
+     * @return A pair with the specified qualified name or null.
+     */
+    protected Pair find(Pair chain, char[] qname) {
+        for (Pair pair = chain; pair != null; pair = pair.next) {
+            if (pair.eqname(qname) == true) {
+                return pair;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Provedes an instance of a pair.
+     *
+     * @param next The reference to a next pair.
+     * @return An instance of a pair.
+     */
+    protected Pair pair(Pair next) {
+        Pair pair;
+
+        if (mDltd != null) {
+            pair = mDltd;
+            mDltd = pair.next;
+        } else {
+            pair = new Pair();
+        }
+        pair.next = next;
+
+        return pair;
+    }
+
+    /**
+     * Deletes an instance of a pair.
+     *
+     * @param pair The pair to delete.
+     * @return A reference to the next pair in a chain.
+     */
+    protected Pair del(Pair pair) {
+        Pair next = pair.next;
+
+        pair.name = null;
+        pair.value = null;
+        pair.chars = null;
+        pair.list = null;
+        pair.next = mDltd;
+        mDltd = pair;
+
+        return next;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/ParserSAX.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.ContentHandler;
+import jdk.internal.org.xml.sax.DTDHandler;
+import jdk.internal.org.xml.sax.EntityResolver;
+import jdk.internal.org.xml.sax.ErrorHandler;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.Locator;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.SAXParseException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * XML non-validating push parser.
+ *
+ * This non-validating parser conforms to <a href="http://www.w3.org/TR/REC-xml"
+ * >Extensible Markup Language (XML) 1.0</a> and <a
+ * href="http://www.w3.org/TR/REC-xml-names" >"Namespaces in XML"</a>
+ * specifications. The API supported by the parser are <a
+ * href="http://java.sun.com/aboutJava/communityprocess/final/jsr030/index.html">CLDC
+ * 1.0</a> and <a href="http://www.jcp.org/en/jsr/detail?id=280">JSR-280</a>, a
+ * JavaME subset of <a href="http://java.sun.com/xml/jaxp/index.html">JAXP</a>
+ * and <a href="http://www.saxproject.org/">SAX2</a>.
+ *
+ * @see org.xml.sax.XMLReader
+ */
+
+final class ParserSAX
+    extends Parser implements XMLReader, Locator
+{
+    public final static String FEATURE_NS =
+            "http://xml.org/sax/features/namespaces";
+    public final static String FEATURE_PREF =
+            "http://xml.org/sax/features/namespace-prefixes";
+    //          SAX feature flags
+    private boolean mFNamespaces;
+    private boolean mFPrefixes;
+    //          SAX handlers
+    private DefaultHandler mHand;      // the default handler
+    private ContentHandler mHandCont;  // the content handler
+    private DTDHandler mHandDtd;   // the DTD handler
+    private ErrorHandler mHandErr;   // the error handler
+    private EntityResolver mHandEnt;   // the entity resolver
+
+    /**
+     * Constructor.
+     */
+    public ParserSAX() {
+        super();
+
+        //              SAX feature defaut values
+        mFNamespaces = true;
+        mFPrefixes = false;
+
+        //              Default handler which will be used in case the application
+        //              do not set one of handlers.
+        mHand = new DefaultHandler();
+        mHandCont = mHand;
+        mHandDtd = mHand;
+        mHandErr = mHand;
+        mHandEnt = mHand;
+    }
+
+    /**
+     * Return the current content handler.
+     *
+     * @return The current content handler, or null if none has been registered.
+     * @see #setContentHandler
+     */
+    public ContentHandler getContentHandler() {
+        return (mHandCont != mHand) ? mHandCont : null;
+    }
+
+    /**
+     * Allow an application to register a content event handler.
+     *
+     * <p>If the application does not register a content handler, all content
+     * events reported by the SAX parser will be silently ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the middle of
+     * a parse, and the SAX parser must begin using the new handler
+     * immediately.</p>
+     *
+     * @param handler The content handler.
+     * @exception java.lang.NullPointerException If the handler argument is
+     * null.
+     * @see #getContentHandler
+     */
+    public void setContentHandler(ContentHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException();
+        }
+        mHandCont = handler;
+    }
+
+    /**
+     * Return the current DTD handler.
+     *
+     * @return The current DTD handler, or null if none has been registered.
+     * @see #setDTDHandler
+     */
+    public DTDHandler getDTDHandler() {
+        return (mHandDtd != mHand) ? mHandDtd : null;
+    }
+
+    /**
+     * Allow an application to register a DTD event handler.
+     *
+     * <p>If the application does not register a DTD handler, all DTD events
+     * reported by the SAX parser will be silently ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the middle of
+     * a parse, and the SAX parser must begin using the new handler
+     * immediately.</p>
+     *
+     * @param handler The DTD handler.
+     * @exception java.lang.NullPointerException If the handler argument is
+     * null.
+     * @see #getDTDHandler
+     */
+    public void setDTDHandler(DTDHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException();
+        }
+        mHandDtd = handler;
+    }
+
+    /**
+     * Return the current error handler.
+     *
+     * @return The current error handler, or null if none has been registered.
+     * @see #setErrorHandler
+     */
+    public ErrorHandler getErrorHandler() {
+        return (mHandErr != mHand) ? mHandErr : null;
+    }
+
+    /**
+     * Allow an application to register an error event handler.
+     *
+     * <p>If the application does not register an error handler, all error
+     * events reported by the SAX parser will be silently ignored; however,
+     * normal processing may not continue. It is highly recommended that all SAX
+     * applications implement an error handler to avoid unexpected bugs.</p>
+     *
+     * <p>Applications may register a new or different handler in the middle of
+     * a parse, and the SAX parser must begin using the new handler
+     * immediately.</p>
+     *
+     * @param handler The error handler.
+     * @exception java.lang.NullPointerException If the handler argument is
+     * null.
+     * @see #getErrorHandler
+     */
+    public void setErrorHandler(ErrorHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException();
+        }
+        mHandErr = handler;
+    }
+
+    /**
+     * Return the current entity resolver.
+     *
+     * @return The current entity resolver, or null if none has been registered.
+     * @see #setEntityResolver
+     */
+    public EntityResolver getEntityResolver() {
+        return (mHandEnt != mHand) ? mHandEnt : null;
+    }
+
+    /**
+     * Allow an application to register an entity resolver.
+     *
+     * <p>If the application does not register an entity resolver, the XMLReader
+     * will perform its own default resolution.</p>
+     *
+     * <p>Applications may register a new or different resolver in the middle of
+     * a parse, and the SAX parser must begin using the new resolver
+     * immediately.</p>
+     *
+     * @param resolver The entity resolver.
+     * @exception java.lang.NullPointerException If the resolver argument is
+     * null.
+     * @see #getEntityResolver
+     */
+    public void setEntityResolver(EntityResolver resolver) {
+        if (resolver == null) {
+            throw new NullPointerException();
+        }
+        mHandEnt = resolver;
+    }
+
+    /**
+     * Return the public identifier for the current document event.
+     *
+     * <p>The return value is the public identifier of the document entity or of
+     * the external parsed entity in which the markup triggering the event
+     * appears.</p>
+     *
+     * @return A string containing the public identifier, or null if none is
+     * available.
+     *
+     * @see #getSystemId
+     */
+    public String getPublicId() {
+        return (mInp != null) ? mInp.pubid : null;
+    }
+
+    /**
+     * Return the system identifier for the current document event.
+     *
+     * <p>The return value is the system identifier of the document entity or of
+     * the external parsed entity in which the markup triggering the event
+     * appears.</p>
+     *
+     * <p>If the system identifier is a URL, the parser must resolve it fully
+     * before passing it to the application.</p>
+     *
+     * @return A string containing the system identifier, or null if none is
+     * available.
+     *
+     * @see #getPublicId
+     */
+    public String getSystemId() {
+        return (mInp != null) ? mInp.sysid : null;
+    }
+
+    /**
+     * Return the line number where the current document event ends.
+     *
+     * @return Always returns -1 indicating the line number is not available.
+     *
+     * @see #getColumnNumber
+     */
+    public int getLineNumber() {
+        return -1;
+    }
+
+    /**
+     * Return the column number where the current document event ends.
+     *
+     * @return Always returns -1 indicating the column number is not available.
+     *
+     * @see #getLineNumber
+     */
+    public int getColumnNumber() {
+        return -1;
+    }
+
+    /**
+     * Parse an XML document from a system identifier (URI).
+     *
+     * <p>This method is a shortcut for the common case of reading a document
+     * from a system identifier. It is the exact equivalent of the
+     * following:</p>
+     *
+     * <pre>
+     * parse(new InputSource(systemId));
+     * </pre>
+     *
+     * <p>If the system identifier is a URL, it must be fully resolved by the
+     * application before it is passed to the parser.</p>
+     *
+     * @param systemId The system identifier (URI).
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly wrapping
+     * another exception.
+     * @exception java.io.IOException An IO exception from the parser, possibly
+     * from a byte stream or character stream supplied by the application.
+     * @see #parse(org.xml.sax.InputSource)
+     */
+    public void parse(String systemId) throws IOException, SAXException {
+        parse(new InputSource(systemId));
+    }
+
+    /**
+     * Parse an XML document.
+     *
+     * <p>The application can use this method to instruct the XML reader to
+     * begin parsing an XML document from any valid input source (a character
+     * stream, a byte stream, or a URI).</p>
+     *
+     * <p>Applications may not invoke this method while a parse is in progress
+     * (they should create a new XMLReader instead for each nested XML
+     * document). Once a parse is complete, an application may reuse the same
+     * XMLReader object, possibly with a different input source.</p>
+     *
+     * <p>During the parse, the XMLReader will provide information about the XML
+     * document through the registered event handlers.</p>
+     *
+     * <p>This method is synchronous: it will not return until parsing has
+     * ended. If a client application wants to terminate parsing early, it
+     * should throw an exception.</p>
+     *
+     * @param is The input source for the top-level of the XML document.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly wrapping
+     * another exception.
+     * @exception java.io.IOException An IO exception from the parser, possibly
+     * from a byte stream or character stream supplied by the application.
+     * @see org.xml.sax.InputSource
+     * @see #parse(java.lang.String)
+     * @see #setEntityResolver
+     * @see #setDTDHandler
+     * @see #setContentHandler
+     * @see #setErrorHandler
+     */
+    public void parse(InputSource is) throws IOException, SAXException {
+        if (is == null) {
+            throw new IllegalArgumentException("");
+        }
+        //              Set up the document
+        mInp = new Input(BUFFSIZE_READER);
+        mPh = PH_BEFORE_DOC;  // before parsing
+        try {
+            setinp(is);
+        } catch (SAXException saxe) {
+            throw saxe;
+        } catch (IOException ioe) {
+            throw ioe;
+        } catch (RuntimeException rte) {
+            throw rte;
+        } catch (Exception e) {
+            panic(e.toString());
+        }
+        parse();
+    }
+
+    /**
+     * Parse the content of the given {@link java.io.InputStream} instance as
+     * XML using the specified {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param src InputStream containing the content to be parsed.
+     * @param handler The SAX DefaultHandler to use.
+     * @exception IOException If any IO errors occur.
+     * @exception IllegalArgumentException If the given InputStream or handler
+     * is null.
+     * @exception SAXException If the underlying parser throws a SAXException
+     * while parsing.
+     * @see org.xml.sax.helpers.DefaultHandler
+     */
+    public void parse(InputStream src, DefaultHandler handler)
+            throws SAXException, IOException {
+        if ((src == null) || (handler == null)) {
+            throw new IllegalArgumentException("");
+        }
+        parse(new InputSource(src), handler);
+    }
+
+    /**
+     * Parse the content given {@link org.xml.sax.InputSource} as XML using the
+     * specified {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param is The InputSource containing the content to be parsed.
+     * @param handler The SAX DefaultHandler to use.
+     * @exception IOException If any IO errors occur.
+     * @exception IllegalArgumentException If the InputSource or handler is
+     * null.
+     * @exception SAXException If the underlying parser throws a SAXException
+     * while parsing.
+     * @see org.xml.sax.helpers.DefaultHandler
+     */
+    public void parse(InputSource is, DefaultHandler handler)
+        throws SAXException, IOException
+    {
+        if ((is == null) || (handler == null)) {
+            throw new IllegalArgumentException("");
+        }
+        //              Set up the handler
+        mHandCont = handler;
+        mHandDtd = handler;
+        mHandErr = handler;
+        mHandEnt = handler;
+        //              Set up the document
+        mInp = new Input(BUFFSIZE_READER);
+        mPh = PH_BEFORE_DOC;  // before parsing
+        try {
+            setinp(is);
+        } catch (SAXException | IOException | RuntimeException saxe) {
+            throw saxe;
+        } catch (Exception e) {
+            panic(e.toString());
+        }
+        parse();
+    }
+
+    /**
+     * Parse the XML document content using specified handlers and an input
+     * source.
+     *
+     * @exception IOException If any IO errors occur.
+     * @exception SAXException If the underlying parser throws a SAXException
+     * while parsing.
+     */
+    @SuppressWarnings("fallthrough")
+    private void parse() throws SAXException, IOException {
+        init();
+        try {
+            mHandCont.setDocumentLocator(this);
+            mHandCont.startDocument();
+
+            if (mPh != PH_MISC_DTD) {
+                mPh = PH_MISC_DTD;  // misc before DTD
+            }
+            int evt = EV_NULL;
+            //          XML document prolog
+            do {
+                wsskip();
+                switch (evt = step()) {
+                    case EV_ELM:
+                    case EV_ELMS:
+                        mPh = PH_DOCELM;
+                        break;
+
+                    case EV_COMM:
+                    case EV_PI:
+                        break;
+
+                    case EV_DTD:
+                        if (mPh >= PH_DTD_MISC) {
+                            panic(FAULT);
+                        }
+                        mPh = PH_DTD_MISC;  // misc after DTD
+                        break;
+
+                    default:
+                        panic(FAULT);
+                }
+            } while (mPh < PH_DOCELM);  // misc before DTD
+            //          XML document starting with document's element
+            do {
+                switch (evt) {
+                    case EV_ELM:
+                    case EV_ELMS:
+                        //              Report the element
+                        if (mIsNSAware == true) {
+                            mHandCont.startElement(
+                                    mElm.value,
+                                    mElm.name,
+                                    "",
+                                    mAttrs);
+                        } else {
+                            mHandCont.startElement(
+                                    "",
+                                    "",
+                                    mElm.name,
+                                    mAttrs);
+                        }
+                        if (evt == EV_ELMS) {
+                            evt = step();
+                            break;
+                        }
+
+                    case EV_ELME:
+                        //              Report the end of element
+                        if (mIsNSAware == true) {
+                            mHandCont.endElement(mElm.value, mElm.name, "");
+                        } else {
+                            mHandCont.endElement("", "", mElm.name);
+                        }
+                        //              Restore the top of the prefix stack
+                        while (mPref.list == mElm) {
+                            mHandCont.endPrefixMapping(mPref.name);
+                            mPref = del(mPref);
+                        }
+                        //              Remove the top element tag
+                        mElm = del(mElm);
+                        if (mElm == null) {
+                            mPh = PH_DOCELM_MISC;
+                        } else {
+                            evt = step();
+                        }
+                        break;
+
+                    case EV_TEXT:
+                    case EV_WSPC:
+                    case EV_CDAT:
+                    case EV_COMM:
+                    case EV_PI:
+                    case EV_ENT:
+                        evt = step();
+                        break;
+
+                    default:
+                        panic(FAULT);
+                }
+            } while (mPh == PH_DOCELM);
+            //          Misc after document's element
+            do {
+                if (wsskip() == EOS) {
+                    break;
+                }
+
+                switch (step()) {
+                    case EV_COMM:
+                    case EV_PI:
+                        break;
+
+                    default:
+                        panic(FAULT);
+                }
+            } while (mPh == PH_DOCELM_MISC);
+            mPh = PH_AFTER_DOC;  // parsing is completed
+
+        } catch (SAXException saxe) {
+            throw saxe;
+        } catch (IOException ioe) {
+            throw ioe;
+        } catch (RuntimeException rte) {
+            throw rte;
+        } catch (Exception e) {
+            panic(e.toString());
+        } finally {
+            mHandCont.endDocument();
+            cleanup();
+        }
+    }
+
+    /**
+     * Reports document type.
+     *
+     * @param name The name of the entity.
+     * @param pubid The public identifier of the entity or <code>null</code>.
+     * @param sysid The system identifier of the entity or <code>null</code>.
+     */
+    protected void docType(String name, String pubid, String sysid) throws SAXException {
+        mHandDtd.notationDecl(name, pubid, sysid);
+    }
+
+    /**
+     * Reports a comment.
+     *
+     * @param text The comment text starting from first charcater.
+     * @param length The number of characters in comment.
+     */
+    protected void comm(char[] text, int length) {
+    }
+
+    /**
+     * Reports a processing instruction.
+     *
+     * @param target The processing instruction target name.
+     * @param body The processing instruction body text.
+     */
+    protected void pi(String target, String body) throws SAXException {
+        mHandCont.processingInstruction(target, body);
+    }
+
+    /**
+     * Reports new namespace prefix. The Namespace prefix (
+     * <code>mPref.name</code>) being declared and the Namespace URI (
+     * <code>mPref.value</code>) the prefix is mapped to. An empty string is
+     * used for the default element namespace, which has no prefix.
+     */
+    protected void newPrefix() throws SAXException {
+        mHandCont.startPrefixMapping(mPref.name, mPref.value);
+    }
+
+    /**
+     * Reports skipped entity name.
+     *
+     * @param name The entity name.
+     */
+    protected void skippedEnt(String name) throws SAXException {
+        mHandCont.skippedEntity(name);
+    }
+
+    /**
+     * Returns an
+     * <code>InputSource</code> for specified entity or
+     * <code>null</code>.
+     *
+     * @param name The name of the entity.
+     * @param pubid The public identifier of the entity.
+     * @param sysid The system identifier of the entity.
+     */
+    protected InputSource resolveEnt(String name, String pubid, String sysid)
+        throws SAXException, IOException
+    {
+        return mHandEnt.resolveEntity(pubid, sysid);
+    }
+
+    /**
+     * Reports notation declaration.
+     *
+     * @param name The notation's name.
+     * @param pubid The notation's public identifier, or null if none was given.
+     * @param sysid The notation's system identifier, or null if none was given.
+     */
+    protected void notDecl(String name, String pubid, String sysid)
+        throws SAXException
+    {
+        mHandDtd.notationDecl(name, pubid, sysid);
+    }
+
+    /**
+     * Reports unparsed entity name.
+     *
+     * @param name The unparsed entity's name.
+     * @param pubid The entity's public identifier, or null if none was given.
+     * @param sysid The entity's system identifier.
+     * @param notation The name of the associated notation.
+     */
+    protected void unparsedEntDecl(String name, String pubid, String sysid, String notation)
+        throws SAXException
+    {
+        mHandDtd.unparsedEntityDecl(name, pubid, sysid, notation);
+    }
+
+    /**
+     * Notifies the handler about fatal parsing error.
+     *
+     * @param msg The problem description message.
+     */
+    protected void panic(String msg) throws SAXException {
+        SAXParseException spe = new SAXParseException(msg, this);
+        mHandErr.fatalError(spe);
+        throw spe;  // [#1.2] fatal error definition
+    }
+
+    /**
+     * Reports characters and empties the parser's buffer. This method is called
+     * only if parser is going to return control to the main loop. This means
+     * that this method may use parser buffer to report white space without
+     * copeing characters to temporary buffer.
+     */
+    protected void bflash() throws SAXException {
+        if (mBuffIdx >= 0) {
+            //          Textual data has been read
+            mHandCont.characters(mBuff, 0, (mBuffIdx + 1));
+            mBuffIdx = -1;
+        }
+    }
+
+    /**
+     * Reports white space characters and empties the parser's buffer. This
+     * method is called only if parser is going to return control to the main
+     * loop. This means that this method may use parser buffer to report white
+     * space without copeing characters to temporary buffer.
+     */
+    protected void bflash_ws() throws SAXException {
+        if (mBuffIdx >= 0) {
+            // BUG: With additional info from DTD and xml:space attr [#2.10]
+            // the following call can be supported:
+            // mHandCont.ignorableWhitespace(mBuff, 0, (mBuffIdx + 1));
+
+            //          Textual data has been read
+            mHandCont.characters(mBuff, 0, (mBuffIdx + 1));
+            mBuffIdx = -1;
+        }
+    }
+
+    public boolean getFeature(String name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void setFeature(String name, boolean value) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Object getProperty(String name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void setProperty(String name, Object value) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/ReaderUTF16.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * UTF-16 encoded stream reader.
+ */
+public class ReaderUTF16 extends Reader {
+
+    private InputStream is;
+    private char bo;
+
+    /**
+     * Constructor.
+     *
+     * Byte order argument can be: 'l' for little-endian or 'b' for big-endian.
+     *
+     * @param is A byte input stream.
+     * @param bo A byte order in the input stream.
+     */
+    public ReaderUTF16(InputStream is, char bo) {
+        switch (bo) {
+            case 'l':
+                break;
+
+            case 'b':
+                break;
+
+            default:
+                throw new IllegalArgumentException("");
+        }
+        this.bo = bo;
+        this.is = is;
+    }
+
+    /**
+     * Reads characters into a portion of an array.
+     *
+     * @param cbuf Destination buffer.
+     * @param off Offset at which to start storing characters.
+     * @param len Maximum number of characters to read.
+     * @exception IOException If any IO errors occur.
+     */
+    public int read(char[] cbuf, int off, int len) throws IOException {
+        int num = 0;
+        int val;
+        if (bo == 'b') {
+            while (num < len) {
+                if ((val = is.read()) < 0) {
+                    return (num != 0) ? num : -1;
+                }
+                cbuf[off++] = (char) ((val << 8) | (is.read() & 0xff));
+                num++;
+            }
+        } else {
+            while (num < len) {
+                if ((val = is.read()) < 0) {
+                    return (num != 0) ? num : -1;
+                }
+                cbuf[off++] = (char) ((is.read() << 8) | (val & 0xff));
+                num++;
+            }
+        }
+        return num;
+    }
+
+    /**
+     * Reads a single character.
+     *
+     * @return The character read, as an integer in the range 0 to 65535
+     *  (0x0000-0xffff), or -1 if the end of the stream has been reached.
+     * @exception IOException If any IO errors occur.
+     */
+    public int read() throws IOException {
+        int val;
+        if ((val = is.read()) < 0) {
+            return -1;
+        }
+        if (bo == 'b') {
+            val = (char) ((val << 8) | (is.read() & 0xff));
+        } else {
+            val = (char) ((is.read() << 8) | (val & 0xff));
+        }
+        return val;
+    }
+
+    /**
+     * Closes the stream.
+     *
+     * @exception IOException If any IO errors occur.
+     */
+    public void close() throws IOException {
+        is.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/ReaderUTF8.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * UTF-8 transformed UCS-2 character stream reader.
+ *
+ * This reader converts UTF-8 transformed UCS-2 characters to Java characters.
+ * The UCS-2 subset of UTF-8 transformation is described in RFC-2279 #2
+ * "UTF-8 definition":
+ *  0000 0000-0000 007F   0xxxxxxx
+ *  0000 0080-0000 07FF   110xxxxx 10xxxxxx
+ *  0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
+ *
+ * This reader will return incorrect last character on broken UTF-8 stream.
+ */
+public class ReaderUTF8 extends Reader {
+
+    private InputStream is;
+
+    /**
+     * Constructor.
+     *
+     * @param is A byte input stream.
+     */
+    public ReaderUTF8(InputStream is) {
+        this.is = is;
+    }
+
+    /**
+     * Reads characters into a portion of an array.
+     *
+     * @param cbuf Destination buffer.
+     * @param off Offset at which to start storing characters.
+     * @param len Maximum number of characters to read.
+     * @exception IOException If any IO errors occur.
+     * @exception UnsupportedEncodingException If UCS-4 character occur in the stream.
+     */
+    public int read(char[] cbuf, int off, int len) throws IOException {
+        int num = 0;
+        int val;
+        while (num < len) {
+            if ((val = is.read()) < 0) {
+                return (num != 0) ? num : -1;
+            }
+            switch (val & 0xf0) {
+                case 0xc0:
+                case 0xd0:
+                    cbuf[off++] = (char) (((val & 0x1f) << 6) | (is.read() & 0x3f));
+                    break;
+
+                case 0xe0:
+                    cbuf[off++] = (char) (((val & 0x0f) << 12)
+                            | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f));
+                    break;
+
+                case 0xf0:      // UCS-4 character
+                    throw new UnsupportedEncodingException("UTF-32 (or UCS-4) encoding not supported.");
+
+                default:
+                    cbuf[off++] = (char) val;
+                    break;
+            }
+            num++;
+        }
+        return num;
+    }
+
+    /**
+     * Reads a single character.
+     *
+     * @return The character read, as an integer in the range 0 to 65535
+     *  (0x00-0xffff), or -1 if the end of the stream has been reached.
+     * @exception IOException If any IO errors occur.
+     * @exception UnsupportedEncodingException If UCS-4 character occur in the stream.
+     */
+    public int read() throws IOException {
+        int val;
+        if ((val = is.read()) < 0) {
+            return -1;
+        }
+        switch (val & 0xf0) {
+            case 0xc0:
+            case 0xd0:
+                val = ((val & 0x1f) << 6) | (is.read() & 0x3f);
+                break;
+
+            case 0xe0:
+                val = ((val & 0x0f) << 12)
+                        | ((is.read() & 0x3f) << 6) | (is.read() & 0x3f);
+                break;
+
+            case 0xf0:  // UCS-4 character
+                throw new UnsupportedEncodingException();
+
+            default:
+                break;
+        }
+        return val;
+    }
+
+    /**
+     * Closes the stream.
+     *
+     * @exception IOException If any IO errors occur.
+     */
+    public void close() throws IOException {
+        is.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/SAXParserImpl.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import jdk.internal.org.xml.sax.InputSource;
+import jdk.internal.org.xml.sax.SAXException;
+import jdk.internal.org.xml.sax.XMLReader;
+import jdk.internal.org.xml.sax.helpers.DefaultHandler;
+import jdk.internal.util.xml.SAXParser;
+
+public class SAXParserImpl extends SAXParser {
+
+    private ParserSAX parser;
+
+    public SAXParserImpl() {
+        super();
+        parser = new ParserSAX();
+    }
+
+    /**
+     * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the
+     * implementation of this class.
+     *
+     * @return The XMLReader that is encapsulated by the
+     *         implementation of this class.
+     *
+     * @throws SAXException If any SAX errors occur during processing.
+     */
+    public XMLReader getXMLReader()
+            throws SAXException {
+        return parser;
+    }
+
+    /**
+     * Indicates whether or not this parser is configured to
+     * understand namespaces.
+     *
+     * @return true if this parser is configured to
+     *         understand namespaces; false otherwise.
+     */
+    public boolean isNamespaceAware() {
+        return parser.mIsNSAware;
+    }
+
+    /**
+     * Indicates whether or not this parser is configured to validate
+     * XML documents.
+     *
+     * @return true if this parser is configured to validate XML
+     *          documents; false otherwise.
+     */
+    public boolean isValidating() {
+        return false;
+    }
+
+    /**
+     * Parse the content of the given {@link java.io.InputStream}
+     * instance as XML using the specified
+     * {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param src InputStream containing the content to be parsed.
+     * @param handler The SAX DefaultHandler to use.
+     * @exception IOException If any IO errors occur.
+     * @exception IllegalArgumentException If the given InputStream or handler is null.
+     * @exception SAXException If the underlying parser throws a
+     * SAXException while parsing.
+     * @see org.xml.sax.helpers.DefaultHandler
+     */
+    public void parse(InputStream src, DefaultHandler handler)
+        throws SAXException, IOException
+    {
+        parser.parse(src, handler);
+    }
+
+    /**
+     * Parse the content given {@link org.xml.sax.InputSource}
+     * as XML using the specified
+     * {@link org.xml.sax.helpers.DefaultHandler}.
+     *
+     * @param is The InputSource containing the content to be parsed.
+     * @param handler The SAX DefaultHandler to use.
+     * @exception IOException If any IO errors occur.
+     * @exception IllegalArgumentException If the InputSource or handler is null.
+     * @exception SAXException If the underlying parser throws a
+     * SAXException while parsing.
+     * @see org.xml.sax.helpers.DefaultHandler
+     */
+    public void parse(InputSource is, DefaultHandler handler)
+        throws SAXException, IOException
+    {
+        parser.parse(is, handler);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import jdk.internal.util.xml.XMLStreamException;
+import jdk.internal.util.xml.XMLStreamWriter;
+
+/**
+ * Implementation of a reduced version of XMLStreamWriter
+ *
+ * @author Joe Wang
+ */
+public class XMLStreamWriterImpl implements XMLStreamWriter {
+    //Document state
+
+    static final int STATE_XML_DECL = 1;
+    static final int STATE_PROLOG = 2;
+    static final int STATE_DTD_DECL = 3;
+    static final int STATE_ELEMENT = 4;
+    //Element state
+    static final int ELEMENT_STARTTAG_OPEN = 10;
+    static final int ELEMENT_STARTTAG_CLOSE = 11;
+    static final int ELEMENT_ENDTAG_OPEN = 12;
+    static final int ELEMENT_ENDTAG_CLOSE = 13;
+    public static final char CLOSE_START_TAG = '>';
+    public static final char OPEN_START_TAG = '<';
+    public static final String OPEN_END_TAG = "</";
+    public static final char CLOSE_END_TAG = '>';
+    public static final String START_CDATA = "<![CDATA[";
+    public static final String END_CDATA = "]]>";
+    public static final String CLOSE_EMPTY_ELEMENT = "/>";
+    public static final String ENCODING_PREFIX = "&#x";
+    public static final char SPACE = ' ';
+    public static final char AMPERSAND = '&';
+    public static final char DOUBLEQUOT = '"';
+    public static final char SEMICOLON = ';';
+    //current state
+    private int _state = 0;
+    private Element _currentEle;
+    private XMLWriter _writer;
+    private String _encoding;
+    /**
+     * This flag can be used to turn escaping off for content. It does
+     * not apply to attribute content.
+     */
+    boolean _escapeCharacters = true;
+    //pretty print by default
+    private boolean _doIndent = true;
+    //The system line separator for writing out line breaks.
+    private char[] _lineSep =
+            System.getProperty("line.separator").toCharArray();
+
+    public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException {
+        this(os, XMLStreamWriter.DEFAULT_ENCODING);
+    }
+
+    public XMLStreamWriterImpl(OutputStream os, String encoding)
+        throws XMLStreamException
+    {
+        Charset cs = null;
+        if (encoding == null) {
+            _encoding = XMLStreamWriter.DEFAULT_ENCODING;
+        } else {
+            try {
+                cs = getCharset(encoding);
+            } catch (UnsupportedEncodingException e) {
+                throw new XMLStreamException(e);
+            }
+
+            this._encoding = encoding;
+        }
+
+        _writer = new XMLWriter(os, encoding, cs);
+    }
+
+    /**
+     * Write the XML Declaration. Defaults the XML version to 1.0, and the
+     * encoding to utf-8.
+     *
+     * @throws XMLStreamException
+     */
+    public void writeStartDocument() throws XMLStreamException {
+        writeStartDocument(_encoding, XMLStreamWriter.DEFAULT_XML_VERSION);
+    }
+
+    /**
+     * Write the XML Declaration. Defaults the encoding to utf-8
+     *
+     * @param version version of the xml document
+     * @throws XMLStreamException
+     */
+    public void writeStartDocument(String version) throws XMLStreamException {
+        writeStartDocument(_encoding, version, null);
+    }
+
+    /**
+     * Write the XML Declaration. Note that the encoding parameter does not set
+     * the actual encoding of the underlying output. That must be set when the
+     * instance of the XMLStreamWriter is created
+     *
+     * @param encoding encoding of the xml declaration
+     * @param version version of the xml document
+     * @throws XMLStreamException If given encoding does not match encoding of the
+     * underlying stream
+     */
+    public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+        writeStartDocument(encoding, version, null);
+    }
+
+    /**
+     * Write the XML Declaration. Note that the encoding parameter does not set
+     * the actual encoding of the underlying output. That must be set when the
+     * instance of the XMLStreamWriter is created
+     *
+     * @param encoding encoding of the xml declaration
+     * @param version version of the xml document
+     * @param standalone indicate if the xml document is standalone
+     * @throws XMLStreamException If given encoding does not match encoding of the
+     * underlying stream
+     */
+    public void writeStartDocument(String encoding, String version, String standalone)
+        throws XMLStreamException
+    {
+        if (_state > 0) {
+            throw new XMLStreamException("XML declaration must be as the first line in the XML document.");
+        }
+        _state = STATE_XML_DECL;
+        String enc = encoding;
+        if (enc == null) {
+            enc = _encoding;
+        } else {
+            //check if the encoding is supported
+            try {
+                getCharset(encoding);
+            } catch (UnsupportedEncodingException e) {
+                throw new XMLStreamException(e);
+            }
+        }
+
+        if (version == null) {
+            version = XMLStreamWriter.DEFAULT_XML_VERSION;
+        }
+
+        _writer.write("<?xml version=\"");
+        _writer.write(version);
+        _writer.write(DOUBLEQUOT);
+
+        if (enc != null) {
+            _writer.write(" encoding=\"");
+            _writer.write(enc);
+            _writer.write(DOUBLEQUOT);
+        }
+
+        if (standalone != null) {
+            _writer.write(" standalone=\"");
+            _writer.write(standalone);
+            _writer.write(DOUBLEQUOT);
+        }
+        _writer.write("?>");
+        writeLineSeparator();
+    }
+
+    /**
+     * Write a DTD section.  This string represents the entire doctypedecl production
+     * from the XML 1.0 specification.
+     *
+     * @param dtd the DTD to be written
+     * @throws XMLStreamException
+     */
+    public void writeDTD(String dtd) throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+        _writer.write(dtd);
+        writeLineSeparator();
+    }
+
+    /**
+     * Writes a start tag to the output.
+     * @param localName local name of the tag, may not be null
+     * @throws XMLStreamException
+     */
+    public void writeStartElement(String localName) throws XMLStreamException {
+        if (localName == null || localName.length() == 0) {
+            throw new XMLStreamException("Local Name cannot be null or empty");
+        }
+
+        _state = STATE_ELEMENT;
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        _currentEle = new Element(_currentEle, localName, false);
+        openStartTag();
+
+        _writer.write(localName);
+    }
+
+    /**
+     * Writes an empty element tag to the output
+     * @param localName local name of the tag, may not be null
+     * @throws XMLStreamException
+     */
+    public void writeEmptyElement(String localName) throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        _currentEle = new Element(_currentEle, localName, true);
+
+        openStartTag();
+        _writer.write(localName);
+    }
+
+    /**
+     * Writes an attribute to the output stream without a prefix.
+     * @param localName the local name of the attribute
+     * @param value the value of the attribute
+     * @throws IllegalStateException if the current state does not allow Attribute writing
+     * @throws XMLStreamException
+     */
+    public void writeAttribute(String localName, String value) throws XMLStreamException {
+        if (_currentEle.getState() != ELEMENT_STARTTAG_OPEN) {
+            throw new XMLStreamException(
+                    "Attribute not associated with any element");
+        }
+
+        _writer.write(SPACE);
+        _writer.write(localName);
+        _writer.write("=\"");
+        writeXMLContent(
+                value,
+                true, // true = escapeChars
+                true);  // true = escapeDoubleQuotes
+        _writer.write(DOUBLEQUOT);
+    }
+
+    public void writeEndDocument() throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        /**
+         * close unclosed elements if any
+         */
+        while (_currentEle != null) {
+
+            if (!_currentEle.isEmpty()) {
+                _writer.write(OPEN_END_TAG);
+                _writer.write(_currentEle.getLocalName());
+                _writer.write(CLOSE_END_TAG);
+            }
+
+            _currentEle = _currentEle.getParent();
+        }
+    }
+
+    public void writeEndElement() throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        if (_currentEle == null) {
+            throw new XMLStreamException("No element was found to write");
+        }
+
+        if (_currentEle.isEmpty()) {
+            return;
+        }
+
+        _writer.write(OPEN_END_TAG);
+        _writer.write(_currentEle.getLocalName());
+        _writer.write(CLOSE_END_TAG);
+        writeLineSeparator();
+
+        _currentEle = _currentEle.getParent();
+    }
+
+    public void writeCData(String cdata) throws XMLStreamException {
+        if (cdata == null) {
+            throw new XMLStreamException("cdata cannot be null");
+        }
+
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        _writer.write(START_CDATA);
+        _writer.write(cdata);
+        _writer.write(END_CDATA);
+    }
+
+    public void writeCharacters(String data) throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        writeXMLContent(data);
+    }
+
+    public void writeCharacters(char[] data, int start, int len)
+            throws XMLStreamException {
+        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
+            closeStartTag();
+        }
+
+        writeXMLContent(data, start, len, _escapeCharacters);
+    }
+
+    /**
+     * Close this XMLStreamWriter by closing underlying writer.
+     */
+    public void close() throws XMLStreamException {
+        if (_writer != null) {
+            _writer.close();
+        }
+        _writer = null;
+        _currentEle = null;
+        _state = 0;
+    }
+
+    /**
+     * Flush this XMLStreamWriter by flushing underlying writer.
+     */
+    public void flush() throws XMLStreamException {
+        if (_writer != null) {
+            _writer.flush();
+        }
+    }
+
+    /**
+     * Set the flag to indicate if the writer should add line separator
+     * @param doIndent
+     */
+    public void setDoIndent(boolean doIndent) {
+        _doIndent = doIndent;
+    }
+
+    /**
+     * Writes XML content to underlying writer. Escapes characters unless
+     * escaping character feature is turned off.
+     */
+    private void writeXMLContent(char[] content, int start, int length, boolean escapeChars)
+        throws XMLStreamException
+    {
+        if (!escapeChars) {
+            _writer.write(content, start, length);
+            return;
+        }
+
+        // Index of the next char to be written
+        int startWritePos = start;
+
+        final int end = start + length;
+
+        for (int index = start; index < end; index++) {
+            char ch = content[index];
+
+            if (!_writer.canEncode(ch)) {
+                _writer.write(content, startWritePos, index - startWritePos);
+
+                // Escape this char as underlying encoder cannot handle it
+                _writer.write(ENCODING_PREFIX);
+                _writer.write(Integer.toHexString(ch));
+                _writer.write(SEMICOLON);
+                startWritePos = index + 1;
+                continue;
+            }
+
+            switch (ch) {
+                case OPEN_START_TAG:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&lt;");
+                    startWritePos = index + 1;
+
+                    break;
+
+                case AMPERSAND:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&amp;");
+                    startWritePos = index + 1;
+
+                    break;
+
+                case CLOSE_START_TAG:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&gt;");
+                    startWritePos = index + 1;
+
+                    break;
+            }
+        }
+
+        // Write any pending data
+        _writer.write(content, startWritePos, end - startWritePos);
+    }
+
+    private void writeXMLContent(String content) throws XMLStreamException {
+        if ((content != null) && (content.length() > 0)) {
+            writeXMLContent(content,
+                    _escapeCharacters, // boolean = escapeChars
+                    false);             // false = escapeDoubleQuotes
+        }
+    }
+
+    /**
+     * Writes XML content to underlying writer. Escapes characters unless
+     * escaping character feature is turned off.
+     */
+    private void writeXMLContent(
+            String content,
+            boolean escapeChars,
+            boolean escapeDoubleQuotes)
+        throws XMLStreamException
+    {
+
+        if (!escapeChars) {
+            _writer.write(content);
+
+            return;
+        }
+
+        // Index of the next char to be written
+        int startWritePos = 0;
+
+        final int end = content.length();
+
+        for (int index = 0; index < end; index++) {
+            char ch = content.charAt(index);
+
+            if (!_writer.canEncode(ch)) {
+                _writer.write(content, startWritePos, index - startWritePos);
+
+                // Escape this char as underlying encoder cannot handle it
+                _writer.write(ENCODING_PREFIX);
+                _writer.write(Integer.toHexString(ch));
+                _writer.write(SEMICOLON);
+                startWritePos = index + 1;
+                continue;
+            }
+
+            switch (ch) {
+                case OPEN_START_TAG:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&lt;");
+                    startWritePos = index + 1;
+
+                    break;
+
+                case AMPERSAND:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&amp;");
+                    startWritePos = index + 1;
+
+                    break;
+
+                case CLOSE_START_TAG:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    _writer.write("&gt;");
+                    startWritePos = index + 1;
+
+                    break;
+
+                case DOUBLEQUOT:
+                    _writer.write(content, startWritePos, index - startWritePos);
+                    if (escapeDoubleQuotes) {
+                        _writer.write("&quot;");
+                    } else {
+                        _writer.write(DOUBLEQUOT);
+                    }
+                    startWritePos = index + 1;
+
+                    break;
+            }
+        }
+
+        // Write any pending data
+        _writer.write(content, startWritePos, end - startWritePos);
+    }
+
+    /**
+     * marks open of start tag and writes the same into the writer.
+     */
+    private void openStartTag() throws XMLStreamException {
+        _currentEle.setState(ELEMENT_STARTTAG_OPEN);
+        _writer.write(OPEN_START_TAG);
+    }
+
+    /**
+     * marks close of start tag and writes the same into the writer.
+     */
+    private void closeStartTag() throws XMLStreamException {
+        if (_currentEle.isEmpty()) {
+            _writer.write(CLOSE_EMPTY_ELEMENT);
+        } else {
+            _writer.write(CLOSE_START_TAG);
+
+        }
+
+        if (_currentEle.getParent() == null) {
+            writeLineSeparator();
+        }
+
+        _currentEle.setState(ELEMENT_STARTTAG_CLOSE);
+
+    }
+
+    /**
+     * Write a line separator
+     * @throws XMLStreamException
+     */
+    private void writeLineSeparator() throws XMLStreamException {
+        if (_doIndent) {
+            _writer.write(_lineSep, 0, _lineSep.length);
+        }
+    }
+
+    /**
+     * Returns a charset object for the specified encoding
+     * @param encoding
+     * @return a charset object
+     * @throws UnsupportedEncodingException if the encoding is not supported
+     */
+    private Charset getCharset(String encoding) throws UnsupportedEncodingException {
+        if (encoding.equalsIgnoreCase("UTF-32")) {
+            throw new UnsupportedEncodingException("The basic XMLWriter does "
+                    + "not support " + encoding);
+        }
+
+        Charset cs;
+        try {
+            cs = Charset.forName(encoding);
+        } catch (IllegalCharsetNameException | UnsupportedCharsetException ex) {
+            throw new UnsupportedEncodingException(encoding);
+        }
+        return cs;
+    }
+
+    /*
+     * Start of Internal classes.
+     *
+     */
+    protected class Element {
+
+        /**
+         * the parent element
+         */
+        protected Element _parent;
+        /**
+         * The size of the stack.
+         */
+        protected short _Depth;
+        /**
+         * indicate if an element is an empty one
+         */
+        boolean _isEmptyElement = false;
+        String _localpart;
+        int _state;
+
+        /**
+         * Default constructor.
+         */
+        public Element() {
+        }
+
+        /**
+         * @param parent the parent of the element
+         * @param localpart name of the element
+         * @param isEmpty indicate if the element is an empty one
+         */
+        public Element(Element parent, String localpart, boolean isEmpty) {
+            _parent = parent;
+            _localpart = localpart;
+            _isEmptyElement = isEmpty;
+        }
+
+        public Element getParent() {
+            return _parent;
+        }
+
+        public String getLocalName() {
+            return _localpart;
+        }
+
+        /**
+         * get the state of the element
+         */
+        public int getState() {
+            return _state;
+        }
+
+        /**
+         * Set the state of the element
+         *
+         * @param state the state of the element
+         */
+        public void setState(int state) {
+            _state = state;
+        }
+
+        public boolean isEmpty() {
+            return _isEmptyElement;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/internal/util/xml/impl/XMLWriter.java	Wed Dec 19 12:09:10 2012 +0000
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.xml.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import jdk.internal.util.xml.XMLStreamException;
+
+/**
+ *
+ * @author huizwang
+ */
+public class XMLWriter {
+
+    private Writer _writer;
+    /**
+     * In some cases, this charset encoder is used to determine if a char is
+     * encodable by underlying writer. For example, an 8-bit char from the
+     * extended ASCII set is not encodable by 7-bit ASCII encoder. Unencodable
+     * chars are escaped using XML numeric entities.
+     */
+    private CharsetEncoder _encoder = null;
+
+    public XMLWriter(OutputStream os, String encoding, Charset cs) throws XMLStreamException {
+        _encoder = cs.newEncoder();
+        try {
+            _writer = getWriter(os, encoding, cs);
+        } catch (UnsupportedEncodingException ex) {
+            throw new XMLStreamException(ex);
+        }
+
+    }
+
+    public boolean canEncode(char ch) {
+        if (_encoder == null) {
+            return false;
+        }
+        return (_encoder.canEncode(ch));
+    }
+
+    public void write(String s)
+            throws XMLStreamException {
+        try {
+            _writer.write(s.toCharArray());
+//            _writer.write(s.getBytes(Charset.forName(_encoding)));
+        } catch (IOException e) {
+            throw new XMLStreamException("I/O error", e);
+        }
+    }
+
+    public void write(String str, int off, int len)
+            throws XMLStreamException {
+        try {
+            _writer.write(str, off, len);
+        } catch (IOException e) {
+            throw new XMLStreamException("I/O error", e);
+        }
+
+    }
+
+    public void write(char[] cbuf, int off, int len)
+            throws XMLStreamException {
+        try {
+            _writer.write(cbuf, off, len);
+        } catch (IOException e) {
+            throw new XMLStreamException("I/O error", e);
+        }
+
+    }
+
+    void write(int b)
+            throws XMLStreamException {
+        try {
+            _writer.write(b);
+        } catch (IOException e) {
+            throw new XMLStreamException("I/O error", e);
+        }
+    }
+
+    void flush() throws XMLStreamException {
+        try {
+            _writer.flush();
+        } catch (IOException ex) {
+            throw new XMLStreamException(ex);
+        }
+    }
+
+    void close() throws XMLStreamException {
+        try {
+            _writer.close();
+        } catch (IOException ex) {
+            throw new XMLStreamException(ex);
+        }
+    }
+
+    private void nl() throws XMLStreamException {
+        String lineEnd = System.getProperty("line.separator");
+        try {
+            _writer.write(lineEnd);
+        } catch (IOException e) {
+            throw new XMLStreamException("I/O error", e);
+        }
+    }
+
+    /**
+     * Returns a writer for the specified encoding based on an output stream.
+     *
+     * @param output The output stream
+     * @param encoding The encoding
+     * @return A suitable writer
+     * @throws UnsupportedEncodingException There is no convertor to support
+     * this encoding
+     */
+    private Writer getWriter(OutputStream output, String encoding, Charset cs)
+        throws XMLStreamException, UnsupportedEncodingException
+    {
+        if (cs != null) {
+            return (new OutputStreamWriter(new BufferedOutputStream(output), cs));
+        }
+
+        return new OutputStreamWriter(new BufferedOutputStream(output), encoding);
+    }
+}