diff --git a/xml/src/main/java/javax/xml/XMLConstants.java b/xml/src/main/java/javax/xml/XMLConstants.java
new file mode 100644
index 0000000..88fcdad
--- /dev/null
+++ b/xml/src/main/java/javax/xml/XMLConstants.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml;
+
+/**
+ * Defines several standard constants that are often used during XML processing.
+ *  
+ * @since Android 1.0
+ */
+public class XMLConstants {
+
+    /**
+     * The default namespace prefix. Defined to be the empty string. 
+     */
+    public static final String DEFAULT_NS_PREFIX = "";
+
+    /**
+     * The SAX feature name for secure processing. Turning on this feature
+     * might result in a parser rejecting XML documents that are considered
+     * "insecure" (having a potential for DOS attacks, for example). The
+     * Android XML parsing implementation currently ignores this feature.  
+     */
+    public static final String FEATURE_SECURE_PROCESSING = 
+        "http://javax.xml.XMLConstants/feature/secure-processing";
+
+    /**
+     * The namespace URI for the case that no namespace is being used at all.
+     * Defined to be the empty string.
+     */
+    public static final String NULL_NS_URI = "";
+
+    /**
+     * The official Relax-NG namespace URI.
+     */
+    public static final String RELAXNG_NS_URI = 
+        "http://relaxng.org/ns/structure/1.0";
+
+    /**
+     * The official XSchema instance namespace URI, as defined by W3C.
+     */
+    public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = 
+        "http://www.w3.org/2001/XMLSchema-instance";
+
+    /**
+     * The official XSchema namespace URI, as defined by W3C.
+     */
+    public static final String W3C_XML_SCHEMA_NS_URI = 
+        "http://www.w3.org/2001/XMLSchema";
+
+    /**
+     * The official XPath datatype namespace URI, as defined by W3C.
+     */
+    public static final String W3C_XPATH_DATATYPE_NS_URI = 
+        "http://www.w3.org/2003/11/xpath-datatypes";
+
+    /**
+     * The official XML namespace attribute, as defined by W3C.
+     */
+    public static final String XMLNS_ATTRIBUTE = "xmlns";
+
+    /**
+     * The official XML namespace attribute URI, as defined by W3C.
+     */
+    public static final String XMLNS_ATTRIBUTE_NS_URI = 
+        "http://www.w3.org/2000/xmlns/";
+
+    /**
+     * The official XML DTD namespace URI, as defined by W3C.
+     */
+    public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
+
+    /**
+     * The official XML namespace prefix, as defined by W3C. 
+     */
+    public static final String XML_NS_PREFIX = "xml";
+
+    /**
+     * The official XML namespace URI, as defined by W3C. 
+     */
+    public static final String XML_NS_URI = 
+        "http://www.w3.org/XML/1998/namespace";
+
+}
diff --git a/xml/src/main/java/javax/xml/package.html b/xml/src/main/java/javax/xml/package.html
new file mode 100644
index 0000000..5a4621d
--- /dev/null
+++ b/xml/src/main/java/javax/xml/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      Provides a utility class with useful XML constants.
+    </p>
+    @since Android 1.0
+  </body>
+</html>
\ No newline at end of file
diff --git a/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java b/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java
new file mode 100644
index 0000000..6fd6550
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Defines a bridge from XML sources (files, stream etc.) to DOM trees. Can be
+ * used for easily obtaining a {@link org.w3c.dom.Document} for the input. The
+ * class itself is abstract. The class {@link DocumentBuilderFactory} is able to
+ * provide instances (of concrete subclasses known to the system).
+ * 
+ * @since Android 1.0
+ */
+public abstract class DocumentBuilder {
+
+    /**
+     * Do-nothing constructor. Prevents instantiation. To be overridden by
+     * concrete subclasses.
+     * 
+     * @since Android 1.0
+     */
+    protected DocumentBuilder() {
+        // Does nothing.
+    }
+
+    /**
+     * Queries the DOM implementation this {@code DocumentBuilder} is working
+     * on.
+     * 
+     * @return the DOM implementation
+     * 
+     * @since Android 1.0
+     */
+    public abstract DOMImplementation getDOMImplementation();
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Queries the XML schema used by the DocumentBuilder.
+//     * 
+//     * @return The XML schema
+//     * 
+//     * @throws UnsupportedOperationException when the underlying implementation
+//     *         doesn't support XML schemas.
+//     */
+//    public javax.xml.validation.Schema getSchema() throws
+//            UnsupportedOperationException {
+//        throw new UnsupportedOperationException();
+//    }
+     
+    /**
+     * Queries whether the {@code DocumentBuilder} has namespace support
+     * enabled.
+     * 
+     * @return {@code true} if namespaces are turned on, {@code false}
+     *         otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public abstract boolean isNamespaceAware();
+
+    /**
+     * Queries whether the {@code DocumentBuilder} has validation support
+     * enabled.
+     * 
+     * @return {@code true} if validation is turned on, {@code false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public abstract boolean isValidating();
+
+    /**
+     * Queries whether the {@code DocumentBuilder} has XInclude support enabled.
+     * 
+     * @return {@code true} if XInclude support is turned on, {@code false}
+     *         otherwise.
+     * 
+     * @throws UnsupportedOperationException if the underlying implementation
+     *         doesn't support XInclude.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isXIncludeAware() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Creates a new, empty document, serving as the starting point for a DOM
+     * tree.
+     * 
+     * @return the document.
+     * 
+     * @since Android 1.0
+     */
+    public abstract Document newDocument();
+
+    /**
+     * Parses a given XML file and builds a DOM tree from it.
+     * 
+     * @param file the file to be parsed.
+     * @return the document element that represents the root of the DOM tree.
+     * 
+     * @throws SAXException if the XML parsing fails.
+     * @throws IOException if an input/output error occurs.
+     * 
+     * @since Android 1.0
+     */
+    public Document parse(File file) throws SAXException, IOException {
+        if (file == null) {
+            throw new IllegalArgumentException();
+        }
+        
+        return parse(new BufferedInputStream(new FileInputStream(file), 8192));
+    }
+
+    /**
+     * Parses a given XML input stream and builds a DOM tree from it.
+     * 
+     * @param stream the stream to be parsed.
+     * @return the document element that represents the root of the DOM tree.
+     * 
+     * @throws SAXException if the XML parsing fails.
+     * @throws IOException if an input/output error occurs.
+     * 
+     * @since Android 1.0
+     */
+    public Document parse(InputStream stream) throws SAXException, IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException();
+        }
+        
+        return parse(new InputSource(stream));
+    }
+
+    /**
+     * Parses a given XML input stream and builds a DOM tree from it.
+     * 
+     * @param stream the stream to be parsed.
+     * @param systemId the base for resolving relative URIs.
+     * @return the document element that represents the root of the DOM tree.
+     * 
+     * @throws SAXException if the XML parsing fails.
+     * @throws IOException if an input/output error occurs.
+     * 
+     * @since Android 1.0
+     */
+    public org.w3c.dom.Document parse(InputStream stream, String systemId)
+            throws SAXException, IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException();
+        }
+        
+        InputSource source = new InputSource(stream);
+        source.setSystemId(systemId);
+        return parse(source);
+    }
+
+    /**
+     * Parses an XML input stream from a given URI and builds a DOM tree from
+     * it.
+     * 
+     * @param uri the URI to fetch the XML stream from.
+     * @return the document element that represents the root of the DOM tree.
+     * 
+     * @throws SAXException if the XML parsing fails.
+     * @throws IOException if an input/output error occurs.
+     * 
+     * @since Android 1.0
+     */
+    public org.w3c.dom.Document parse(String uri) throws SAXException,
+            IOException {
+        if (uri == null) {
+            throw new IllegalArgumentException();
+        }
+        
+        return parse(new InputSource(uri));
+    }
+
+    /**
+     * Parses an XML input source and builds a DOM tree from it.
+     * 
+     * @param source the input source to parse.
+     * @return the document element that represents the root of the DOM tree.
+     * 
+     * @throws SAXException if the XML parsing fails.
+     * @throws IOException if an input/output error occurs.
+     * 
+     * @since Android 1.0
+     */
+    public abstract org.w3c.dom.Document parse(InputSource source)
+            throws SAXException, IOException;
+
+    /**
+     * Resets the DocumentBuilder to the same state is was in after its
+     * creation.
+     * 
+     * @since Android 1.0
+     */
+    public void reset() {
+        // Do nothing.
+    }
+
+    /**
+     * Sets the {@link EntityResolver} used for resolving entities encountered
+     * during the parse process. Passing {@code null} results in the
+     * {@code DocumentBuilder}'s own {@code EntityResolver} being used.
+     * 
+     * @param resolver the {@code EntityResolver} to use, or null for the
+     *        built-in one.
+     * 
+     * @since Android 1.0
+     */
+    public abstract void setEntityResolver(EntityResolver resolver);
+
+    /**
+     * Sets the {@link ErrorHandler} used for dealing with errors encountered
+     * during the parse process. Passing {@code null} results in the
+     * {@code DocumentBuilder}'s own {@code ErrorHandler} being used.
+     * 
+     * @param handler the {@code ErrorHandler} to use, or {@code null} for the
+     *        built-in one.
+     * 
+     * @since Android 1.0
+     */
+    public abstract void setErrorHandler(ErrorHandler handler);
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java b/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java
new file mode 100644
index 0000000..4e186c1
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+import org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl;
+
+/**
+ * Provides a factory for {@link DocumentBuilder} instances. The class first
+ * needs to be instantiated using the {@link #newInstance()} method. The
+ * instance can be configured as desired. A call to
+ * {@link #newDocumentBuilder()} then provides a {@code DocumentBuilder}
+ * instance matching this configuration (if possible).
+ * 
+ * @since Android 1.0
+ */
+public abstract class DocumentBuilderFactory extends Object {
+
+    private boolean coalesce;
+
+    private boolean expandEntityReferences;
+
+    private boolean ignoreComments;
+
+    private boolean ignoreElementContentWhitespace;
+
+    private boolean namespaceAware;
+
+    private boolean validate;
+
+    /**
+     * Do-nothing constructor. To be overridden by concrete document builders.
+     * 
+     * @since Android 1.0
+     */
+    protected DocumentBuilderFactory() {
+        // Does nothing.
+    }
+
+    /**
+     * Queries an attribute from the underlying implementation.
+     * 
+     * @param name the name of the attribute.
+     * @return the value of the attribute.
+     * 
+     * @throws IllegalArgumentException if the argument is unknown to the
+     *         underlying implementation.
+     * 
+     * @since Android 1.0
+     */
+    public abstract Object getAttribute(String name)
+            throws IllegalArgumentException;
+
+    /**
+     * Queries a feature from the underlying implementation.
+     * 
+     * @param name The name of the feature. The default Android implementation
+     *             of {@link DocumentBuilder} supports only the following three
+     *             features:
+     *             
+     *             <dl>
+     *               <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+     *               <dd>Queries the state of namespace-awareness.</dd>
+     *               
+     *               <dt>
+     *                 {@code http://xml.org/sax/features/namespace-prefixes}
+     *               </dt>
+     *               <dd>Queries the state of namespace prefix processing</dd>
+     *
+     *               <dt>
+     *                 {@code http://xml.org/sax/features/validation}
+     *               </dt>
+     *               <dd>Queries the state of validation.</dd>
+     *             </dl>
+     *             
+     *             Note that despite the ability to query the validation
+     *             feature, there is currently no validating parser available.
+     *             Also note that currently either namespaces or 
+     *             namespace prefixes can be enabled, but not both at the same 
+     *             time.
+     * 
+     * @return the status of the feature.
+     * 
+     * @throws IllegalArgumentException if the feature is unknown to
+     *         the underlying implementation.
+     * @throws ParserConfigurationException if the feature is
+     *         known, but not supported.
+     * 
+     * @since Android 1.0
+     */
+    public abstract boolean getFeature(String name)
+            throws ParserConfigurationException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Queries the desired XML Schema object.
+//     * 
+//     * @return The XML Schema object, if it has been set by a call to setSchema,
+//     *         or null otherwise.
+//     */
+//    public javax.xml.validation.Schema getSchema() {
+//        return schema;
+//    }
+    
+    /**
+     * Queries whether the factory is configured to deliver parsers that convert
+     * CDATA nodes to text nodes and melt them with neighboring nodes. This is
+     * called "coalescing".
+     * 
+     * @return {@code true} if coalescing is desired, {@code false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isCoalescing() {
+        return coalesce;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that expand
+     * entity references.
+     * 
+     * @return {@code true} if entity expansion is desired, {@code false}
+     * otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isExpandEntityReferences() {
+        return expandEntityReferences;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that ignore
+     * comments.
+     * 
+     * @return {@code true} if comment ignorance is desired, {@code false}
+     * otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isIgnoringComments() {
+        return ignoreComments;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that ignore
+     * whitespace in elements.
+     * 
+     * @return {@code true} if whitespace ignorance is desired, {@code false}
+     * otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isIgnoringElementContentWhitespace() {
+        return ignoreElementContentWhitespace;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * namespace-aware.
+     * 
+     * @return {@code true} if namespace-awareness is desired, {@code false}
+     * otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isNamespaceAware() {
+        return namespaceAware;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * validating.
+     * 
+     * @return {@code true} if validating is desired, {@code false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isValidating() {
+        return validate;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * XInclude-aware.
+     * 
+     * @return {@code true} if XInclude-awareness is desired, {@code false}
+     * otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isXIncludeAware() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Creates a new {@link DocumentBuilder} that matches the current
+     * configuration of the factory.
+     * 
+     * @return the DocumentBuilder.
+     * @throws ParserConfigurationException if no matching
+     *         {@code DocumentBuilder} could be found.
+     * 
+     * @since Android 1.0
+     */
+    public abstract DocumentBuilder newDocumentBuilder()
+            throws ParserConfigurationException;
+
+    /**
+     * Creates a new DocumentBuilderFactory that can be configured and then be
+     * used for creating DocumentBuilder objects. The method first checks the
+     * value of the {@code DocumentBuilderFactory} property.
+     * If this is non-{@code null}, it is assumed to be the name of a class
+     * that serves as the factory. The class is instantiated, and the instance
+     * is returned. If the property value is {@code null}, the system's default
+     * factory implementation is returned.
+     * 
+     * @return the DocumentBuilderFactory.
+     * @throws FactoryConfigurationError if no {@code DocumentBuilderFactory}
+     *         can be created.
+     * 
+     * @since Android 1.0
+     */
+    public static DocumentBuilderFactory newInstance()
+            throws FactoryConfigurationError {
+        // TODO Properties file and META-INF case missing here. See spec.
+        String factory = System
+                .getProperty("javax.xml.parsers.DocumentBuilderFactory");
+        if (factory != null) {
+            try {
+                return (DocumentBuilderFactory) Class.forName(factory)
+                        .newInstance();
+            } catch (Exception ex) {
+                // Ignore.
+            }
+        }
+
+        try {
+            return new DocumentBuilderFactoryImpl();
+        } catch (Exception ex) {
+            // Ignore.
+        }
+
+        throw new FactoryConfigurationError(
+                "Cannot create DocumentBuilderFactory");
+    }
+
+    /**
+     * Sets an attribute in the underlying implementation.
+     * 
+     * @param name the name of the attribute.
+     * @param value the value of the attribute.
+     * 
+     * @throws IllegalArgumentException if the argument is unknown to the
+     *         underlying implementation.
+     * 
+     * @since Android 1.0
+     */
+    public abstract void setAttribute(String name, Object value)
+            throws IllegalArgumentException;
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that
+     * convert CDATA nodes to text nodes and melt them with neighboring nodes.
+     * This is called "coalescing".
+     * 
+     * @param value turns coalescing on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setCoalescing(boolean value) {
+        coalesce = value;
+    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that
+     * expands entity references.
+     * 
+     * @param value turns entity reference expansion on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setExpandEntityReferences(boolean value) {
+        expandEntityReferences = value;
+    }
+
+    /**
+     * Sets a feature in the underlying implementation.
+     * 
+     * @param name the name of the feature. The default Android implementation
+     *             of {@link DocumentBuilder} supports only the following three
+     *             features:
+     *             
+     *             <dl>
+     *               <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+     *               <dd>Sets the state of namespace-awareness.</dd>
+     *               
+     *               <dt>
+     *                 {@code http://xml.org/sax/features/namespace-prefixes}
+     *               </dt>
+     *               <dd>Sets the state of namespace prefix processing</dd>
+     *
+     *               <dt>{@code http://xml.org/sax/features/validation}</dt>
+     *               <dd>Sets the state of validation.</dd>
+     *             </dl>
+     *             
+     *             Note that despite the ability to set the validation
+     *             feature, there is currently no validating parser available.
+     *             Also note that currently either namespaces or
+     *             namespace prefixes can be enabled, but not both at the same
+     *             time.
+     * 
+     * @param value the value of the feature.
+     * 
+     * @throws ParserConfigurationException if the feature is unknown to the
+     *         underlying implementation.
+     * 
+     * @since Android 1.0
+     */
+    public abstract void setFeature(String name, boolean value)
+            throws ParserConfigurationException;
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that
+     * ignore comments.
+     * 
+     * @param value turns comment ignorance on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setIgnoringComments(boolean value) {
+        ignoreComments = value;
+    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that
+     * ignores element whitespace.
+     * 
+     * @param value turns element whitespace ignorance on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setIgnoringElementContentWhitespace(boolean value) {
+        ignoreElementContentWhitespace = value;
+    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * namespace-aware.
+     * 
+     * @param value turns namespace-awareness on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setNamespaceAware(boolean value) {
+        namespaceAware = value;
+    }
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Sets the desired XML Schema object.
+//     * 
+//     * @param schema The XML Schema object.
+//     */
+//    public void setSchema(Schema schema) {
+//        this.schema = schema;
+//    }
+    
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * validating.
+     * 
+     * @param value turns validation on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setValidating(boolean value) {
+        validate = value;
+    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * XInclude-aware.
+     * 
+     * @param value turns XInclude-awareness on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setXIncludeAware(boolean value) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java b/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java
new file mode 100644
index 0000000..f5e0c03
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+/**
+ * Represents an error that occurred during the configuration of parser factory.
+ * 
+ * @since Android 1.0
+ */
+public class FactoryConfigurationError extends Error {
+
+    /**
+     * The nested exception that caused this exception. Note that the nested
+     * exception will be stored in a special attribute, and can be queried using
+     * the {@link #getException()} method. It does not use the facility the
+     * {@link Exception} class provides for storing nested exceptions, since the
+     * XML API predates that facility.
+     */
+    private Exception cause;
+    
+    /**
+     * Creates a new {@code FactoryConfigurationError} with no error message and
+     * no cause.
+     * 
+     * @since Android 1.0
+     */
+    public FactoryConfigurationError() {
+        super();
+    }
+
+    /**
+     * Creates a new {@code FactoryConfigurationError} with no error message and
+     * a given cause.
+     * 
+     * @param cause the cause of the error. Note that the nested exception will
+     *        be stored in a special attribute, and can be queried using the
+     *        {@link #getException()} method. It does not use the facility the
+     *        Exception class provides for storing nested exceptions, since the
+     *        XML API predates that facility.
+     * 
+     * @since Android 1.0
+     */
+    public FactoryConfigurationError(Exception cause) {
+        super();
+        this.cause = cause;
+    }
+
+    /**
+     * Creates a new {@code FactoryConfigurationError} with a given error
+     * message and cause.
+     * 
+     * @param cause the cause of the error. Note that the nested exception will
+     *        be stored in a special attribute, and can be queried using the
+     *        {@link #getException()} method. It does not use the facility the
+     *        {@link Exception} class provides for storing nested exceptions,
+     *        since the XML API predates that facility.
+     * @param message The error message.
+     * 
+     * @since Android 1.0
+     */
+    public FactoryConfigurationError(Exception cause, String message) {
+        super(message);
+        this.cause = cause;
+    }
+
+    /**
+     * Creates a new {@code FactoryConfigurationError} with a given error
+     * message and no cause.
+     * 
+     * @param message the error message.
+     * 
+     * @since Android 1.0
+     */
+    public FactoryConfigurationError(String message) {
+        super(message);
+    }
+
+    /**
+     * Returns the cause of the error, in case there is one.
+     * 
+     * @return the exception that caused the error, or {@code null} if none is
+     *         set.
+     * 
+     * @since Android 1.0
+     */
+    public Exception getException() {
+        return cause;
+    }
+
+    /**
+     * Returns the message of the error, in case there is one.
+     * 
+     * @return the message. If an explicit error message has been assigned to
+     *         the exception, this one is returned. If not, and there is an
+     *         underlying exception (the cause), then the result of invoking
+     *         {@link #toString()} on that object is returned. Otherwise, {@code
+     *         null} is returned.
+     * 
+     * @since Android 1.0
+     */
+    public String getMessage() {
+        String message = super.getMessage();
+
+        if (message != null) {
+            return message;
+        } else if (cause != null) {
+            return cause.toString();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java b/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java
new file mode 100644
index 0000000..49875d6
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+/**
+ * Represents an exception that occurred during the configuration of parser.
+ * 
+ * @since Android 1.0
+ */
+public class ParserConfigurationException extends Exception {
+
+    /**
+     * Creates a new {@code ParserConfigurationException} with no error message.
+     * 
+     * @since Android 1.0
+     */
+    public ParserConfigurationException() {
+        super();
+    }
+
+    /**
+     * Creates a new {@code ParserConfigurationException} with a given error
+     * message.
+     * 
+     * @param msg the error message.
+     * 
+     * @since Android 1.0
+     */
+    public ParserConfigurationException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/SAXParser.java b/xml/src/main/java/javax/xml/parsers/SAXParser.java
new file mode 100644
index 0000000..73cc0eb
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/SAXParser.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Provides a wrapper around a SAX {@link XMLReader}. This abstract
+ * class only defines the interface, whereas the {@link SAXParserFactory} class
+ * is used to obtain instances of concrete subclasses.
+ * 
+ * @since Android 1.0
+ */
+public abstract class SAXParser extends java.lang.Object {
+
+    /**
+     * Do-nothing constructor. Prevents instantiation. To be overridden by
+     * concrete subclasses.
+     * 
+     * @since Android 1.0
+     */
+    protected SAXParser() {
+        // Does nothing.
+    }
+
+    /**
+     * Queries the underlying SAX {@link Parser} object.
+     * 
+     * @return the SAX {@code Parser}.
+     * 
+     * @throws SAXException if a problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public abstract Parser getParser()
+            throws SAXException;
+
+    /**
+     * Queries a property of the underlying SAX {@link XMLReader}.
+     * 
+     * @param name the name of the property.
+     * @return the value of the property.
+     * 
+     * @throws SAXNotRecognizedException if the property is not known to the
+     *         underlying SAX {@code XMLReader}.
+     * @throws SAXNotSupportedException if the property is known, but not
+     *         supported by the underlying SAX {@code XMLReader}.
+     * 
+     * @since Android 1.0
+     */
+    public abstract Object getProperty(String name)
+            throws SAXNotRecognizedException, SAXNotSupportedException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Queries the XML Schema used by the underlying XMLReader.
+//     * 
+//     * @return The XML Schema.
+//     */
+//    public Schema getSchema() {
+//        return schema;
+//    }
+    
+    /**
+     * Queries the underlying SAX XMLReader object.
+     * 
+     * @return the SAX XMLREader.
+     * 
+     * @throws SAXException if a problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public abstract XMLReader getXMLReader() throws SAXException;
+
+    /**
+     * Reflects whether this {@code SAXParser} is namespace-aware.
+     * 
+     * @return {@code true} if the {@code SAXParser} is namespace-aware, or
+     * {@code false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public abstract boolean isNamespaceAware();
+
+    /**
+     * Reflects whether this {@code SAXParser} is validating.
+     * 
+     * @return {@code true} if the {@code SAXParser} is validating, or {@code
+     * false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public abstract boolean isValidating();
+
+    /**
+     * Reflects whether this {@code SAXParser} is XInclude-aware.
+     * 
+     * @return {@code true} if the {@code SAXParser} is XInclude-aware, or
+     *         {@code false} otherwise.
+     * 
+     * @throws UnsupportedOperationException if the underlying implementation
+     *         doesn't know about XInclude at all (backwards compatibility).
+     * 
+     * @since Android 1.0
+     */
+    public boolean isXIncludeAware() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Parses the given XML file using the given SAX event handler.
+     * 
+     * @param file the file containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(File file, HandlerBase handler) throws SAXException,
+            IOException {
+        if (file == null) {
+            throw new IllegalArgumentException("file must not be null");
+        }
+        if (file.isDirectory()) {
+            throw new IllegalArgumentException("file must not be a directory");
+        }
+        InputSource source = new InputSource("file:" + file.getAbsolutePath());
+        parse(source, handler);
+    }
+
+    /**
+     * Parses the given XML file using the given SAX event handler.
+     * 
+     * @param file the file containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(File file, DefaultHandler handler) throws SAXException,
+            IOException {
+        if (file == null) {
+            throw new IllegalArgumentException("file must not be null");
+        }
+        if (file.isDirectory()) {
+            throw new IllegalArgumentException("file must not be a directory");
+        }
+        InputSource source = new InputSource("file:" + file.getAbsolutePath());
+        parse(source, handler);
+    }
+
+    /**
+     * Parses the given XML InputStream using the given SAX event handler.
+     * 
+     * @param stream the InputStream containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputStream stream, HandlerBase handler)
+            throws SAXException, IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream must not be null");
+        }
+        parse(new InputSource(stream), handler);
+    }
+
+    /**
+     * Parses the given XML InputStream using the given SAX event handler and
+     * system ID.
+     * 
+     * @param stream the InputStream containing the XML document.
+     * @param handler the SAX handler.
+     * @param systemId the system ID.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputStream stream, HandlerBase handler, String systemId)
+            throws SAXException, IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream must not be null");
+        }
+        InputSource source = new InputSource(stream);
+        if (systemId != null) {
+            source.setSystemId(systemId);
+        }
+        parse(source, handler);
+    }
+
+    /**
+     * Parses the given XML InputStream using the given SAX event handler.
+     * 
+     * @param stream the InputStream containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputStream stream, DefaultHandler handler)
+            throws SAXException, IOException {
+        parse(new InputSource(stream), handler);
+    }
+
+    /**
+     * Parses the given XML InputStream using the given SAX event handler and
+     * system ID.
+     * 
+     * @param stream the InputStream containing the XML document.
+     * @param handler the SAX handler.
+     * @param systemId the system ID.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputStream stream, DefaultHandler handler,
+            String systemId) throws SAXException, IOException {
+        if (stream  == null) {
+            throw new IllegalArgumentException("stream must not be null");
+        }
+        InputSource source = new InputSource(stream);
+        if (systemId != null) {
+            source.setSystemId(systemId);
+        }
+        parse(source, handler);
+    }
+
+    /**
+     * Parses the contents of the given URI using the given SAX event handler.
+     * 
+     * @param uri the URI pointing to the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(String uri, HandlerBase handler) throws SAXException,
+            IOException {
+        if (uri == null) {
+            throw new IllegalArgumentException("uri must not be null");
+        }
+        parse(new InputSource(uri), handler);
+    }
+
+    /**
+     * Parses the contents of the given URI using the given SAX event handler.
+     * 
+     * @param uri the URI pointing to the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(String uri, DefaultHandler handler) throws SAXException,
+            IOException {
+        if (uri == null) {
+            throw new IllegalArgumentException("uri must not be null");
+        }
+        parse(new InputSource(uri), handler);
+    }
+
+    /**
+     * Parses the given SAX {@link InputSource} using the given SAX event
+     * handler.
+     * 
+     * @param source the SAX {@code InputSource} containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputSource source, HandlerBase handler)
+            throws SAXException, IOException {
+        Parser parser = getParser();
+        if (source == null) {
+            throw new IllegalArgumentException("source must not be null");
+        }
+
+        if (handler != null) {
+            parser.setDocumentHandler(handler);
+            parser.setDTDHandler(handler);
+            parser.setEntityResolver(handler);
+            parser.setErrorHandler(handler);
+        }
+
+        parser.parse(source);
+    }
+
+    /**
+     * Parses the given SAX {@link InputSource} using the given SAX event
+     * handler.
+     * 
+     * @param source the SAX {@code InputSource} containing the XML document.
+     * @param handler the SAX handler.
+     * 
+     * @throws SAXException if a problem occurs during SAX parsing.
+     * @throws IOException if a general IO problem occurs.
+     * 
+     * @since Android 1.0
+     */
+    public void parse(InputSource source, DefaultHandler handler)
+            throws SAXException, IOException {
+        if (source == null) {
+            throw new IllegalArgumentException("source must not be null");
+        }
+        XMLReader reader = getXMLReader();
+
+        if (handler != null) {
+            reader.setContentHandler(handler);
+            reader.setDTDHandler(handler);
+            reader.setEntityResolver(handler);
+            reader.setErrorHandler(handler);
+        }
+
+        reader.parse(source);
+    }
+
+    /**
+     * Resets the {@code SAXParser} to the same state is was in after its
+     * creation.
+     * 
+     * @since Android 1.0
+     */
+    public void reset() {
+        // Do nothing.
+    }
+
+    /**
+     * Sets a property of the underlying SAX {@link XMLReader}.
+     * 
+     * @param name the name of the property.
+     * @param value the value of the property.
+     * 
+     * @throws SAXNotRecognizedException if the property is not known to the
+     *         underlying SAX {@code XMLReader}.
+     * @throws SAXNotSupportedException if the property is known, but not
+     *         supported by the underlying SAX {@code XMLReader}.
+     * 
+     * @since Android 1.0
+     */
+    public abstract void setProperty(String name, Object value)
+            throws SAXNotRecognizedException, SAXNotSupportedException;
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java b/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java
new file mode 100644
index 0000000..ebf0531
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.xml.parsers;
+
+import org.apache.harmony.xml.parsers.SAXParserFactoryImpl;
+
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXException;
+
+/**
+ * Provides a factory for {@link SAXParser} instances. The class first needs to
+ * be instantiated using the {@link #newInstance()} method. The instance can be
+ * configured as desired. A call to its {@link #newSAXParser()} then provides a
+ * {@code SAXParser} instance matching this configuration, if possible.
+ * 
+ * @since Android 1.0
+ */
+public abstract class SAXParserFactory {
+
+    private boolean namespaceAware;
+
+    private boolean validating;
+
+    private boolean xincludeAware;
+
+    /**
+     * Do-nothing constructor. Prevents instantiation. To be overridden by
+     * concrete subclasses.
+     * 
+     * @since Android 1.0
+     */
+    protected SAXParserFactory() {
+        // Does nothing.
+    }
+
+    /**
+     * Queries a feature from the underlying implementation.
+     * 
+     * @param name The name of the feature. The default Android implementation
+     *             of {@link SAXParser} supports only the following three
+     *             features:
+     *             
+     *             <dl>
+     *               <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+     *               <dd>Queries the state of namespace-awareness.</dd>
+     *               
+     *               <dt>
+     *                 {@code http://xml.org/sax/features/namespace-prefixes}
+     *               </dt>
+     *               <dd>Queries the state of namespace prefix processing</dd>
+     *
+     *               <dt>{@code http://xml.org/sax/features/validation}</dt>
+     *               <dd>Queries the state of validation.</dd>
+     *             </dl>
+     *             
+     *             Note that despite the ability to query the validation
+     *             feature, there is currently no validating parser available.
+     *             Also note that currently either namespaces or 
+     *             namespace prefixes can be enabled, but not both at the same 
+     *             time.
+     *             
+     * @return the status of the feature.
+     * 
+     * @throws ParserConfigurationException if no {@code SAXParser} matching the
+     *         given criteria is available.
+     * @throws SAXNotRecognizedException if the given feature is not known to
+     *         the underlying implementation.
+     * @throws SAXNotSupportedException if the given features is known, but not
+     *         supported by the underlying implementation.
+     *         
+     * @since Android 1.0
+     */
+    public abstract boolean getFeature(String name)
+            throws ParserConfigurationException, SAXNotRecognizedException,
+            SAXNotSupportedException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Queries the desired XML Schema object.
+//     * 
+//     * @return The XML Schema object, if it has been set by a call to setSchema,
+//     *         or null otherwise.
+//     */
+//    public javax.xml.validation.Schema getSchema() {
+//        return schema;
+//    }
+    
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * namespace-aware.
+     * 
+     * @return {@code true} if namespace-awareness is desired, {@code false}
+     *         otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isNamespaceAware() {
+        return namespaceAware;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * validating.
+     * 
+     * @return {@code true} if validating is desired, {@code false} otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isValidating() {
+        return validating;
+    }
+
+    /**
+     * Queries whether the factory is configured to deliver parsers that are
+     * XInclude-aware.
+     * 
+     * @return {@code true} if XInclude-awareness is desired, {@code false}
+     *         otherwise.
+     * 
+     * @since Android 1.0
+     */
+    public boolean isXIncludeAware() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Creates a new {@code SAXParserFactory} that can be configured and then be
+     * used for creating {@link SAXParser} objects. The method first checks the
+     * value of the {@code SAXParserFactory} property. If this
+     * is non-{@code null}, it is assumed to be the name of a class that serves
+     * as the factory. The class is instantiated, and the instance is returned.
+     * If the property value is {@code null}, the system's default factory
+     * implementation is returned. 
+     * 
+     * @return the {@code SAXParserFactory}.
+     * 
+     * @throws FactoryConfigurationError if no {@code SAXParserFactory} can be
+     *         created.
+     *         
+     * @since Android 1.0
+     */
+    public static SAXParserFactory newInstance()
+            throws FactoryConfigurationError {
+        // TODO Properties file and META-INF case missing here. See spec.
+        String factory = System
+                .getProperty("javax.xml.parsers.SAXParserFactory");
+        if (factory != null) {
+            try {
+                return (SAXParserFactory) Class.forName(factory).newInstance();
+            } catch (Exception ex) {
+                throw new FactoryConfigurationError(factory);
+            }
+        }
+
+        try {
+            return new SAXParserFactoryImpl();
+        } catch (Exception ex) {
+            // Ignore.
+        }
+
+        throw new FactoryConfigurationError("Cannot create SAXParserFactory");
+    }
+
+    /**
+     * Creates a new {@link SAXParser} that matches the current configuration of
+     * the factory.
+     * 
+     * @return the {@code SAXParser}.
+     * 
+     * @throws ParserConfigurationException if no matching {@code SAXParser}
+     *         could be found.
+     * @throws SAXException if creating the {@code SAXParser} failed due to some
+     *         other reason.
+     * 
+     * @since Android 1.0
+     */
+    public abstract SAXParser newSAXParser()
+            throws ParserConfigurationException, SAXException;
+
+    /**
+     * Sets a feature in the underlying implementation.
+     * 
+     * @param name the name of the feature. The default Android implementation
+     *             of {@link SAXParser} supports only the following three
+     *             features:
+     *             
+     *             <dl>
+     *               <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+     *               <dd>Sets the state of namespace-awareness.</dd>
+     *
+     *               <dt>
+     *                 {@code http://xml.org/sax/features/namespace-prefixes}
+     *               </dt>
+     *               <dd>Sets the state of namespace prefix processing</dd>
+     *
+     *               <dt>{@code http://xml.org/sax/features/validation}</dt>
+     *               <dd>Sets the state of validation.</dd>
+     *             </dl>
+     *             
+     *             Note that despite the ability to query the validation
+     *             feature, there is currently no validating parser available.
+     *             Also note that currently either namespaces or 
+     *             namespace prefixes can be enabled, but not both at the same 
+     *             time.
+     *             
+     * @param value the status of the feature.
+     * 
+     * @throws ParserConfigurationException if no {@code SAXParser} matching
+     *         the given criteria is available.
+     * @throws SAXNotRecognizedException if the given feature is not known to
+     *         the underlying implementation.
+     * @throws SAXNotSupportedException if the given features is known, but not
+     *         supported by the underlying implementation.
+     *         
+     * @since Android 1.0
+     */
+    public abstract void setFeature(String name, boolean value)
+            throws ParserConfigurationException, SAXNotRecognizedException,
+            SAXNotSupportedException;
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * namespace-aware.
+     * 
+     * @param value turns namespace-awareness on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setNamespaceAware(boolean value) {
+        namespaceAware = value;
+    }
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+//    /**
+//     * Sets the desired XML Schema object.
+//     * 
+//     * @param schema The XML Schema object.
+//     */
+//    public void setSchema(Schema schema) {
+//       this.schema = schema;
+//    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * validating.
+     * 
+     * @param value turns validation on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setValidating(boolean value) {
+        validating = value;
+    }
+
+    /**
+     * Determines whether the factory is configured to deliver parsers that are
+     * XInclude-aware.
+     * 
+     * @param value turns XInclude-awareness on or off.
+     * 
+     * @since Android 1.0
+     */
+    public void setXIncludeAware(boolean value) {
+        throw new UnsupportedOperationException();
+    }
+
+}
+
diff --git a/xml/src/main/java/javax/xml/parsers/package.html b/xml/src/main/java/javax/xml/parsers/package.html
new file mode 100644
index 0000000..7e0921d
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/package.html
@@ -0,0 +1,24 @@
+<html>
+  <body>
+    <p>
+      Provides facilities for parsing XML documents and building Document Object
+      Model (DOM) trees from them. The
+      {@link javax.xml.parsers.SAXParserFactory} class serves as an entry point
+      to event-based XML parsing. The
+      {@link javax.xml.parsers.DocumentBuilderFactory} class is an entry point
+      for dealing with DOM trees. Both factories are usually configured
+      before their factory methods are invoked. They then try to create a
+      {@link javax.xml.parsers.SAXParser} or a
+      {@link javax.xml.parsers.DocumentBuilder} (respectively) suiting the
+      application's needs. If none can be found, an Exception is thrown. 
+    </p>
+    <p>
+      Note that in order to cater for resource-constrained environments,
+      Android's XML packages currently only provide DOM Level 2 Core support
+      and a non-validating parser. This means that (a) the interface for the
+      various DOM classes might differ from other implementations and (b)
+      requesting a validating parser will always fail.
+    </p>
+    @since Android 1.0
+  </body>
+</html>
\ No newline at end of file
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java b/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
new file mode 100644
index 0000000..ed6cb11
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+
+/**
+ * Wraps native attribute array.
+ */
+abstract class ExpatAttributes implements Attributes {
+
+    /**
+     * Since we don't do validation, pretty much everything is CDATA type.
+     */
+    private static final String CDATA = "CDATA";
+
+    /**
+     * Gets the number of attributes.
+     */
+    public abstract int getLength();
+
+    /**
+     * Gets the pointer to the parser. We need this so we can get to the
+     * interned string pool.
+     */
+    abstract int getParserPointer();
+
+    /**
+     * Gets the pointer to the underlying attribute array. Can be 0 if the
+     * length is 0.
+     */
+    public abstract int getPointer();
+
+    public String getURI(int index) {
+        if (index < 0 || index >= getLength()) {
+            return null;
+        }
+        return getURI(getParserPointer(), getPointer(), index);
+    }
+
+    public String getLocalName(int index) {
+        return (index < 0 || index >= getLength())
+                ? null
+                : getLocalName(getParserPointer(), getPointer(), index);
+    }
+
+    public String getQName(int index) {
+        return (index < 0 || index >= getLength())
+                ? null
+                : getQName(getParserPointer(), getPointer(), index);
+    }
+
+    public String getType(int index) {
+        return (index < 0 || index >= getLength()) ? null : CDATA;
+    }
+
+    public String getValue(int index) {
+        return (index < 0 || index >= getLength())
+                ? null
+                : getValue(getPointer(), index);
+    }
+
+    public int getIndex(String uri, String localName) {
+        if (uri == null) {
+            throw new NullPointerException("uri");
+        }
+        if (localName == null) {
+            throw new NullPointerException("local name");
+        }
+        int pointer = getPointer();
+        if (pointer == 0) {
+            return -1;
+        }
+        return getIndex(pointer, uri, localName);
+    }
+
+    public int getIndex(String qName) {
+        if (qName == null) {
+            throw new NullPointerException("uri");
+        }
+        int pointer = getPointer();
+        if (pointer == 0) {
+            return -1;
+        }
+        return getIndex(pointer, qName);
+    }
+
+    public String getType(String uri, String localName) {
+        if (uri == null) {
+            throw new NullPointerException("uri");
+        }
+        if (localName == null) {
+            throw new NullPointerException("local name");
+        }
+        return getIndex(uri, localName) == -1 ? null : CDATA;
+    }
+
+    public String getType(String qName) {
+        return getIndex(qName) == -1 ? null : CDATA;
+    }
+
+    public String getValue(String uri, String localName) {
+        if (uri == null) {
+            throw new NullPointerException("uri");
+        }
+        if (localName == null) {
+            throw new NullPointerException("local name");
+        }
+        int pointer = getPointer();
+        if (pointer == 0) {
+            return null;
+        }
+        return getValue(pointer, uri, localName);
+    }
+
+    public String getValue(String qName) {
+        if (qName == null) {
+            throw new NullPointerException("qName");
+        }
+        int pointer = getPointer();
+        if (pointer == 0) {
+            return null;
+        }
+        return getValue(pointer, qName);
+    }
+
+    static native String getURI(int pointer, int attributePointer, int index);
+    static native String getLocalName(int pointer, int attributePointer,
+            int index);
+    static native String getQName(int pointer, int attributePointer,
+            int index);
+    static native String getValue(int attributePointer, int index);
+    static native int getIndex(int attributePointer, String uri,
+            String localName);
+    static native int getIndex(int attributePointer, String qName);
+    static native String getValue(int attributePointer,
+            String uri, String localName);
+    static native String getValue(int attributePointer, String qName);
+    static native void freeAttributes(int pointer);
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatException.java b/xml/src/main/java/org/apache/harmony/xml/ExpatException.java
new file mode 100644
index 0000000..da3db9d
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+/**
+ * Used internally to propogate Expat errors. We convert these exceptions into
+ * SAXParseExceptions before propogating them to the client.
+ */
+class ExpatException extends Exception {
+
+    public ExpatException(String message) {
+        super(message);
+    }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java b/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java
new file mode 100644
index 0000000..60d74b8
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.LexicalHandler;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URLConnection;
+import java.net.URL;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ * Adapts SAX API to the Expat native XML parser. Not intended for reuse
+ * across documents.
+ *
+ * @see org.apache.harmony.xml.ExpatPullParser
+ * @see org.apache.harmony.xml.ExpatReader
+ */
+class ExpatParser {
+
+    private static final int BUFFER_SIZE = 8096; // in bytes
+
+    /** Pointer to XML_Parser instance. */
+    private int pointer;
+
+    private boolean inStartElement = false;
+    private int attributeCount = -1;
+    private int attributePointer = 0;
+
+    private final Locator locator = new ExpatLocator();
+
+    private final ExpatReader xmlReader;
+
+    private final String publicId;
+    private final String systemId;
+
+    private final String encoding;
+
+    private final ExpatAttributes attributes = new CurrentAttributes();
+
+    private static final String OUTSIDE_START_ELEMENT
+            = "Attributes can only be used within the scope of startElement().";
+
+    /** We default to UTF-8 when the user doesn't specify an encoding. */
+    private static final String DEFAULT_ENCODING = "UTF-8";
+
+    /** Encoding used for Java chars, used to parse Readers and Strings */
+    /*package*/ static final String CHARACTER_ENCODING = "UTF-16";
+
+    /** Timeout for HTTP connections (in ms) */
+    private static final int TIMEOUT = 20 * 1000;
+
+    /**
+     * Constructs a new parser with the specified encoding.
+     */
+    /*package*/ ExpatParser(String encoding, ExpatReader xmlReader,
+            boolean processNamespaces, String publicId, String systemId) {
+        this.publicId = publicId;
+        this.systemId = systemId;
+
+        this.xmlReader = xmlReader;
+
+        /*
+         * TODO: Let Expat try to guess the encoding instead of defaulting.
+         * Unfortunately, I don't know how to tell which encoding Expat picked,
+         * so I won't know how to encode "<externalEntity>" below. The solution
+         * I think is to fix Expat to not require the "<externalEntity>"
+         * workaround.
+         */
+        this.encoding = encoding == null ? DEFAULT_ENCODING : encoding;
+        this.pointer = initialize(
+            this.encoding,
+            processNamespaces
+        );
+    }
+
+    /**
+     * Used by {@link EntityParser}.
+     */
+    private ExpatParser(String encoding, ExpatReader xmlReader, int pointer,
+            String publicId, String systemId) {
+        this.encoding = encoding;
+        this.xmlReader = xmlReader;
+        this.pointer = pointer;
+        this.systemId = systemId;
+        this.publicId = publicId;
+    }
+
+    /**
+     * Initializes native resources.
+     *
+     * @return the pointer to the native parser
+     */
+    private native int initialize(String encoding, boolean namespacesEnabled);
+
+    /**
+     * Called at the start of an element.
+     *
+     * @param uri namespace URI of element or "" if namespace processing is
+     *  disabled
+     * @param localName local name of element or "" if namespace processing is
+     *  disabled
+     * @param qName qualified name or "" if namespace processing is enabled
+     * @param attributePointer pointer to native attribute char*--we keep
+     *  a separate pointer so we can detach it from the parser instance
+     * @param attributeCount number of attributes
+     */
+    /*package*/ void startElement(String uri, String localName, String qName,
+            int attributePointer, int attributeCount) throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler == null) {
+            return;
+        }
+
+        try {
+            inStartElement = true;
+            this.attributePointer = attributePointer;
+            this.attributeCount = attributeCount;
+
+            contentHandler.startElement(
+                    uri, localName, qName, this.attributes);
+        }
+        finally {
+            inStartElement = false;
+            this.attributeCount = -1;
+            this.attributePointer = 0;
+        }
+    }
+
+    /*package*/ void endElement(String uri, String localName, String qName)
+            throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.endElement(uri, localName, qName);
+        }
+    }
+
+    /*package*/ void text(char[] text, int length) throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.characters(text, 0, length);
+        }
+    }
+
+    /*package*/ void comment(char[] text, int length) throws SAXException {
+        LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+        if (lexicalHandler != null) {
+            lexicalHandler.comment(text, 0, length);
+        }
+    }
+
+    /*package*/ void startCdata() throws SAXException {
+        LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+        if (lexicalHandler != null) {
+            lexicalHandler.startCDATA();
+        }
+    }
+
+    /*package*/ void endCdata() throws SAXException {
+        LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+        if (lexicalHandler != null) {
+            lexicalHandler.endCDATA();
+        }
+    }
+
+    /*package*/ void startNamespace(String prefix, String uri)
+            throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.startPrefixMapping(prefix, uri);
+        }
+    }
+
+    /*package*/ void endNamespace(String prefix) throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.endPrefixMapping(prefix);
+        }
+    }
+
+    /*package*/ void startDtd(String name, String publicId, String systemId)
+            throws SAXException {
+        LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+        if (lexicalHandler != null) {
+            lexicalHandler.startDTD(name, publicId, systemId);
+        }
+    }
+
+    /*package*/ void endDtd() throws SAXException {
+        LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+        if (lexicalHandler != null) {
+            lexicalHandler.endDTD();
+        }
+    }
+
+    /*package*/ void processingInstruction(String target, String data)
+            throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.processingInstruction(target, data);
+        }        
+    }
+
+    /**
+     * Handles an external entity.
+     *
+     * @param context to be passed back to Expat when we parse the entity
+     * @param publicId the publicId of the entity
+     * @param systemId the systemId of the entity
+     */
+    /*package*/ void handleExternalEntity(String context, String publicId,
+            String systemId) throws SAXException, IOException {
+        EntityResolver entityResolver = xmlReader.entityResolver;
+        if (entityResolver == null) {
+            return;
+        }
+
+        /*
+         * The spec. is terribly under-specified here. It says that if the
+         * systemId is a URL, we should try to resolve it, but it doesn't
+         * specify how to tell whether or not the systemId is a URL let alone
+         * how to resolve it.
+         *
+         * Other implementations do various insane things. We try to keep it
+         * simple: if the systemId parses as a URI and it's relative, we try to
+         * resolve it against the parent document's systemId. If anything goes
+         * wrong, we go with the original systemId. If crazybob had designed
+         * the API, he would have left all resolving to the EntityResolver.
+         */
+        if (this.systemId != null) {
+            try {
+                URI systemUri = new URI(systemId);
+                if (!systemUri.isAbsolute() && !systemUri.isOpaque()) {
+                    // It could be relative (or it may not be a URI at all!)
+                    URI baseUri = new URI(this.systemId);
+                    systemUri = baseUri.resolve(systemUri);
+
+                    // Replace systemId w/ resolved URI
+                    systemId = systemUri.toString();
+                }
+            } catch (Exception e) {
+                Logger.getLogger(ExpatParser.class.getName()).log(Level.INFO,
+                        "Could not resolve '" + systemId + "' relative to"
+                        + " '" + this.systemId + "' at " + locator, e);
+            }
+        }
+
+        InputSource inputSource = entityResolver.resolveEntity(
+                publicId, systemId);
+        if (inputSource == null) {
+            /*
+             * The spec. actually says that we should try to treat systemId
+             * as a URL and download and parse its contents here, but an
+             * entity resolver can easily accomplish the same by returning
+             * new InputSource(systemId).
+             *
+             * Downloading external entities by default would result in several
+             * unwanted DTD downloads, not to mention pose a security risk
+             * when parsing untrusted XML (http://tinyurl.com/56ggrk),
+             * so we just do nothing instead. This also enables the user to
+             * opt out of entity parsing when using
+             * {@link org.xml.sax.helpers.DefaultHandler}, something that
+             * wouldn't be possible otherwise.
+             */
+            return;
+        }
+
+        String encoding = pickEncoding(inputSource);
+        int pointer = createEntityParser(this.pointer, context, encoding);
+        try {
+            EntityParser entityParser = new EntityParser(encoding, xmlReader,
+                    pointer, inputSource.getPublicId(),
+                    inputSource.getSystemId());
+
+            parseExternalEntity(entityParser, inputSource);
+        } finally {
+            releaseParser(pointer);
+        }
+    }
+
+    /**
+     * Picks an encoding for an external entity. Defaults to UTF-8.
+     */
+    private String pickEncoding(InputSource inputSource) {
+        Reader reader = inputSource.getCharacterStream();
+        if (reader != null) {
+            return CHARACTER_ENCODING;
+        }
+
+        String encoding = inputSource.getEncoding();
+        return encoding == null ? DEFAULT_ENCODING : encoding;
+    }
+
+    /**
+     * Parses the the external entity provided by the input source.
+     */
+    private void parseExternalEntity(ExpatParser entityParser,
+            InputSource inputSource) throws IOException, SAXException {
+        /*
+         * Expat complains if the external entity isn't wrapped with a root
+         * element so we add one and ignore it later on during parsing.
+         */
+        
+        // Try the character stream.
+        Reader reader = inputSource.getCharacterStream();
+        if (reader != null) {
+            try {
+                entityParser.append("<externalEntity>");
+                entityParser.parseFragment(reader);
+                entityParser.append("</externalEntity>");
+            } finally {
+                // TODO: Don't eat original exception when close() throws.
+                reader.close();
+            }
+            return;
+        }
+
+        // Try the byte stream.
+        InputStream in = inputSource.getByteStream();
+        if (in != null) {
+            try {
+                entityParser.append("<externalEntity>"
+                        .getBytes(entityParser.encoding));
+                entityParser.parseFragment(in);
+                entityParser.append("</externalEntity>"
+                        .getBytes(entityParser.encoding));
+            } finally {
+                // TODO: Don't eat original exception when close() throws.
+                in.close();
+            }
+            return;
+        }
+
+        // Make sure we use the user-provided systemId.
+        String systemId = inputSource.getSystemId();
+        if (systemId == null) {
+            // TODO: We could just try our systemId here.
+            throw new ParseException("No input specified.", locator);
+        }
+
+        // Try the system id.
+        in = openUrl(systemId);
+        try {
+            entityParser.append("<externalEntity>"
+                    .getBytes(entityParser.encoding));
+            entityParser.parseFragment(in);
+            entityParser.append("</externalEntity>"
+                    .getBytes(entityParser.encoding));
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Creates a native entity parser.
+     *
+     * @param parentPointer pointer to parent Expat parser
+     * @param context passed to {@link #handleExternalEntity}
+     * @param encoding
+     * @return pointer to native parser
+     */
+    private static native int createEntityParser(int parentPointer,
+            String context, String encoding);
+
+    /**
+     * Appends part of an XML document. This parser will parse the given XML to
+     * the extent possible and dispatch to the appropriate methods.
+     *
+     * @param xml a whole or partial snippet of XML
+     * @throws SAXException if an error occurs during parsing
+     */
+    /*package*/ void append(String xml) throws SAXException {
+        try {
+            append(this.pointer, xml, false);
+        } catch (ExpatException e) {
+            throw new ParseException(e.getMessage(), this.locator);
+        }
+    }
+
+    private native void append(int pointer, String xml, boolean isFinal)
+            throws SAXException, ExpatException;
+
+    /**
+     * Appends part of an XML document. This parser will parse the given XML to
+     * the extent possible and dispatch to the appropriate methods.
+     *
+     * @param xml a whole or partial snippet of XML
+     * @param offset into the char[]
+     * @param length of characters to use
+     * @throws SAXException if an error occurs during parsing
+     */
+    /*package*/ void append(char[] xml, int offset, int length)
+            throws SAXException {
+        try {
+            append(this.pointer, xml, offset, length);
+        } catch (ExpatException e) {
+            throw new ParseException(e.getMessage(), this.locator);
+        }
+    }
+
+    private native void append(int pointer, char[] xml, int offset,
+            int length) throws SAXException, ExpatException;
+
+    /**
+     * Appends part of an XML document. This parser will parse the given XML to
+     * the extent possible and dispatch to the appropriate methods.
+     *
+     * @param xml a whole or partial snippet of XML
+     * @throws SAXException if an error occurs during parsing
+     */
+    /*package*/ void append(byte[] xml) throws SAXException {
+        append(xml, 0, xml.length);
+    }
+
+    /**
+     * Appends part of an XML document. This parser will parse the given XML to
+     * the extent possible and dispatch to the appropriate methods.
+     *
+     * @param xml a whole or partial snippet of XML
+     * @param offset into the byte[]
+     * @param length of bytes to use
+     * @throws SAXException if an error occurs during parsing
+     */
+    /*package*/ void append(byte[] xml, int offset, int length)
+            throws SAXException {
+        try {
+            append(this.pointer, xml, offset, length);
+        } catch (ExpatException e) {
+            throw new ParseException(e.getMessage(), this.locator);
+        }
+    }
+
+    private native void append(int pointer, byte[] xml, int offset,
+            int length) throws SAXException, ExpatException;
+
+    /**
+     * Parses an XML document from the given input stream.
+     */
+    /*package*/ void parseDocument(InputStream in) throws IOException,
+            SAXException {
+        startDocument();
+        parseFragment(in);
+        finish();
+        endDocument();
+    }
+
+    /**
+     * Parses an XML Document from the given reader.
+     */
+    /*package*/ void parseDocument(Reader in) throws IOException, SAXException {
+        startDocument();
+        parseFragment(in);
+        finish();
+        endDocument();
+    }
+
+    /**
+     * Parses XML from the given Reader.
+     */
+    private void parseFragment(Reader in) throws IOException, SAXException {
+        char[] buffer = new char[BUFFER_SIZE / 2];
+        int length;
+        while ((length = in.read(buffer)) != -1) {
+            try {
+                append(this.pointer, buffer, 0, length);
+            } catch (ExpatException e) {
+                throw new ParseException(e.getMessage(), locator);
+            }
+        }
+    }
+
+    /**
+     * Parses XML from the given input stream.
+     */
+    private void parseFragment(InputStream in)
+            throws IOException, SAXException {
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int length;
+        while ((length = in.read(buffer)) != -1) {
+            try {
+                append(this.pointer, buffer, 0, length);
+            } catch (ExpatException e) {
+                throw new ParseException(e.getMessage(), this.locator);
+            }
+        }
+    }
+
+    private void startDocument() throws SAXException {
+        ContentHandler contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.setDocumentLocator(this.locator);
+            contentHandler.startDocument();
+        }
+    }
+
+    private void endDocument() throws SAXException {
+        ContentHandler contentHandler;
+        contentHandler = xmlReader.contentHandler;
+        if (contentHandler != null) {
+            contentHandler.endDocument();
+        }
+    }
+
+    /**
+     * Indicate that we're finished parsing.
+     *
+     * @throws SAXException if the xml is incomplete
+     */
+    /*package*/ void finish() throws SAXException {
+        try {
+            append(this.pointer, "", true);
+        } catch (ExpatException e) {
+            throw new ParseException(e.getMessage(), this.locator);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+    protected synchronized void finalize() throws Throwable {
+        if (this.pointer != 0) {
+            release(this.pointer);
+            this.pointer = 0;
+        }
+    }
+
+    /**
+     * Releases all native objects.
+     */
+    private native void release(int pointer);
+
+    /**
+     * Releases native parser only.
+     */
+    private static native void releaseParser(int pointer);
+
+    /**
+     * Initialize static resources.
+     */
+    private static native void staticInitialize(String emptyString);
+
+    static {
+        staticInitialize("");
+    }
+
+    /**
+     * Gets the current line number within the XML file.
+     */
+    private int line() {
+        return line(this.pointer);
+    }
+
+    private static native int line(int pointer);
+
+    /**
+     * Gets the current column number within the XML file.
+     */
+    private int column() {
+        return column(this.pointer);
+    }
+
+    private static native int column(int pointer);
+
+    /**
+     * Clones the current attributes so they can be used outside of
+     * startElement().
+     */
+    /*package*/ Attributes cloneAttributes() {
+        if (!inStartElement) {
+            throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+        }
+
+        if (attributeCount == 0) {
+            return ClonedAttributes.EMPTY;
+        }
+
+        int clonePointer
+                = cloneAttributes(this.attributePointer, this.attributeCount);
+        return new ClonedAttributes(pointer, clonePointer, attributeCount);
+    }
+
+    private static native int cloneAttributes(int pointer, int attributeCount);
+
+    /**
+     * Used for cloned attributes.
+     */
+    private static class ClonedAttributes extends ExpatAttributes {
+
+        private static final Attributes EMPTY = new ClonedAttributes(0, 0, 0);
+
+        private final int parserPointer;
+        private int pointer;
+        private final int length;
+
+        /**
+         * Constructs a Java wrapper for native attributes.
+         *
+         * @param parserPointer pointer to the parse, can be 0 if length is 0.
+         * @param pointer pointer to the attributes array, can be 0 if the
+         *  length is 0.
+         * @param length number of attributes
+         */
+        private ClonedAttributes(int parserPointer, int pointer, int length) {
+            this.parserPointer = parserPointer;
+            this.pointer = pointer;
+            this.length = length;
+        }
+
+        @Override
+        public int getParserPointer() {
+            return this.parserPointer;
+        }
+
+        @Override
+        public int getPointer() {
+            return pointer;
+        }
+
+        @Override
+        public int getLength() {
+            return length;
+        }
+
+        @Override
+        @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+        protected synchronized void finalize() throws Throwable {
+            if (pointer != 0) {
+                freeAttributes(pointer);
+                pointer = 0;
+            }
+        }
+    }
+
+    private class ExpatLocator implements Locator {
+
+        public String getPublicId() {
+            return publicId;
+        }
+
+        public String getSystemId() {
+            return systemId;
+        }
+
+        public int getLineNumber() {
+            return line();
+        }
+
+        public int getColumnNumber() {
+            return column();
+        }
+
+        @Override
+        public String toString() {
+            return "Locator[publicId: " + publicId + ", systemId: " + systemId
+                + ", line: " + getLineNumber()
+                + ", column: " + getColumnNumber() + "]";
+        }
+    }
+
+    /**
+     * Attributes that are only valid during startElement().
+     */
+    private class CurrentAttributes extends ExpatAttributes {
+
+        @Override
+        public int getParserPointer() {
+            return pointer;
+        }
+
+        @Override
+        public int getPointer() {
+            if (!inStartElement) {
+                throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+            }
+            return attributePointer;
+        }
+
+        @Override
+        public int getLength() {
+            if (!inStartElement) {
+                throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+            }
+            return attributeCount;
+        }
+    }
+
+    /**
+     * Includes line and column in the message.
+     */
+    private static class ParseException extends SAXParseException {
+
+        private ParseException(String message, Locator locator) {
+            super(makeMessage(message, locator), locator);
+        }
+
+        private static String makeMessage(String message, Locator locator) {
+            return makeMessage(message, locator.getLineNumber(),
+                    locator.getColumnNumber());
+        }
+
+        private static String makeMessage(
+                String message, int line, int column) {
+            return "At line " + line + ", column "
+                    + column + ": " + message;
+        }
+    }
+    
+    /**
+     * Opens an InputStream for the given URL.
+     */
+    /*package*/ static InputStream openUrl(String url) throws IOException {
+        try {
+            URLConnection urlConnection = new URL(url).openConnection();
+            urlConnection.setConnectTimeout(TIMEOUT);
+            urlConnection.setReadTimeout(TIMEOUT);
+            urlConnection.setDoInput(true);
+            urlConnection.setDoOutput(false);
+            return urlConnection.getInputStream();
+        } catch (Exception e) {
+            IOException ioe = new IOException("Couldn't open " + url);
+            ioe.initCause(e);
+            throw ioe;
+        }
+    }
+
+    /**
+     * Parses an external entity.
+     */
+    private static class EntityParser extends ExpatParser {
+
+        private int depth = 0; 
+
+        private EntityParser(String encoding, ExpatReader xmlReader,
+                int pointer, String publicId, String systemId) {
+            super(encoding, xmlReader, pointer, publicId, systemId);
+        }
+
+        @Override
+        void startElement(String uri, String localName, String qName,
+                int attributePointer, int attributeCount) throws SAXException {
+            /*
+             * Skip topmost element generated by our workaround in
+             * {@link #handleExternalEntity}.
+             */
+            if (depth++ > 0) {
+                super.startElement(uri, localName, qName, attributePointer,
+                        attributeCount);
+            }
+        }
+        
+        @Override
+        void endElement(String uri, String localName, String qName)
+                throws SAXException {
+            if (--depth > 0) {
+                super.endElement(uri, localName, qName);
+            }
+        }
+
+        @Override
+        @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+        protected synchronized void finalize() throws Throwable {
+            /*
+             * Don't release our native resources. We do so explicitly in
+             * {@link #handleExternalEntity} and we don't want to release the
+             * parsing context--our parent is using it.
+             */
+        }
+    }
+}
+
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java b/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java
new file mode 100644
index 0000000..4759718
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java
@@ -0,0 +1,964 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Fast, partial XmlPullParser implementation based upon Expat. Does not
+ * support validation or {@code DOCTYPE} processing.
+ */
+public class ExpatPullParser implements XmlPullParser {
+    /**
+     * This feature is identified by http://xmlpull.org/v1/doc/features.html#relaxed
+     * If this feature is supported that means that XmlPull parser will be
+     * lenient when checking XML well formedness.
+     * NOTE: use it only if XML input is not well-formed and in general usage
+     * if this feature is discouraged
+     * NOTE: as there is no definition of what is relaxed XML parsing
+     * therefore what parser will do completely depends on implementation used
+     */
+    public static final String FEATURE_RELAXED =
+            "http://xmlpull.org/v1/doc/features.html#relaxed";
+
+    private static final int BUFFER_SIZE = 8096;
+
+    private static final String NOT_A_START_TAG = "This is not a start tag.";
+
+    private Document document;
+    private boolean processNamespaces = false;
+    private boolean relaxed = false;
+
+    public void setFeature(String name, boolean state)
+            throws XmlPullParserException {
+        if (name == null) {
+            // Required by API.          
+            throw new IllegalArgumentException("Null feature name");
+        }
+
+        if (name.equals(FEATURE_PROCESS_NAMESPACES)) {
+            processNamespaces = state;
+            return;
+        }
+
+        if (name.equals(FEATURE_RELAXED)) {
+            relaxed = true;
+            return;
+        }
+
+        // You're free to turn these features off because we don't support them.
+        if (!state && (name.equals(FEATURE_REPORT_NAMESPACE_ATTRIBUTES)
+                || name.equals(FEATURE_PROCESS_DOCDECL)
+                || name.equals(FEATURE_VALIDATION))) {
+            return;
+        }
+
+        throw new XmlPullParserException("Unsupported feature: " + name);
+    }
+
+    public boolean getFeature(String name) {
+        if (name == null) {
+            // Required by API.
+            throw new IllegalArgumentException("Null feature name");
+        }
+
+        // We always support namespaces, but no other features.
+        return name.equals(FEATURE_PROCESS_NAMESPACES) && processNamespaces;
+    }
+
+    /**
+     * Returns true if this parser processes namespaces.
+     *
+     * @see #setNamespaceProcessingEnabled(boolean)
+     */
+    public boolean isNamespaceProcessingEnabled() {
+        return processNamespaces;
+    }
+
+    /**
+     * Enables or disables namespace processing. Set to false by default.
+     *
+     * @see #isNamespaceProcessingEnabled()
+     */
+    public void setNamespaceProcessingEnabled(boolean processNamespaces) {
+        this.processNamespaces = processNamespaces;
+    }
+
+    public void setProperty(String name, Object value)
+            throws XmlPullParserException {
+        if (name == null) {
+            // Required by API.
+            throw new IllegalArgumentException("Null feature name");
+        }
+
+        // We don't support any properties.
+        throw new XmlPullParserException("Properties aren't supported.");
+    }
+
+    public Object getProperty(String name) {
+        return null;
+    }
+
+    public void setInput(Reader in) throws XmlPullParserException {
+        this.document = new CharDocument(in, processNamespaces);
+    }
+
+    public void setInput(InputStream in, String encodingName)
+            throws XmlPullParserException {
+        this.document = new ByteDocument(in, encodingName, processNamespaces);
+    }
+
+    public String getInputEncoding() {
+        return this.document.getEncoding();
+    }
+
+    /**
+     * Not supported.
+     *
+     * @throws UnsupportedOperationException always
+     */
+    public void defineEntityReplacementText(String entityName,
+            String replacementText) throws XmlPullParserException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getNamespaceCount(int depth) throws XmlPullParserException {
+        return document.currentEvent.namespaceStack.countAt(depth);
+    }
+
+    public String getNamespacePrefix(int pos) throws XmlPullParserException {
+        String prefix = document.currentEvent.namespaceStack.prefixAt(pos);
+        @SuppressWarnings("StringEquality")
+        boolean hasPrefix = prefix != "";
+        return hasPrefix ? prefix : null;
+    }
+
+    public String getNamespaceUri(int pos) throws XmlPullParserException {
+        return document.currentEvent.namespaceStack.uriAt(pos);
+    }
+
+    public String getNamespace(String prefix) {
+        // In XmlPullParser API, null == default namespace.
+        if (prefix == null) {
+            // Internally, we use empty string instead of null.
+            prefix = "";
+        }
+
+        return document.currentEvent.namespaceStack.uriFor(prefix);
+    }
+
+    public int getDepth() {
+        return this.document.getDepth();
+    }
+
+    public String getPositionDescription() {
+        return "line " + getLineNumber() + ", column " + getColumnNumber();
+    }
+
+    /**
+     * Not supported.
+     *
+     * @return {@literal -1} always
+     */
+    public int getLineNumber() {
+        // We would have to record the line number in each event.
+        return -1;
+    }
+
+    /**
+     * Not supported.
+     *
+     * @return {@literal -1} always
+     */
+    public int getColumnNumber() {
+        // We would have to record the column number in each event.
+        return -1;
+    }
+
+    public boolean isWhitespace() throws XmlPullParserException {
+        if (getEventType() != TEXT) {
+            throw new XmlPullParserException("Not on text.");
+        }
+
+        String text = getText();
+
+        if (text.length() == 0) {
+            return true;
+        }
+
+        int length = text.length();
+        for (int i = 0; i < length; i++) {
+            if (!Character.isWhitespace(text.charAt(i))) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public String getText() {
+        final StringBuilder builder = this.document.currentEvent.getText();
+        return builder == null ? null : builder.toString();
+    }
+
+    public char[] getTextCharacters(int[] holderForStartAndLength) {
+        final StringBuilder builder = this.document.currentEvent.getText();
+
+        final int length = builder.length();
+        char[] characters = new char[length];
+        builder.getChars(0, length, characters, 0);
+
+        holderForStartAndLength[0] = 0;
+        holderForStartAndLength[1] = length;
+
+        return characters;
+    }
+
+    public String getNamespace() {
+        return this.document.currentEvent.getNamespace();
+    }
+
+    public String getName() {
+        return this.document.currentEvent.getName();
+    }
+
+    /**
+     * Not supported.
+     *
+     * @throws UnsupportedOperationException always
+     */
+    public String getPrefix() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isEmptyElementTag() throws XmlPullParserException {
+        return this.document.isCurrentElementEmpty();
+    }
+
+    public int getAttributeCount() {
+        return this.document.currentEvent.getAttributeCount();
+    }
+
+    public String getAttributeNamespace(int index) {
+        return this.document.currentEvent.getAttributeNamespace(index);
+    }
+
+    public String getAttributeName(int index) {
+        return this.document.currentEvent.getAttributeName(index);
+    }
+
+    /**
+     * Not supported.
+     *
+     * @throws UnsupportedOperationException always
+     */
+    public String getAttributePrefix(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getAttributeType(int index) {
+        return "CDATA";
+    }
+
+    public boolean isAttributeDefault(int index) {
+        return false;
+    }
+
+    public String getAttributeValue(int index) {
+        return this.document.currentEvent.getAttributeValue(index);
+    }
+
+    public String getAttributeValue(String namespace, String name) {
+        return this.document.currentEvent.getAttributeValue(namespace, name);
+    }
+
+    public int getEventType() throws XmlPullParserException {
+        return this.document.currentEvent.getType();
+    }
+
+    public int next() throws XmlPullParserException, IOException {
+        return this.document.dequeue();
+    }
+
+    /**
+     * Not supported.
+     *
+     * @throws UnsupportedOperationException always
+     */
+    public int nextToken() throws XmlPullParserException, IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void require(int type, String namespace, String name)
+            throws XmlPullParserException, IOException {
+        if (type != getEventType()
+                || (namespace != null && !namespace.equals(getNamespace()))
+                || (name != null && !name.equals(getName()))) {
+            throw new XmlPullParserException("expected "
+                    + TYPES[type] + getPositionDescription());
+        }
+    }
+
+    public String nextText() throws XmlPullParserException, IOException {
+        if (this.document.currentEvent.getType() != START_TAG)
+            throw new XmlPullParserException("Not on start tag.");
+
+        int next = this.document.dequeue();
+        switch (next) {
+            case TEXT: return getText();
+            case END_TAG: return "";
+            default: throw new XmlPullParserException(
+                "Unexpected event type: " + TYPES[next]);
+        }
+    }
+
+    public int nextTag() throws XmlPullParserException, IOException {
+        int eventType = next();
+        if (eventType == TEXT && isWhitespace()) {
+            eventType = next();
+        }
+        if (eventType != START_TAG && eventType != END_TAG) {
+            throw new XmlPullParserException(
+                "Expected start or end tag", this, null);
+        }
+        return eventType;
+    }
+
+    /**
+     * Immutable namespace stack. Pushing a new namespace on to the stack
+     * only results in one object allocation. Most operations are O(N) where
+     * N is the stack size. Accessing recently pushed namespaces, like those
+     * for the current element, is significantly faster.
+     */
+    static class NamespaceStack {
+
+        /** An empty stack. */
+        static final NamespaceStack EMPTY = new NamespaceStack();
+
+        private final NamespaceStack parent;
+        private final String prefix;
+        private final String uri;
+        private final int index;
+        private final int depth;
+
+        /**
+         * Constructs an actual namespace stack node. Internally, the nodes
+         * and the stack are one in the same making for a very efficient
+         * implementation. The user just sees an immutable stack and the
+         * builder.
+         */
+        private NamespaceStack(NamespaceStack parent, String prefix,
+                String uri, int depth) {
+            this.parent = parent;
+            this.prefix = prefix;
+            this.uri = uri;
+            this.index = parent.index + 1;
+            this.depth = depth;
+        }
+
+        /**
+         * Constructs a dummy node which only serves to point to the bottom
+         * of the stack. Using an actual node instead of null simplifies the
+         * code.
+         */
+        private NamespaceStack() {
+            this.parent = null;
+            this.prefix = null;
+            this.uri = null;
+
+            // This node has an index of -1 since the actual first node in the
+            // stack has index 0.
+            this.index = -1;
+            
+            // The actual first node will have a depth of 1.
+            this.depth = 0;
+        }
+
+        String uriFor(String prefix) {
+            for (NamespaceStack node = this; node.index >= 0;
+                    node = node.parent) {
+                if (node.prefix.equals(prefix)) {
+                    return node.uri;
+                }
+            }
+
+            // Not found.
+            return null;
+        }
+
+        /**
+         * Gets the prefix at the given index in the stack.
+         */
+        String prefixAt(int index) {
+            return nodeAt(index).prefix;
+        }
+
+        /**
+         * Gets the URI at the given index in the stack.
+         */
+        String uriAt(int index) {
+            return nodeAt(index).uri;
+        }
+
+        private NamespaceStack nodeAt(int index) {
+            if (index > this.index) {
+                throw new IndexOutOfBoundsException("Index > size.");
+            }
+            if (index < 0) {
+                throw new IndexOutOfBoundsException("Index < 0.");
+            }
+
+            NamespaceStack node = this;
+            while (index != node.index) {
+                node = node.parent;
+            }
+            return node;
+        }
+
+        /**
+         * Gets the size of the stack at the given element depth.
+         */
+        int countAt(int depth) {
+            if (depth > this.depth) {
+                throw new IndexOutOfBoundsException("Depth > maximum.");
+            }
+            if (depth < 0) {
+                throw new IndexOutOfBoundsException("Depth < 0.");
+            }
+
+            NamespaceStack node = this;
+            while (depth < node.depth) {
+                node = node.parent;
+            }
+            return node.index + 1;         
+        }
+
+        /** Builds a NamespaceStack. */
+        static class Builder {
+
+            NamespaceStack top = EMPTY;
+
+            /**
+             * Pushes a namespace onto the stack.
+             *
+             * @param depth of the element upon which the namespace was
+             *  declared
+             */
+            void push(String prefix, String uri, int depth) {
+                top = new NamespaceStack(top, prefix, uri, depth);
+            }
+
+            /**
+             * Pops all namespaces from the given element depth.
+             */
+            void pop(int depth) {
+                // Remove all nodes at the specified depth.
+                while (top != null && top.depth == depth) {
+                    top = top.parent;
+                }
+            }
+
+            /** Returns the current stack. */
+            NamespaceStack build() {
+                return top;
+            }
+        }
+    }
+
+    /**
+     * Base class for events. Implements event chaining and defines event API
+     * along with common implementations which can be overridden.
+     */
+    static abstract class Event {
+
+        /** Element depth at the time of this event. */
+        final int depth;
+
+        /** The namespace stack at the time of this event. */
+        final NamespaceStack namespaceStack;
+
+        /** Next event in the queue. */ 
+        Event next = null;
+
+        Event(int depth, NamespaceStack namespaceStack) {
+            this.depth = depth;
+            this.namespaceStack = namespaceStack;
+        }
+
+        void setNext(Event next) {
+            this.next = next;
+        }
+
+        Event getNext() {
+            return next;
+        }
+
+        StringBuilder getText() {
+            return null;
+        }
+
+        String getNamespace() {
+            return null;
+        }
+
+        String getName() {
+            return null;
+        }
+
+        int getAttributeCount() {
+            return -1;
+        }
+
+        String getAttributeNamespace(int index) {
+            throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+        }
+
+        String getAttributeName(int index) {
+            throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+        }
+
+        String getAttributeValue(int index) {
+            throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+        }
+
+        abstract int getType();
+
+        String getAttributeValue(String namespace, String name) {
+            throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+        }
+
+        public int getDepth() {
+            return this.depth;
+        }
+    }
+
+    static class StartDocumentEvent extends Event {
+
+        public StartDocumentEvent() {
+            super(0, NamespaceStack.EMPTY);
+        }
+
+        @Override
+        int getType() {
+            return START_DOCUMENT;
+        }
+    }
+
+    static class StartTagEvent extends Event {
+
+        final String name;
+        final String namespace;
+        final Attributes attributes;
+        final boolean processNamespaces;
+
+        StartTagEvent(String namespace,
+                String name,
+                ExpatParser expatParser,
+                int depth,
+                NamespaceStack namespaceStack,
+                boolean processNamespaces) {
+            super(depth, namespaceStack);
+            this.namespace = namespace;
+            this.name = name;
+            this.attributes = expatParser.cloneAttributes();
+            this.processNamespaces = processNamespaces;
+        }
+
+        @Override
+        String getNamespace() {
+            return namespace;
+        }
+
+        @Override
+        String getName() {
+            return name;
+        }
+
+        @Override
+        int getAttributeCount() {
+            return attributes.getLength();
+        }
+
+        @Override
+        String getAttributeNamespace(int index) {
+            return attributes.getURI(index);
+        }
+
+        @Override
+        String getAttributeName(int index) {
+            return processNamespaces ? attributes.getLocalName(index)
+                    : attributes.getQName(index);
+        }
+
+        @Override
+        String getAttributeValue(int index) {
+            return attributes.getValue(index);
+        }
+
+        @Override
+        String getAttributeValue(String namespace, String name) {
+            if (namespace == null) {
+                namespace = "";
+            }
+
+            return attributes.getValue(namespace, name);
+        }
+
+        @Override
+        int getType() {
+            return START_TAG;
+        }
+    }
+
+    static class EndTagEvent extends Event {
+
+        final String namespace;
+        final String localName;
+
+        EndTagEvent(String namespace, String localName, int depth,
+                NamespaceStack namespaceStack) {
+            super(depth, namespaceStack);
+            this.namespace = namespace;
+            this.localName = localName;
+        }
+
+        @Override
+        String getName() {
+            return this.localName;
+        }
+
+        @Override
+        String getNamespace() {
+            return this.namespace;
+        }
+
+        @Override
+        int getType() {
+            return END_TAG;
+        }
+    }
+
+    static class TextEvent extends Event {
+
+        final StringBuilder builder;
+
+        public TextEvent(int initialCapacity, int depth,
+                NamespaceStack namespaceStack) {
+            super(depth, namespaceStack);
+            this.builder = new StringBuilder(initialCapacity);
+        }
+
+        @Override
+        int getType() {
+            return TEXT;
+        }
+
+        @Override
+        StringBuilder getText() {
+            return this.builder;
+        }
+
+        void append(char[] text, int start, int length) {
+            builder.append(text, start, length);
+        }
+    }
+
+    static class EndDocumentEvent extends Event {
+
+        EndDocumentEvent() {
+            super(0, NamespaceStack.EMPTY);
+        }
+
+        @Override
+        Event getNext() {
+            throw new IllegalStateException("End of document.");
+        }
+
+        @Override
+        void setNext(Event next) {
+            throw new IllegalStateException("End of document.");
+        }
+
+        @Override
+        int getType() {
+            return END_DOCUMENT;
+        }
+    }
+
+    /**
+     * Encapsulates the parsing context of the current document.
+     */
+    abstract class Document {
+
+        final String encoding;
+        final ExpatParser parser;
+        final boolean processNamespaces;
+
+        TextEvent textEvent = null;
+        boolean finished = false;
+
+        Document(String encoding, boolean processNamespaces) {
+            this.encoding = encoding;
+            this.processNamespaces = processNamespaces;
+
+            ExpatReader xmlReader = new ExpatReader();
+            xmlReader.setContentHandler(new SaxHandler());
+
+            this.parser = new ExpatParser(
+                    encoding, xmlReader, processNamespaces, null, null);
+        }
+
+        /** Namespace stack builder. */
+        NamespaceStack.Builder namespaceStackBuilder
+                = new NamespaceStack.Builder();
+        
+        Event currentEvent = new StartDocumentEvent();
+        Event last = currentEvent;
+
+        /**
+         * Sends some more XML to the parser.
+         */
+        void pump() throws IOException, XmlPullParserException {
+            if (this.finished) {
+                return;
+            }
+
+            int length = buffer();
+
+            // End of document.
+            if (length == -1) {
+                this.finished = true;
+                if (!relaxed) {
+                    try {
+                        parser.finish();
+                    } catch (SAXException e) {
+                        throw new XmlPullParserException(
+                            "Premature end of document.", ExpatPullParser.this, e);
+                    }
+                }
+                add(new EndDocumentEvent());
+                return;
+            }
+
+            if (length == 0) {
+                return;
+            }
+
+            flush(parser, length);
+        }
+
+        /**
+         * Reads data into the buffer.
+         *
+         * @return the length of data buffered or {@code -1} if we've reached
+         *  the end of the data.
+         */
+        abstract int buffer() throws IOException;
+
+        /**
+         * Sends buffered data to the parser.
+         *
+         * @param parser the parser to flush to
+         * @param length of data buffered
+         */
+        abstract void flush(ExpatParser parser, int length)
+                throws XmlPullParserException;
+
+        /**
+         * Adds an event.
+         */
+        void add(Event event) {
+            // Flush pre-exising text event if necessary.
+            if (textEvent != null) {
+                last.setNext(textEvent);
+                last = textEvent;
+                textEvent = null;
+            }
+
+            last.setNext(event);
+            last = event;
+        }
+
+        /**
+         * Moves to the next event in the queue.
+         *
+         * @return type of next event
+         */
+        int dequeue() throws XmlPullParserException, IOException {
+            Event next;
+
+            while ((next = currentEvent.getNext()) == null) {
+                pump();
+            }
+
+            currentEvent.next = null;
+            currentEvent = next;
+
+            return currentEvent.getType();
+        }
+
+        String getEncoding() {
+            return this.encoding;
+        }
+
+        int getDepth() {
+            return currentEvent.getDepth();
+        }
+
+        /**
+         * Returns true if we're on a start element and the next event is
+         * its corresponding end element.
+         *
+         * @throws XmlPullParserException if we aren't on a start element
+         */
+        boolean isCurrentElementEmpty() throws XmlPullParserException {
+            if (currentEvent.getType() != START_TAG) {
+                throw new XmlPullParserException(NOT_A_START_TAG);
+            }
+
+            Event next;
+
+            try {
+                while ((next = currentEvent.getNext()) == null) {
+                    pump();
+                }
+            } catch (IOException ex) {
+                throw new XmlPullParserException(ex.toString());
+            }
+
+            return next.getType() == END_TAG;
+        }
+
+        private class SaxHandler implements ContentHandler {
+
+            int depth = 0;
+
+            public void startPrefixMapping(String prefix, String uri)
+                    throws SAXException {
+                // Depth + 1--we aren't actually in the element yet.
+                namespaceStackBuilder.push(prefix, uri, depth + 1);
+            }
+
+            public void startElement(String uri, String localName, String qName,
+                    Attributes attributes) {
+                String name = processNamespaces ? localName : qName;
+
+                add(new StartTagEvent(uri, name, parser, ++this.depth,
+                        namespaceStackBuilder.build(), processNamespaces));
+            }
+
+            public void endElement(String uri, String localName, String qName) {
+                String name = processNamespaces ? localName : qName;
+
+                int depth = this.depth--;
+                add(new EndTagEvent(uri, name, depth,
+                        namespaceStackBuilder.build()));
+                namespaceStackBuilder.pop(depth);
+            }
+
+            public void characters(char ch[], int start, int length) {
+                // Ignore empty strings.
+                if (length == 0) {
+                    return;
+                }
+
+                // Start a new text event if necessary.
+                if (textEvent == null) {
+                    textEvent = new TextEvent(length, this.depth,
+                            namespaceStackBuilder.build());
+                }
+
+                // Append to an existing text event.
+                textEvent.append(ch, start, length);
+            }
+
+            public void setDocumentLocator(Locator locator) {}
+            public void startDocument() throws SAXException {}
+            public void endDocument() throws SAXException {}
+            public void endPrefixMapping(String prefix) throws SAXException {}
+            public void ignorableWhitespace(char ch[], int start, int length)
+                    throws SAXException {}
+            public void processingInstruction(String target, String data)
+                    throws SAXException {}
+            public void skippedEntity(String name) throws SAXException {}
+        }
+    }
+
+    class CharDocument extends Document {
+
+        final char[] buffer = new char[BUFFER_SIZE / 2];
+        final Reader in;
+
+        CharDocument(Reader in, boolean processNamespaces) {
+            super("UTF-16", processNamespaces);
+            this.in = in;
+        }
+
+        @Override
+        int buffer() throws IOException {
+            return in.read(buffer);
+        }
+
+        @Override
+        void flush(ExpatParser parser, int length)
+                throws XmlPullParserException {
+            try {
+                parser.append(buffer, 0, length);
+            } catch (SAXException e) {
+                throw new XmlPullParserException(
+                        "Error parsing document.", ExpatPullParser.this, e);
+            }
+        }
+    }
+
+    class ByteDocument extends Document {
+
+        final byte[] buffer = new byte[BUFFER_SIZE];
+        final InputStream in;
+
+        ByteDocument(InputStream in, String encoding,
+                boolean processNamespaces) {
+            super(encoding, processNamespaces);
+            this.in = in;
+        }
+
+        @Override
+        int buffer() throws IOException {
+            return in.read(buffer);
+        }
+
+        @Override
+        void flush(ExpatParser parser, int length)
+                throws XmlPullParserException {
+            try {
+                parser.append(buffer, 0, length);
+            } catch (SAXException e) {
+                throw new XmlPullParserException(
+                        "Error parsing document.", ExpatPullParser.this, e);
+            }
+        }
+    }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
new file mode 100644
index 0000000..a6a83a0
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.InputStream;
+import java.util.logging.Logger;
+
+/**
+ * SAX wrapper around Expat. Interns strings. Does not support validation.
+ * Does not support {@link DTDHandler}.
+ */
+public class ExpatReader implements XMLReader {
+
+    private static final Logger logger
+            = Logger.getLogger(ExpatReader.class.getName());
+
+    /*
+     * ExpatParser accesses these fields directly during parsing. The user
+     * should be able to safely change them during parsing.
+     */
+    /*package*/ ContentHandler contentHandler;
+    /*package*/ EntityResolver entityResolver;
+    /*package*/ ErrorHandler errorHandler;
+    /*package*/ LexicalHandler lexicalHandler;
+
+    private boolean processNamespaces = true;
+    private boolean processNamespacePrefixes = false;
+
+    private static final String LEXICAL_HANDLER_PROPERTY
+            = "http://xml.org/sax/properties/lexical-handler";
+
+    private static class Feature {
+
+        private static final String BASE_URI = "http://xml.org/sax/features/";
+
+        private static final String VALIDATION = BASE_URI + "validation";
+        private static final String NAMESPACES = BASE_URI + "namespaces";
+        private static final String NAMESPACE_PREFIXES
+                = BASE_URI + "namespace-prefixes";
+        private static final String STRING_INTERNING
+                = BASE_URI + "string-interning";
+    }
+
+    public boolean getFeature(String name)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        if (name.equals(Feature.VALIDATION)) {
+            return false;
+        }
+
+        if (name.equals(Feature.NAMESPACES)) {
+            return processNamespaces;
+        }
+
+        if (name.equals(Feature.NAMESPACE_PREFIXES)) {
+            return processNamespacePrefixes;
+        }
+
+        if (name.equals(Feature.STRING_INTERNING)) {
+            return true;
+        }
+
+        throw new SAXNotRecognizedException(name);
+    }
+
+    public void setFeature(String name, boolean value)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        if (name.equals(Feature.VALIDATION)) {
+            if (value) {
+                throw new SAXNotSupportedException("Cannot enable " + name);
+            } else {
+                // Default.
+                return;
+            }
+        }
+
+        if (name.equals(Feature.NAMESPACES)) {
+            processNamespaces = value;
+            return;
+        }
+
+        if (name.equals(Feature.NAMESPACE_PREFIXES)) {
+            processNamespacePrefixes = value;
+            return;
+        }
+
+        if (name.equals(Feature.STRING_INTERNING)) {
+            if (value) {
+                // Default.
+                return;
+            } else {
+                throw new SAXNotSupportedException("Cannot disable " + name);
+            }
+        }
+
+        throw new SAXNotRecognizedException(name);
+    }
+
+    public Object getProperty(String name)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
+            return lexicalHandler;
+        }
+
+        throw new SAXNotRecognizedException(name);
+    }
+
+    public void setProperty(String name, Object value)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
+            // The object must implement LexicalHandler
+            if (value instanceof LexicalHandler) {
+                this.lexicalHandler = (LexicalHandler) value;
+                return;
+            }
+            throw new SAXNotSupportedException("value doesn't implement " +
+                    "org.xml.sax.ext.LexicalHandler");
+        }
+
+        throw new SAXNotRecognizedException(name);
+    }
+
+    public void setEntityResolver(EntityResolver resolver) {
+        this.entityResolver = resolver;
+    }
+
+    public EntityResolver getEntityResolver() {
+        return entityResolver;
+    }
+
+    /**
+     * Not implemented.
+     */
+    public void setDTDHandler(DTDHandler ignored) {
+        logger.warning("DTD handlers aren't supported.");
+    }
+
+    /**
+     * Always returns null.
+     */
+    public DTDHandler getDTDHandler() {
+        return null;
+    }
+
+    public void setContentHandler(ContentHandler handler) {
+        this.contentHandler = handler;
+    }
+
+    public ContentHandler getContentHandler() {
+        return this.contentHandler;
+    }
+
+    public void setErrorHandler(ErrorHandler handler) {
+        this.errorHandler = handler;
+    }
+
+    public ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+    /**
+     * Returns the current lexical handler.
+     *
+     * @return the current lexical handler, or null if none has been registered
+     * @see #setLexicalHandler
+     */
+    public LexicalHandler getLexicalHandler() {
+        return lexicalHandler;
+    }
+
+    /**
+     * Registers a lexical event handler. Supports neither
+     * {@link LexicalHandler#startEntity(String)} nor
+     * {@link LexicalHandler#endEntity(String)}.
+     *
+     * <p>If the application does not register a lexical handler, all
+     * lexical 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 lexicalHandler listens for lexical events
+     * @see #getLexicalHandler()
+     */
+    public void setLexicalHandler(LexicalHandler lexicalHandler) {
+        this.lexicalHandler = lexicalHandler;
+    }
+
+    /**
+     * Returns true if this SAX parser processes namespaces.
+     *
+     * @see #setNamespaceProcessingEnabled(boolean)
+     */
+    public boolean isNamespaceProcessingEnabled() {
+        return processNamespaces;
+    }
+
+    /**
+     * Enables or disables namespace processing. Set to true by default. If you
+     * enable namespace processing, the parser will invoke
+     * {@link ContentHandler#startPrefixMapping(String, String)} and
+     * {@link ContentHandler#endPrefixMapping(String)}, and it will filter
+     * out namespace declarations from element attributes.
+     *
+     * @see #isNamespaceProcessingEnabled()
+     */
+    public void setNamespaceProcessingEnabled(boolean processNamespaces) {
+        this.processNamespaces = processNamespaces;
+    }
+
+    public void parse(InputSource input) throws IOException, SAXException {
+        if (processNamespacePrefixes == processNamespaces) {
+            /*
+             * Expat has XML_SetReturnNSTriplet, but that still doesn't
+             * include xmlns attributes like this feature requires. We may
+             * have to implement namespace processing ourselves if we want
+             * this (not too difficult). We obviously "support" namespace
+             * prefixes if namespaces are disabled.
+             */
+            throw new SAXNotSupportedException("The 'namespace-prefix' " +
+                    "feature is not supported while the 'namespaces' " +
+                    "feature is enabled.");
+        }
+
+        // Try the character stream.
+        Reader reader = input.getCharacterStream();
+        if (reader != null) {
+            try {
+                parse(reader, input.getPublicId(), input.getSystemId());
+            } finally {
+                // TODO: Don't eat original exception when close() throws.
+                reader.close();
+            }
+            return;
+        }
+
+        // Try the byte stream.
+        InputStream in = input.getByteStream();
+        String encoding = input.getEncoding();
+        if (in != null) {
+            try {
+                parse(in, encoding, input.getPublicId(), input.getSystemId());
+            } finally {
+                // TODO: Don't eat original exception when close() throws.
+                in.close();
+            }
+            return;
+        }
+
+        String systemId = input.getSystemId();
+        if (systemId == null) {
+            throw new SAXException("No input specified.");
+        }
+
+        // Try the system id.
+        in = ExpatParser.openUrl(systemId);
+        try {
+            parse(in, encoding, input.getPublicId(), systemId);
+        } finally {
+            in.close();
+        }
+    }
+
+    private void parse(Reader in, String publicId, String systemId)
+            throws IOException, SAXException {
+        ExpatParser parser = new ExpatParser(
+                ExpatParser.CHARACTER_ENCODING,
+                this,
+                processNamespaces,
+                publicId,
+                systemId
+        );
+        parser.parseDocument(in);
+    }
+
+    private void parse(InputStream in, String encoding, String publicId,
+            String systemId) throws IOException, SAXException {
+        ExpatParser parser = new ExpatParser(
+                encoding,
+                this,
+                processNamespaces,
+                publicId,
+                systemId
+        );
+        parser.parseDocument(in);
+    }
+
+    public void parse(String systemId) throws IOException, SAXException {
+        parse(new InputSource(systemId));
+    }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
new file mode 100644
index 0000000..a39e0c4
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class AttrImpl extends NodeImpl implements Attr {
+
+    // Maintained by ElementImpl.
+    ElementImpl ownerElement;
+
+    private boolean namespaceAware;
+    
+    private String namespaceURI;
+
+    private String localName;
+
+    private String prefix;
+    
+    private String value;
+
+    AttrImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
+        super(document);
+
+        namespaceAware = true;
+        this.namespaceURI = namespaceURI;
+
+        if (qualifiedName == null || "".equals(qualifiedName)) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+        }
+        
+        int prefixSeparator = qualifiedName.lastIndexOf(":");
+        if (prefixSeparator != -1) {
+            setPrefix(qualifiedName.substring(0, prefixSeparator));
+            qualifiedName = qualifiedName.substring(prefixSeparator + 1);
+        }
+
+        localName = qualifiedName;
+        
+        if ("".equals(localName)) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, localName);
+        }
+        
+        if ("xmlns".equals(localName) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, localName);
+        }
+            
+        if (!document.isXMLIdentifier(localName)) {
+            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName);
+        }
+            
+        value = "";
+    }
+
+    AttrImpl(DocumentImpl document, String name) {
+        super(document);
+
+        this.namespaceAware = false;
+        
+        int prefixSeparator = name.lastIndexOf(":");
+        if (prefixSeparator != -1) {
+            String prefix = name.substring(0, prefixSeparator);
+            String localName = name.substring(prefixSeparator + 1);
+            
+            if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+            }
+        } else {
+            if (!document.isXMLIdentifier(name)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+            }
+        }
+        
+        this.localName = name;
+    }
+    
+    @Override
+    public String getLocalName() {
+        return namespaceAware ? localName : null;
+    }
+
+    public String getName() {
+        return (prefix != null ? prefix + ":" : "") + localName;
+    }
+
+    @Override
+    public String getNamespaceURI() {
+        return namespaceURI;
+    }
+
+    @Override
+    public String getNodeName() {
+        return getName();
+    }
+
+    public short getNodeType() {
+        return Node.ATTRIBUTE_NODE;
+    }
+
+    @Override
+    public String getNodeValue() {
+        return getValue();
+    }
+
+    public Element getOwnerElement() {
+        return ownerElement;
+    }
+
+    @Override
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public boolean getSpecified() {
+        return value != null;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public void setNodeValue(String value) throws DOMException {
+        setValue(value);
+    }
+    
+    @Override
+    public void setPrefix(String prefix) {
+        if (!namespaceAware) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+        }
+        
+        if (prefix != null) {
+            if (namespaceURI == null || !document.isXMLIdentifier(prefix) || "xmlns".equals(prefix)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+            }
+
+            if ("xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+            }
+        }
+
+        this.prefix = prefix;
+    }
+    
+    public void setValue(String value) throws DOMException {
+        this.value = value;
+    }
+    
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
new file mode 100644
index 0000000..f54e5f4
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class CDATASectionImpl extends TextImpl implements CDATASection {
+
+    CDATASectionImpl(DocumentImpl document, String data) {
+        super(document, data);
+    }
+
+    @Override
+    public String getNodeName() {
+        return "#cdata-section";
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.CDATA_SECTION_NODE;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
new file mode 100644
index 0000000..010cb22
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public abstract class CharacterDataImpl extends LeafNodeImpl implements
+        CharacterData {
+
+    private StringBuffer buffer;
+
+    CharacterDataImpl(DocumentImpl document, String data) {
+        super(document);
+        setData(data);
+    }
+
+    public void appendData(String arg) throws DOMException {
+        buffer.append(arg);
+    }
+
+    public void deleteData(int offset, int count) throws DOMException {
+        buffer.delete(offset, offset + count);
+    }
+
+    public String getData() throws DOMException {
+        return buffer.toString();
+    }
+
+    public int getLength() {
+        return buffer.length();
+    }
+
+    @Override
+    public String getNodeValue() {
+        return getData();
+    }
+
+    public void insertData(int offset, String arg) throws DOMException {
+        try {
+            buffer.insert(offset, arg);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+        }
+    }
+
+    public void replaceData(int offset, int count, String arg)
+            throws DOMException {
+        try {
+            buffer.replace(offset, offset + count, arg);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+        }
+    }
+
+    public void setData(String data) throws DOMException {
+        buffer = new StringBuffer(data);
+    }
+
+    public String substringData(int offset, int count) throws DOMException {
+        try {
+            return buffer.substring(offset, offset + count);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+        }
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java
new file mode 100644
index 0000000..6c1f446
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class CommentImpl extends CharacterDataImpl implements Comment {
+
+    CommentImpl(DocumentImpl document, String data) {
+        super(document, data);
+    }
+
+    @Override
+    public String getNodeName() {
+        return "#comment";
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.COMMENT_NODE;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
new file mode 100644
index 0000000..4e13d19
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DOMImplementationImpl implements DOMImplementation {
+
+    // Singleton instance.
+    private static DOMImplementationImpl instance;
+
+    DOMImplementationImpl() {
+    }
+
+    public Document createDocument(String namespaceURI, String qualifiedName,
+            DocumentType doctype) throws DOMException {
+        return new DocumentImpl(this, namespaceURI, qualifiedName, doctype);
+    }
+
+    public DocumentType createDocumentType(String qualifiedName,
+            String publicId, String systemId) throws DOMException {
+        return new DocumentTypeImpl(this, qualifiedName, publicId, systemId);
+    }
+
+    public boolean hasFeature(String feature, String version) {
+        // We claim to support DOM Core Level 1 & 2, nothing else.
+
+        if ("Core".equalsIgnoreCase(feature) || "XML".equalsIgnoreCase(feature)) {
+            if (version == null || "".equals(version) || "1.0".equals(version) || "2.0".equals(version)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Requests the singleton instance of the class. Creates it first, if
+     * necessary.
+     * 
+     * @return The singleton Android DOMImplementationImpl instance.
+     */
+    public static DOMImplementationImpl getInstance() {
+        if (instance == null) {
+            instance = new DOMImplementationImpl();
+        }
+
+        return instance;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java
new file mode 100644
index 0000000..88e6175
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentFragmentImpl extends InnerNodeImpl implements
+        DocumentFragment {
+
+    DocumentFragmentImpl(DocumentImpl document) {
+        super(document);
+    }
+
+    @Override
+    public String getNodeName() {
+        return "#document-fragment";
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.DOCUMENT_FRAGMENT_NODE;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
new file mode 100644
index 0000000..fbb1cac
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentImpl extends InnerNodeImpl implements Document {
+
+    private DOMImplementation domImplementation;
+
+    DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
+            String qualifiedName, DocumentType doctype) {
+        super(null);
+
+        this.domImplementation = impl;
+        // this.document = this;
+        
+        if (doctype != null) {
+            appendChild(doctype);
+        }
+
+        if (qualifiedName != null) {
+            appendChild(createElementNS(namespaceURI, qualifiedName));
+        }
+    }
+
+    private static boolean isXMLIdentifierStart(char c) {
+        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_');
+    }
+
+    private static boolean isXMLIdentifierPart(char c) {
+        return isXMLIdentifierStart(c) || (c >= '0' && c <= '9') || (c == '-') || (c == '.');
+    }
+
+    static boolean isXMLIdentifier(String s) {
+        if (s.length() == 0) {
+            return false;
+        }
+        
+        if (!isXMLIdentifierStart(s.charAt(0))) {
+            return false;
+        }
+        
+        for (int i = 1; i < s.length(); i++) {
+            if (!isXMLIdentifierPart(s.charAt(i))) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Clones a node and (if requested) its children. The source node(s) may
+     * have been created by a different DocumentImpl or even DOM implementation.
+     * 
+     * @param node The node to clone.
+     * @param deep If true, a deep copy is created (including all child nodes).
+     * 
+     * @return The new node.
+     */
+    Node cloneNode(Node node, boolean deep) throws DOMException {
+        Node target;
+        
+        switch (node.getNodeType()) {
+            case Node.ATTRIBUTE_NODE: {
+                Attr source = (Attr)node;
+                target = createAttributeNS(source.getNamespaceURI(), source.getLocalName());
+                target.setPrefix(source.getPrefix());
+                target.setNodeValue(source.getNodeValue());
+                break;
+            }
+            case Node.CDATA_SECTION_NODE: {
+                CharacterData source = (CharacterData)node;
+                target = createCDATASection(source.getData());
+                break;
+            }
+            case Node.COMMENT_NODE: {
+                Comment source = (Comment)node;
+                target = createComment(source.getData());
+                break;
+            }
+            case Node.DOCUMENT_FRAGMENT_NODE: {
+                // Source is irrelevant in this case.
+                target = createDocumentFragment();
+                break;
+            }
+            case Node.DOCUMENT_NODE: {
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a Document node");
+            }
+            case Node.DOCUMENT_TYPE_NODE: {
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a DocumentType node");
+            }
+            case Node.ELEMENT_NODE: {
+                Element source = (Element)node;
+                target = createElementNS(source.getNamespaceURI(), source.getLocalName());
+                target.setPrefix(source.getPrefix());
+
+                NamedNodeMap map = source.getAttributes();
+                for (int i = 0; i < map.getLength(); i++) {
+                    Attr attr = (Attr)map.item(i);
+                    ((Element)target).setAttributeNodeNS((Attr)cloneNode(attr, deep));
+                }
+                break;
+            }
+            case Node.ENTITY_NODE: {
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone an Entity node");
+            }
+            case Node.ENTITY_REFERENCE_NODE: {
+                EntityReference source = (EntityReference)node;
+                target = createEntityReference(source.getNodeName());
+                break;
+            }
+            case Node.NOTATION_NODE: {
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a Notation node");
+            }
+            case Node.PROCESSING_INSTRUCTION_NODE: {
+                ProcessingInstruction source = (ProcessingInstruction)node;
+                target = createProcessingInstruction(source.getTarget(), source.getData());
+                break;
+            }
+            case Node.TEXT_NODE: {
+                Text source = (Text)node;
+                target = createTextNode(source.getData());
+                break;
+            }
+            default: {
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone unknown node type " + node.getNodeType() + " (" + node.getClass().getSimpleName() + ")");
+            }
+        }
+
+        if (deep) {
+            NodeList list = node.getChildNodes();
+            for (int i = 0; i < list.getLength(); i++) {
+                Node child = cloneNode(list.item(i), deep);
+                target.appendChild(child);
+            }
+        }
+        
+        return target;
+    }
+    
+    public AttrImpl createAttribute(String name) throws DOMException {
+        return new AttrImpl(this, name);
+    }
+
+    public Attr createAttributeNS(String namespaceURI, String qualifiedName)
+            throws DOMException {
+        return new AttrImpl(this, namespaceURI, qualifiedName);
+    }
+
+    public CDATASection createCDATASection(String data) throws DOMException {
+        return new CDATASectionImpl(this, data);
+    }
+
+    public Comment createComment(String data) {
+        return new CommentImpl(this, data);
+    }
+
+    public DocumentFragment createDocumentFragment() {
+        return new DocumentFragmentImpl(this);
+    }
+
+    public Element createElement(String tagName) throws DOMException {
+        return new ElementImpl(this, tagName);
+    }
+
+    public Element createElementNS(String namespaceURI, String qualifiedName)
+            throws DOMException {
+        return new ElementImpl(this, namespaceURI, qualifiedName);
+    }
+
+    public EntityReference createEntityReference(String name)
+            throws DOMException {
+        return new EntityReferenceImpl(this, name);
+    }
+
+    public ProcessingInstruction createProcessingInstruction(String target,
+            String data) throws DOMException {
+        return new ProcessingInstructionImpl(this, target, data);
+    }
+
+    public Text createTextNode(String data) {
+        return new TextImpl(this, data);
+    }
+
+    public DocumentType getDoctype() {
+        for (int i = 0; i < children.size(); i++) {
+            if (children.get(i) instanceof DocumentType) {
+                return (DocumentType) children.get(i);
+            }
+        }
+
+        return null;
+    }
+
+    public Element getDocumentElement() {
+        for (int i = 0; i < children.size(); i++) {
+            if (children.get(i) instanceof Element) {
+                return (Element) children.get(i);
+            }
+        }
+
+        return null;
+    }
+
+    public Element getElementById(String elementId) {
+        ElementImpl root = (ElementImpl) getDocumentElement();
+
+        return (root == null ? null : root.getElementById(elementId));
+    }
+
+    public NodeList getElementsByTagName(String tagname) {
+        ElementImpl root = (ElementImpl) getDocumentElement();
+
+        return (root == null ? new NodeListImpl()
+                : root.getElementsByTagName(tagname));
+    }
+
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+        ElementImpl root = (ElementImpl) getDocumentElement();
+
+        return (root == null ? new NodeListImpl() : root.getElementsByTagNameNS(
+                namespaceURI, localName));
+    }
+
+    public DOMImplementation getImplementation() {
+        return domImplementation;
+    }
+
+    @Override
+    public String getNodeName() {
+        return "#document";
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.DOCUMENT_NODE;
+    }
+
+    public Node importNode(Node importedNode, boolean deep) throws DOMException {
+        return cloneNode(importedNode, deep);
+    }
+
+    @Override
+    public Node insertChildAt(Node newChild, int index) throws DOMException {
+        // Make sure we have at most one root element and one DTD element.
+        if (newChild instanceof Element && getDocumentElement() != null) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+                    "Only one root element allowed");
+        } else if (newChild instanceof DocumentType && getDoctype() != null) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+                    "Only one DOCTYPE element allowed");
+        }
+
+        return super.insertChildAt(newChild, index);
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
new file mode 100644
index 0000000..df40d4b
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentTypeImpl extends LeafNodeImpl implements DocumentType {
+
+    private String qualifiedName;
+
+    private String publicId;
+
+    private String systemId;
+
+    DocumentTypeImpl(DOMImplementationImpl impl, String qualifiedName,
+            String publicId, String systemId) {
+        super(null);
+
+        if (qualifiedName == null || "".equals(qualifiedName)) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+        }
+        
+        int prefixSeparator = qualifiedName.lastIndexOf(":");
+        if (prefixSeparator != -1) {
+            String prefix = qualifiedName.substring(0, prefixSeparator);
+            String localName = qualifiedName.substring(prefixSeparator + 1);
+            
+            if (!DocumentImpl.isXMLIdentifier(prefix)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+            }
+
+            if (!DocumentImpl.isXMLIdentifier(localName)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+            }
+        } else {
+            if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+            }
+        }
+        
+        this.qualifiedName = qualifiedName;
+        this.publicId = publicId;
+        this.systemId = systemId;
+    }
+
+    @Override
+    public String getNodeName() {
+        return qualifiedName;
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.DOCUMENT_TYPE_NODE;
+    }
+
+    public NamedNodeMap getEntities() {
+        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        return null;
+    }
+
+    public String getInternalSubset() {
+        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        return null;
+    }
+
+    public String getName() {
+        return qualifiedName;
+    }
+
+    public NamedNodeMap getNotations() {
+        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        return null;
+    }
+
+    public String getPublicId() {
+        return publicId;
+    }
+
+    public String getSystemId() {
+        return systemId;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
new file mode 100644
index 0000000..3b44ff3
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class ElementImpl extends InnerNodeImpl implements Element {
+
+    private boolean namespaceAware;
+    
+    private String namespaceURI;
+
+    private String prefix;
+    
+    private String localName;
+
+    private List<AttrImpl> attributes = new ArrayList<AttrImpl>();
+
+    ElementImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
+        super(document);
+
+        this.namespaceAware = true;
+        this.namespaceURI = namespaceURI;
+
+        if (qualifiedName == null || "".equals(qualifiedName)) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+        }
+        
+        int p = qualifiedName.lastIndexOf(":");
+        if (p != -1) {
+            setPrefix(qualifiedName.substring(0, p));
+            qualifiedName = qualifiedName.substring(p + 1);
+        }
+        
+        if (!document.isXMLIdentifier(qualifiedName)) {
+            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+        }
+            
+        this.localName = qualifiedName;
+    }
+
+    ElementImpl(DocumentImpl document, String name) {
+        super(document);
+
+        this.namespaceAware = false;
+        
+        int p = name.lastIndexOf(":");
+        if (p != -1) {
+            String prefix = name.substring(0, p);
+            String localName = name.substring(p + 1);
+            
+            if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+            }
+        } else {
+            if (!document.isXMLIdentifier(name)) {
+                throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+            }
+        }
+        
+        this.localName = name;
+    }
+
+    private int indexOfAttribute(String name) {
+        for (int i = 0; i < attributes.size(); i++) {
+            AttrImpl attr = attributes.get(i);
+            if (attr.matchesName(name, false)) {
+                return i;
+            }
+        }
+        
+        return -1;
+    }
+    
+    private int indexOfAttributeNS(String namespaceURI, String localName) {
+        for (int i = 0; i < attributes.size(); i++) {
+            AttrImpl attr = attributes.get(i);
+            if (attr.matchesNameNS(namespaceURI, localName, false)) {
+                return i;
+            }
+        }
+        
+        return -1;
+    }
+    
+    public String getAttribute(String name) {
+        Attr attr = getAttributeNode(name);
+
+        if (attr == null) {
+            return "";
+        }
+
+        return attr.getValue();
+    }
+
+    public String getAttributeNS(String namespaceURI, String localName) {
+        Attr attr = getAttributeNodeNS(namespaceURI, localName);
+
+        if (attr == null) {
+            return "";
+        }
+
+        return attr.getValue();
+    }
+
+    public Attr getAttributeNode(String name) {
+        int i = indexOfAttribute(name);
+        
+        if (i == -1) {
+            return null;
+        }
+        
+        return attributes.get(i);
+    }
+
+    public Attr getAttributeNodeNS(String namespaceURI, String localName) {
+        int i = indexOfAttributeNS(namespaceURI, localName);
+        
+        if (i == -1) {
+            return null;
+        }
+        
+        return attributes.get(i);
+    }
+
+    @Override
+    public NamedNodeMap getAttributes() {
+        return new ElementAttrNamedNodeMapImpl();
+    }
+    
+    Element getElementById(String name) {
+        if (name.equals(getAttribute("id"))) {
+            return this;
+        }
+
+        for (NodeImpl node : children) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                Element element = ((ElementImpl) node).getElementById(name);
+                if (element != null) {
+                    return element;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public NodeList getElementsByTagName(String name) {
+        NodeListImpl list = new NodeListImpl();
+        getElementsByTagName(list, name);
+        return list;
+    }
+
+    void getElementsByTagName(NodeListImpl list, String name) {
+        if (matchesName(name, true)) {
+            list.add(this);
+        }
+
+        for (NodeImpl node : children) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                ((ElementImpl) node).getElementsByTagName(list, name);
+            }
+        }
+    }
+
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+        NodeListImpl list = new NodeListImpl();
+        getElementsByTagNameNS(list, namespaceURI, localName);
+        return list;
+    }
+
+    void getElementsByTagNameNS(NodeListImpl list, String namespaceURI,
+            String localName) {
+        if (matchesNameNS(namespaceURI, localName, true)) {
+            list.add(this);
+        }
+        
+        for (NodeImpl node : children) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                ((ElementImpl) node).getElementsByTagNameNS(list, namespaceURI,
+                        localName);
+            }
+        }
+    }
+
+    @Override
+    public String getLocalName() {
+        return namespaceAware ? localName : null;
+    }
+
+    @Override
+    public String getNamespaceURI() {
+        return namespaceURI;
+    }
+
+    @Override
+    public String getNodeName() {
+        return getTagName();
+    }
+
+    public short getNodeType() {
+        return Node.ELEMENT_NODE;
+    }
+
+    @Override
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public String getTagName() {
+        return (prefix != null ? prefix + ":" : "") + localName;
+    }
+
+    public boolean hasAttribute(String name) {
+        return indexOfAttribute(name) != -1;
+    }
+
+    public boolean hasAttributeNS(String namespaceURI, String localName) {
+        return indexOfAttributeNS(namespaceURI, localName) != -1;
+    }
+
+    @Override
+    public boolean hasAttributes() {
+        return !attributes.isEmpty();
+    }
+
+    public void removeAttribute(String name) throws DOMException {
+        int i = indexOfAttribute(name);
+        
+        if (i != -1) {
+            attributes.remove(i);
+        }
+    }
+
+    public void removeAttributeNS(String namespaceURI, String localName)
+            throws DOMException {
+        int i = indexOfAttributeNS(namespaceURI, localName);
+        
+        if (i != -1) {
+            attributes.remove(i);
+        }
+    }
+
+    public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+        AttrImpl oldAttrImpl = (AttrImpl) oldAttr;
+
+        if (oldAttrImpl.getOwnerElement() != this) {
+            throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+        }
+
+        attributes.remove(oldAttr);
+        oldAttrImpl.ownerElement = null;
+
+        return oldAttrImpl;
+    }
+
+    public void setAttribute(String name, String value) throws DOMException {
+        Attr attr = getAttributeNode(name);
+
+        if (attr == null) {
+            attr = document.createAttribute(name);
+            setAttributeNode(attr);
+        }
+
+        attr.setValue(value);
+    }
+
+    public void setAttributeNS(String namespaceURI, String qualifiedName,
+            String value) throws DOMException {
+        Attr attr = getAttributeNodeNS(namespaceURI, qualifiedName);
+
+        if (attr == null) {
+            attr = document.createAttributeNS(namespaceURI, qualifiedName);
+            setAttributeNodeNS(attr);
+        }
+
+        attr.setValue(value);
+    }
+
+    public Attr setAttributeNode(Attr newAttr) throws DOMException {
+        AttrImpl newAttrImpl = (AttrImpl) newAttr;
+        
+        if (newAttrImpl.document != this.getOwnerDocument()) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (newAttrImpl.getOwnerElement() != null) {
+            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+        }
+
+        AttrImpl oldAttrImpl = null;
+        
+        int i = indexOfAttribute(newAttr.getName());
+        if (i != -1) {
+            oldAttrImpl = attributes.get(i);
+            attributes.remove(i);
+        }
+        
+        attributes.add(newAttrImpl);
+        newAttrImpl.ownerElement = this;
+
+        return oldAttrImpl;
+    }
+
+    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+        AttrImpl newAttrImpl = (AttrImpl) newAttr;
+
+        if (newAttrImpl.document != this.getOwnerDocument()) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (newAttrImpl.getOwnerElement() != null) {
+            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+        }
+
+        AttrImpl oldAttrImpl = null;
+        
+        int i = indexOfAttributeNS(newAttr.getNamespaceURI(), newAttr.getLocalName());
+        if (i != -1) {
+            oldAttrImpl = attributes.get(i);
+            attributes.remove(i);
+        }
+        
+        attributes.add(newAttrImpl);
+        newAttrImpl.ownerElement = this;
+
+        return oldAttrImpl;
+    }
+
+    @Override
+    public void setPrefix(String prefix) {
+        if (!namespaceAware) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+        }
+        
+        if (prefix != null) {
+            if (namespaceURI == null || !document.isXMLIdentifier(prefix)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+            }
+            
+            if ("xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+            }
+        }
+        
+        this.prefix = prefix;
+    }
+    
+    public class ElementAttrNamedNodeMapImpl implements NamedNodeMap {
+
+        public int getLength() {
+            return ElementImpl.this.attributes.size();
+        }
+
+        private int indexOfItem(String name) {
+            return ElementImpl.this.indexOfAttribute(name);
+        }
+        
+        private int indexOfItemNS(String namespaceURI, String localName) {
+            return ElementImpl.this.indexOfAttributeNS(namespaceURI, localName);
+        }
+
+        public Node getNamedItem(String name) {
+            return ElementImpl.this.getAttributeNode(name);
+        }
+
+        public Node getNamedItemNS(String namespaceURI, String localName) {
+            return ElementImpl.this.getAttributeNodeNS(namespaceURI, localName);
+        }
+
+        public Node item(int index) {
+            return ElementImpl.this.attributes.get(index);
+        }
+
+        public Node removeNamedItem(String name) throws DOMException {
+            int i = indexOfItem(name);
+            
+            if (i == -1) {
+                throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+            }
+
+            return ElementImpl.this.attributes.remove(i);
+        }
+
+        public Node removeNamedItemNS(String namespaceURI, String localName)
+                throws DOMException {
+            int i = indexOfItemNS(namespaceURI, localName);
+            
+            if (i == -1) {
+                throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+            }
+
+            return ElementImpl.this.attributes.remove(i);
+        }
+
+        public Node setNamedItem(Node arg) throws DOMException {
+            if (!(arg instanceof Attr)) {
+                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+            }
+
+            return ElementImpl.this.setAttributeNode((Attr)arg);
+        }
+
+        public Node setNamedItemNS(Node arg) throws DOMException {
+            if (!(arg instanceof Attr)) {
+                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+            }
+            
+            return ElementImpl.this.setAttributeNodeNS((Attr)arg);
+        }
+    }
+    
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java
new file mode 100644
index 0000000..463e863
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Entity;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class EntityImpl extends NodeImpl implements Entity {
+
+    private String notationName;
+
+    private String publicID;
+
+    private String systemID;
+
+    EntityImpl(DocumentImpl document, String notationName, String publicID,
+            String systemID) {
+        super(document);
+        this.notationName = notationName;
+        this.publicID = publicID;
+        this.systemID = systemID;
+    }
+
+    @Override
+    public String getNodeName() {
+        return getNotationName();
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.ENTITY_NODE;
+    }
+
+    public String getNotationName() {
+        return notationName;
+    }
+
+    public String getPublicId() {
+        return publicID;
+    }
+
+    public String getSystemId() {
+        return systemID;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java
new file mode 100644
index 0000000..f612a15
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class EntityReferenceImpl extends LeafNodeImpl implements EntityReference {
+
+    private String name;
+
+    EntityReferenceImpl(DocumentImpl document, String name) {
+        super(document);
+        this.name = name;
+    }
+
+    @Override
+    public String getNodeName() {
+        return name;
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.ENTITY_REFERENCE_NODE;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
new file mode 100644
index 0000000..f71d289
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has a parent Node as well as (potentially)
+ * a number of children.
+ */
+public abstract class InnerNodeImpl extends LeafNodeImpl {
+
+    // Maintained by LeafNodeImpl and ElementImpl.
+    List<LeafNodeImpl> children = new ArrayList<LeafNodeImpl>();
+
+    public InnerNodeImpl(DocumentImpl document) {
+        super(document);
+    }
+
+    public Node appendChild(Node newChild) throws DOMException {
+        return insertChildAt(newChild, children.size());
+    }
+
+    public NodeList getChildNodes() {
+        NodeListImpl list = new NodeListImpl();
+
+        for (NodeImpl node : children) {
+            list.add(node);
+        }
+
+        return list;
+    }
+
+    public Node getFirstChild() {
+        return (!children.isEmpty() ? children.get(0) : null);
+    }
+
+    public Node getLastChild() {
+        return (!children.isEmpty() ? children.get(children.size() - 1) : null);
+    }
+
+    public Node getNextSibling() {
+        if (parent == null || index >= parent.children.size()) {
+            return null;
+        }
+
+        return parent.children.get(index + 1);
+    }
+
+    public boolean hasChildNodes() {
+        return children.size() != 0;
+    }
+
+    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+        LeafNodeImpl refChildImpl = (LeafNodeImpl) refChild;
+
+        if (refChildImpl.document != document) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (refChildImpl.parent != this) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+
+        return insertChildAt(newChild, refChildImpl.index);
+    }
+
+    /**
+     * Inserts a new child node into this node at a given position. If the new
+     * node is already child of another node, it is first removed from there.
+     * This method is the generalization of the appendChild() and insertBefore()
+     * methods.
+     * 
+     * @param newChild The new child node to add.
+     * @param index The index at which to insert the new child node.
+     * 
+     * @return The node added.
+     * 
+     * @throws DOMException If the attempted operation violates the XML/DOM
+     *         well-formedness rules.
+     */
+    public Node insertChildAt(Node newChild, int index) throws DOMException {
+        LeafNodeImpl newChildImpl = (LeafNodeImpl) newChild;
+
+        if (document != null && newChildImpl.document != null && newChildImpl.document != document) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (newChildImpl.isParentOf(this)) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+
+        if (newChildImpl.parent != null) {
+            int oldIndex = newChildImpl.index;
+            newChildImpl.parent.children.remove(oldIndex);
+            newChildImpl.parent.refreshIndices(oldIndex);
+        }
+
+        children.add(index, newChildImpl);
+        newChildImpl.parent = this;
+        refreshIndices(index);
+
+        return newChild;
+    }
+
+    public boolean isParentOf(Node node) {
+        LeafNodeImpl nodeImpl = (LeafNodeImpl) node;
+
+        while (nodeImpl != null) {
+            if (nodeImpl == this) {
+                return true;
+            }
+
+            nodeImpl = nodeImpl.parent;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void normalize() {
+        Node nextNode = null;
+        
+        for (int i = children.size() - 1; i >= 0; i--) {
+            Node thisNode = children.get(i);
+
+            thisNode.normalize();
+            
+            if (thisNode.getNodeType() == Node.TEXT_NODE) {
+                if (nextNode != null && nextNode.getNodeType() == Node.TEXT_NODE) {
+                    ((Text)thisNode).setData(thisNode.getNodeValue() + nextNode.getNodeValue());
+                    removeChild(nextNode);
+                }
+                
+                if ("".equals(thisNode.getNodeValue())) {
+                    removeChild(thisNode);
+                    nextNode = null;
+                } else {
+                    nextNode = thisNode;
+                }
+            }
+        }
+    }
+
+    private void refreshIndices(int fromIndex) {
+        for (int i = fromIndex; i < children.size(); i++) {
+            children.get(i).index = i;
+        }
+    }
+
+    public Node removeChild(Node oldChild) throws DOMException {
+        LeafNodeImpl oldChildImpl = (LeafNodeImpl) oldChild;
+
+        if (oldChildImpl.document != document) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (oldChildImpl.parent != this) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+
+        int index = oldChildImpl.index;
+        children.remove(index);
+        oldChildImpl.parent = null;
+        refreshIndices(index);
+
+        return oldChild;
+    }
+
+    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+        LeafNodeImpl oldChildImpl = (LeafNodeImpl) oldChild;
+        LeafNodeImpl newChildImpl = (LeafNodeImpl) newChild;
+
+        if (oldChildImpl.document != document
+                || newChildImpl.document != document) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        if (oldChildImpl.parent != this || newChildImpl.isParentOf(this)) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+
+        int index = oldChildImpl.index;
+        children.set(index, newChildImpl);
+        oldChildImpl.parent = null;
+        newChildImpl.parent = this;
+        refreshIndices(index);
+
+        return oldChildImpl;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java
new file mode 100644
index 0000000..5f9698e
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has a parent Node, but no children.
+ */
+public abstract class LeafNodeImpl extends NodeImpl {
+
+    // Maintained by InnerNodeImpl.
+    InnerNodeImpl parent;
+
+    // Maintained by InnerNodeImpl.
+    int index;
+
+    LeafNodeImpl(DocumentImpl document) {
+        super(document);
+    }
+
+    public Node getNextSibling() {
+        if (parent == null || index + 1 >= parent.children.size()) {
+            return null;
+        }
+
+        return parent.children.get(index + 1);
+    }
+
+    public Node getParentNode() {
+        return parent;
+    }
+
+    public Node getPreviousSibling() {
+        if (parent == null || index == 0) {
+            return null;
+        }
+
+        return parent.children.get(index - 1);
+    }
+
+    boolean isParentOf(Node node) {
+        return false;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java
new file mode 100644
index 0000000..0952d83
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NamedNodeMapImpl implements NamedNodeMap {
+
+    private Class<?> type;
+    
+    private List<NodeImpl> list;
+
+    NamedNodeMapImpl(Class<?> type) {
+        list = new ArrayList<NodeImpl>();
+        this.type = type;
+    }
+
+    NamedNodeMapImpl(List<NodeImpl> list, Class<?> type) {
+        this.list = list;
+        this.type = type;
+    }
+
+    public int getLength() {
+        return list.size();
+    }
+
+    private int indexOfItem(String name) {
+        for (int i = 0; i < list.size(); i++) {
+            NodeImpl node = list.get(i);
+            if (node.matchesName(name, false)) {
+                return i;
+            }
+        }
+        
+        return -1;
+    }
+    
+    private int indexOfItemNS(String namespaceURI, String localName) {
+        for (int i = 0; i < list.size(); i++) {
+            NodeImpl node = list.get(i);
+            if (node.matchesNameNS(namespaceURI, localName, false)) {
+                return i;
+            }
+        }
+        
+        return -1;
+    }
+
+    public Node getNamedItem(String name) {
+        int i = indexOfItem(name);
+        
+        return (i == -1 ? null : item(i));
+    }
+
+    public Node getNamedItemNS(String namespaceURI, String localName) {
+        int i = indexOfItemNS(namespaceURI, localName);
+        
+        return (i == -1 ? null : item(i));
+    }
+
+    public Node item(int index) {
+        return list.get(index);
+    }
+
+    public Node removeNamedItem(String name) throws DOMException {
+        int i = indexOfItem(name);
+        
+        if (i == -1) {
+            throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+        }
+
+        return list.remove(i);
+    }
+
+    public Node removeNamedItemNS(String namespaceURI, String localName)
+            throws DOMException {
+        int i = indexOfItemNS(namespaceURI, localName);
+        
+        if (i == -1) {
+            throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+        }
+
+        return list.remove(i);
+    }
+
+    public Node setNamedItem(Node arg) throws DOMException {
+        // Ensure we only accept nodes of the correct type.
+        if (!type.isAssignableFrom(arg.getClass())) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+        
+        // All nodes in the map must belong to the same document.
+        if (list.size() != 0) {
+            Document document = list.get(0).getOwnerDocument();
+
+            if (document != null && arg.getOwnerDocument() != document) {
+                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+            }
+        }
+
+// TODO Theoretically we should ensure that the nodes don't have a parent.
+//        if (newAttrImpl.getOwnerElement() != null) {
+//            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+//        }
+
+        int i = indexOfItem(arg.getNodeName());
+        
+        if (i != -1) {
+            list.remove(i);
+        }
+        
+        list.add((NodeImpl)arg);
+        return arg;
+    }
+
+    public Node setNamedItemNS(Node arg) throws DOMException {
+        // Ensure we only accept nodes of the correct type.
+        if (!type.isAssignableFrom(arg.getClass())) {
+            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+        }
+        
+        // All nodes in the map must belong to the same document.
+        if (list.size() != 0) {
+            Document document = list.get(0).getOwnerDocument();
+
+            if (document != null && arg.getOwnerDocument() != document) {
+                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+            }
+        }
+
+// TODO Theoretically we should ensure that the nodes don't have a parent.
+//        if (newAttrImpl.getOwnerElement() != null) {
+//            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+//        }
+
+        int i = indexOfItemNS(arg.getNamespaceURI(), arg.getLocalName());
+        
+        if (i != -1) {
+            list.remove(i);
+        }
+        
+        list.add((NodeImpl)arg);
+        return arg;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
new file mode 100644
index 0000000..ca6fb8f
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has neither a parent nor children.
+ */
+public abstract class NodeImpl implements Node {
+
+    private static final NodeList EMPTY_LIST = new NodeListImpl();
+    
+    // Maintained by InnerNodeImpl and ElementImpl.
+    DocumentImpl document;
+
+    NodeImpl(DocumentImpl document) {
+        this.document = document;
+    }
+
+    public Node appendChild(Node newChild) throws DOMException {
+        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+    }
+
+    public Node cloneNode(boolean deep) {
+        return document.cloneNode(this, deep);
+    }
+
+    public NamedNodeMap getAttributes() {
+        return null;
+    }
+
+    public NodeList getChildNodes() {
+        return EMPTY_LIST;
+    }
+
+    public Node getFirstChild() {
+        return null;
+    }
+
+    public Node getLastChild() {
+        return null;
+    }
+
+    public String getLocalName() {
+        return null;
+    }
+
+    public String getNamespaceURI() {
+        return null;
+    }
+
+    public Node getNextSibling() {
+        return null;
+    }
+
+    public String getNodeName() {
+        return null;
+    }
+
+    public abstract short getNodeType();
+
+    public String getNodeValue() throws DOMException {
+        return null;
+    }
+
+    public Document getOwnerDocument() {
+        return document;
+    }
+
+    public Node getParentNode() {
+        return null;
+    }
+
+    public String getPrefix() {
+        return null;
+    }
+
+    public Node getPreviousSibling() {
+        return null;
+    }
+
+    public boolean hasAttributes() {
+        return false;
+    }
+
+    public boolean hasChildNodes() {
+        return false;
+    }
+
+    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+    }
+
+    public boolean isSupported(String feature, String version) {
+        return DOMImplementationImpl.getInstance().hasFeature(feature, version);
+    }
+
+    public void normalize() {
+    }
+
+    public Node removeChild(Node oldChild) throws DOMException {
+        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+    }
+
+    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+    }
+
+    public void setNodeValue(String nodeValue) throws DOMException {
+    }
+
+    public void setPrefix(String prefix) throws DOMException {
+    }
+
+    /**
+     * Checks whether a required string matches an actual string. This utility
+     * method is used for comparing namespaces and such. It takes into account
+     * null arguments and the "*" special case.
+     * 
+     * @param required The required string.
+     * @param actual The actual string.
+     * @return True if and only if the actual string matches the required one.
+     */
+    private static boolean matchesName(String required, String actual, boolean wildcard) {
+        if (wildcard && "*".equals(required)) {
+            return true;
+        }
+        
+        if (required == null) {
+            return (actual == null);
+        }
+        
+        return required.equals(actual);
+    }
+
+    /**
+     * Checks whether this node's name matches a required name. It takes into
+     * account null arguments and the "*" special case.
+     * 
+     * @param name The required name.
+     * @param wildcard TODO
+     * @return True if and only if the actual name matches the required one.
+     */
+    public boolean matchesName(String name, boolean wildcard) {
+        return matchesName(name, getNodeName(), wildcard);
+    }
+
+    /**
+     * Checks whether this node's namespace and local name match a required
+     * pair of namespace and local name. It takes into account null arguments
+     * and the "*" special case.
+     *
+     * @param namespaceURI The required namespace.
+     * @param localName The required local name.
+     * @param wildcard TODO
+     * @return True if and only if the actual namespace and local name match
+     *         the required pair of namespace and local name.
+     */
+    public boolean matchesNameNS(String namespaceURI, String localName, boolean wildcard) {
+        return matchesName(namespaceURI, getNamespaceURI(), wildcard) && matchesName(localName, getLocalName(), wildcard);
+    }
+    
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java
new file mode 100644
index 0000000..caa56af
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NodeListImpl implements NodeList {
+
+    private List<NodeImpl> children;
+
+    NodeListImpl() {
+        children = new ArrayList<NodeImpl>();
+    }
+
+    NodeListImpl(List<NodeImpl> list) {
+        children = list;
+    }
+
+    void add(NodeImpl node) {
+        children.add(node);
+    }
+
+    public int getLength() {
+        return children.size();
+    }
+
+    public Node item(int index) {
+        if (index >= children.size()) {
+            return null;
+        } else {
+            return children.get(index);
+        }
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java
new file mode 100644
index 0000000..4d91d75
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.Notation;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NotationImpl extends LeafNodeImpl implements Notation {
+
+    private String notationName;
+
+    private String publicID;
+
+    private String systemID;
+
+    NotationImpl(DocumentImpl document, String notationName, String publicID,
+            String systemID) {
+        super(document);
+    }
+
+    @Override
+    public String getNodeName() {
+        return notationName;
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.NOTATION_NODE;
+    }
+
+    public String getPublicId() {
+        return publicID;
+    }
+
+    public String getSystemId() {
+        return systemID;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java
new file mode 100644
index 0000000..c3610d5
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class ProcessingInstructionImpl extends LeafNodeImpl implements
+        ProcessingInstruction {
+
+    private String target;
+
+    private String data;
+
+    ProcessingInstructionImpl(DocumentImpl document, String target, String data) {
+        super(document);
+        this.target = target;
+        this.data = data;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    @Override
+    public String getNodeName() {
+        return target;
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.PROCESSING_INSTRUCTION_NODE;
+    }
+
+    @Override
+    public String getNodeValue() {
+        return data;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public void setData(String data) throws DOMException {
+        this.data = data;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
new file mode 100644
index 0000000..3553546
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class TextImpl extends CharacterDataImpl implements Text {
+
+    TextImpl(DocumentImpl document, String data) {
+        super(document, data);
+    }
+
+    @Override
+    public String getNodeName() {
+        return "#text";
+    }
+
+    @Override
+    public short getNodeType() {
+        return Node.TEXT_NODE;
+    }
+
+    @Override
+    public String getNodeValue() {
+        return getData();
+    }
+
+    public Text splitText(int offset) throws DOMException {
+        Text newText = getOwnerDocument().createTextNode(
+                substringData(offset, getLength() - offset));
+        deleteData(0, offset);
+
+        Node refNode = getNextSibling();
+        if (refNode == null) {
+            getParentNode().appendChild(newText);
+        } else {
+            getParentNode().insertBefore(newText, refNode);
+        }
+
+        return this;
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java
new file mode 100644
index 0000000..4b8eef3
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * Provides a straightforward DocumentBuilderFactory implementation based on
+ * XMLPull/KXML. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented. Hope that's
+ * ok.
+ */
+public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
+
+    private static final String NAMESPACES =
+            "http://xml.org/sax/features/namespaces";
+
+    private static final String VALIDATION =
+            "http://xml.org/sax/features/validation";
+    
+    @Override
+    public Object getAttribute(String name) throws IllegalArgumentException {
+        throw new IllegalArgumentException(name);
+    }
+
+    @Override
+    public boolean getFeature(String name) throws ParserConfigurationException {
+        if (name == null) {
+            throw new NullPointerException();
+        }
+        
+        if (NAMESPACES.equals(name)) {
+            return isNamespaceAware();
+        } else if (VALIDATION.equals(name)) {
+            return isValidating();
+        } else {
+            throw new ParserConfigurationException(name);
+        }
+    }
+
+    @Override
+    public DocumentBuilder newDocumentBuilder()
+            throws ParserConfigurationException {
+        if (isValidating()) {
+            throw new ParserConfigurationException(
+                    "No validating DocumentBuilder implementation available");
+        }
+        
+        /**
+         * TODO If Android is going to support a different DocumentBuilder
+         * implementations, this should be wired here. If we wanted to
+         * allow different implementations, these could be distinguished by
+         * a special feature (like http://www.org.apache.harmony.com/xml/expat)
+         * or by throwing the full SPI monty at it.  
+         */
+        DocumentBuilderImpl builder = new DocumentBuilderImpl();
+        
+        builder.setIgnoreComments(isIgnoringComments());
+        builder.setIgnoreElementContentWhitespace(
+                isIgnoringElementContentWhitespace());
+        builder.setNamespaceAware(isNamespaceAware());
+
+        // TODO What about expandEntityReferences?
+        
+        return builder;
+    }
+    
+    @Override
+    public void setAttribute(String name, Object value)
+            throws IllegalArgumentException {
+        throw new IllegalArgumentException(name);
+    }
+
+    @Override
+    public void setFeature(String name, boolean value)
+            throws ParserConfigurationException {
+        if (name == null) {
+            throw new NullPointerException();
+        }
+
+        if (NAMESPACES.equals(name)) {
+            setNamespaceAware(value);
+        } else if (VALIDATION.equals(name)) {
+            setValidating(value);
+        } else {
+            throw new ParserConfigurationException(name);
+        }
+    }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
new file mode 100644
index 0000000..f831c8b
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.kxml2.io.KXmlParser;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.LocatorImpl;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import org.apache.harmony.xml.dom.DOMImplementationImpl;
+
+/**
+ * Provides a straightforward DocumentBuilder implementation based on
+ * XMLPull/KXML. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented. Hope that's
+ * ok.
+ */
+class DocumentBuilderImpl extends DocumentBuilder {
+
+    private static DOMImplementation dom = DOMImplementationImpl.getInstance();
+
+    private EntityResolver entityResolver;
+
+    private ErrorHandler errorHandler;
+
+    private boolean ignoreComments;
+
+    private boolean ignoreElementContentWhitespace;
+
+    private boolean namespaceAware;
+
+    DocumentBuilderImpl() {
+        // Do nothing.
+    }
+
+    @Override
+    public DOMImplementation getDOMImplementation() {
+        return dom;
+    }
+
+    /**
+     * Reflects whether this DocumentBuilder is configured to ignore comments.
+     * 
+     * @return True if and only if comments are ignored.
+     */
+    public boolean isIgnoringComments() {
+        return ignoreComments;
+    }
+
+    /**
+     * Reflects whether this DocumentBuilder is configured to ignore element
+     * content whitespace.
+     * 
+     * @return True if and only if whitespace element content is ignored.
+     */
+    public boolean isIgnoringElementContentWhitespace() {
+        return ignoreElementContentWhitespace;
+    }
+
+    @Override
+    public boolean isNamespaceAware() {
+        return namespaceAware;
+    }
+
+    @Override
+    public boolean isValidating() {
+        return false;
+    }
+
+    @Override
+    public Document newDocument() {
+        return dom.createDocument(null, null, null);
+    }
+
+    @Override
+    public Document parse(InputSource source) throws SAXException, IOException {
+        if (source == null) {
+            throw new IllegalArgumentException();
+        }
+        
+        Document document = newDocument();
+
+        try {
+            XmlPullParser parser = new KXmlParser();
+
+            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,
+                    namespaceAware);
+            
+            if (source.getByteStream() != null) {
+                parser.setInput(source.getByteStream(), source.getEncoding());
+            } else if (source.getCharacterStream() != null) {
+                parser.setInput(source.getCharacterStream());
+            } else {
+                // TODO Accept other sources as well?
+                throw new SAXParseException(
+                        "InputSource needs either stream or reader", null);
+            }
+
+            if(parser.nextToken() == XmlPullParser.END_DOCUMENT) {
+                throw new SAXParseException(
+                        "Unexpected end of document", null);
+            }
+
+            parse(parser, document, document, XmlPullParser.END_DOCUMENT);
+
+            parser.require(XmlPullParser.END_DOCUMENT, null, null);
+        } catch (XmlPullParserException ex) {
+            if(ex.getDetail() instanceof IOException) {
+                throw (IOException)ex.getDetail();
+            }
+            if(ex.getDetail() instanceof RuntimeException) {
+                throw (RuntimeException)ex.getDetail();
+            }
+            
+            LocatorImpl locator = new LocatorImpl();
+
+            locator.setPublicId(source.getPublicId());
+            locator.setSystemId(source.getSystemId());
+            locator.setLineNumber(ex.getLineNumber());
+            locator.setColumnNumber(ex.getColumnNumber());
+
+            SAXParseException newEx = new SAXParseException(ex.getMessage(),
+                    locator);
+
+            if (errorHandler != null) {
+                errorHandler.error(newEx);
+            }
+
+            throw newEx;
+        }
+
+        return document;
+    }
+
+    /**
+     * Implements the whole parsing of the XML document. The XML pull parser is
+     * actually more of a tokenizer, and we are doing a classical recursive
+     * descent parsing (the method invokes itself for XML elements). Our
+     * approach to parsing does accept some illegal documents (more than one
+     * root element, for example). The assumption is that the DOM implementation
+     * throws the proper exceptions in these cases.
+     * 
+     * @param parser The XML pull parser we're reading from.
+     * @param document The document we're building.
+     * @param node The node we're currently on (initially the document itself).
+     * @param endToken The token that will end this recursive call. Either
+     *        XmlPullParser.END_DOCUMENT or XmlPullParser.END_TAG.
+     * 
+     * @throws XmlPullParserException If a parsing error occurs.
+     * @throws IOException If a general IO error occurs.
+     */
+    private void parse(XmlPullParser parser, Document document, Node node,
+            int endToken) throws XmlPullParserException, IOException {
+
+        int token = parser.getEventType();
+
+        /*
+         * The main parsing loop. The precondition is that we are already on the
+         * token to be processed. This holds for each iteration of the loop, so
+         * the inner statements have to ensure that (in particular the recursive
+         * call).
+         */
+        while (token != endToken && token != XmlPullParser.END_DOCUMENT) {
+            if (token == XmlPullParser.PROCESSING_INSTRUCTION) {
+                /*
+                 * Found a processing instructions. We need to split the token
+                 * text at the first whitespace character.
+                 */
+                String text = parser.getText();
+
+                int dot = text.indexOf(' ');
+
+                String target = (dot != -1 ? text.substring(0, dot) : text);
+                String data = (dot != -1 ? text.substring(dot + 1) : "");
+
+                node.appendChild(document.createProcessingInstruction(target,
+                        data));
+            } else if (token == XmlPullParser.DOCDECL) {
+                /*
+                 * Found a document type declaration. Unfortunately KXML doesn't
+                 * have the necessary details. Do we parse it ourselves, or do
+                 * we silently ignore it, since it isn't mandatory in DOM 2
+                 * anyway?
+                 */
+                StringTokenizer tokenizer = new StringTokenizer(parser.getText());
+                if (tokenizer.hasMoreTokens()) {
+                    String name = tokenizer.nextToken();
+                    String pubid = null;
+                    String sysid = null;
+                    
+                    if (tokenizer.hasMoreTokens()) {
+                        String text = tokenizer.nextToken();
+                        
+                        if ("SYSTEM".equals(text)) {
+                            if (tokenizer.hasMoreTokens()) {
+                                sysid = tokenizer.nextToken();
+                            }
+                        } else if ("PUBLIC".equals(text)) {
+                            if (tokenizer.hasMoreTokens()) {
+                                pubid = tokenizer.nextToken();
+                            }
+                            if (tokenizer.hasMoreTokens()) {
+                                sysid = tokenizer.nextToken();
+                            }
+                        }
+                    }
+                    
+                    if (pubid != null && pubid.length() >= 2 && pubid.startsWith("\"") && pubid.endsWith("\"")) {
+                        pubid = pubid.substring(1, pubid.length() - 1);
+                    }
+                    
+                    if (sysid != null && sysid.length() >= 2 && sysid.startsWith("\"") && sysid.endsWith("\"")) {
+                        sysid = sysid.substring(1, sysid.length() - 1);
+                    }
+                    
+                    document.appendChild(dom.createDocumentType(name, pubid, sysid));
+                }
+                
+            } else if (token == XmlPullParser.COMMENT) {
+                /*
+                 * Found a comment. We simply take the token text, but we only
+                 * create a node if the client wants to see comments at all.
+                 */
+                if (!ignoreComments) {
+                    node.appendChild(document.createComment(parser.getText()));
+                }
+            } else if (token == XmlPullParser.IGNORABLE_WHITESPACE) {
+                /*
+                 * Found some ignorable whitespace. We simply take the token
+                 * text, but we only create a node if the client wants to see
+                 * whitespace at all.
+                 */
+                if (!ignoreElementContentWhitespace) {
+                    node.appendChild(document.createTextNode(parser.getText()));
+                }
+            } else if (token == XmlPullParser.TEXT) {
+                /*
+                 * Found a piece of text. That's the easiest case. We simply
+                 * take it and create a corresponding node.
+                 */
+                node.appendChild(document.createTextNode(parser.getText()));
+            } else if (token == XmlPullParser.CDSECT) {
+                /*
+                 * Found a CDATA section. That's also trivial. We simply
+                 * take it and create a corresponding node.
+                 */
+                node.appendChild(document.createCDATASection(parser.getText()));
+            } else if (token == XmlPullParser.ENTITY_REF) {
+                /*
+                 * Found an entity reference. If an entity resolver is
+                 * installed, we replace it by text (if possible). Otherwise we
+                 * add an entity reference node.
+                 */
+                String entity = parser.getName();
+
+                if (entityResolver != null) {
+                    // TODO Implement this...
+                }
+
+                String replacement = resolveStandardEntity(entity);
+                if (replacement != null) {
+                    node.appendChild(document.createTextNode(replacement));
+                } else {
+                    node.appendChild(document.createEntityReference(entity));
+                }
+            } else if (token == XmlPullParser.START_TAG) {
+                /*
+                 * Found an element start tag. We create an element node with
+                 * the proper info and attributes. We then invoke parse()
+                 * recursively to handle the next level of nesting. When we
+                 * return from this call, we check that we are on the proper
+                 * element end tag. The whole handling differs somewhat
+                 * depending on whether the parser is namespace-aware or not.
+                 */
+                if (namespaceAware) {
+                    // Collect info for element node
+                    String namespace = parser.getNamespace();
+                    String name = parser.getName();
+                    String prefix = parser.getPrefix();
+
+                    if ("".equals(namespace)) {
+                        namespace = null;
+                    }
+                    
+                    // Create element node and wire it correctly
+                    Element element = document.createElementNS(namespace, name);
+                    element.setPrefix(prefix);
+                    node.appendChild(element);
+
+                    for (int i = 0; i < parser.getAttributeCount(); i++) {
+                        // Collect info for a single attribute node
+                        String attrNamespace = parser.getAttributeNamespace(i);
+                        String attrPrefix = parser.getAttributePrefix(i);
+                        String attrName = parser.getAttributeName(i);
+                        String attrValue = parser.getAttributeValue(i);
+
+                        if ("".equals(attrNamespace)) {
+                            attrNamespace = null;
+                        }
+                        
+                        // Create attribute node and wire it correctly
+                        Attr attr = document.createAttributeNS(attrNamespace, attrName);
+                        attr.setPrefix(attrPrefix);
+                        attr.setValue(attrValue);
+                        element.setAttributeNodeNS(attr);
+                    }
+                    
+                    // Recursive descent
+                    token = parser.nextToken();
+                    parse(parser, document, element, XmlPullParser.END_TAG);
+
+                    // Expect the element's end tag here
+                    parser.require(XmlPullParser.END_TAG, namespace, name);
+                    
+                } else {
+                    // Collect info for element node
+                    String name = parser.getName();
+
+                    // Create element node and wire it correctly
+                    Element element = document.createElement(name);
+                    node.appendChild(element);
+
+                    for (int i = 0; i < parser.getAttributeCount(); i++) {
+                        // Collect info for a single attribute node
+                        String attrName = parser.getAttributeName(i);
+                        String attrValue = parser.getAttributeValue(i);
+
+                        // Create attribute node and wire it correctly
+                        Attr attr = document.createAttribute(attrName);
+                        attr.setValue(attrValue);
+                        element.setAttributeNode(attr);
+                    }
+
+                    // Recursive descent
+                    token = parser.nextToken();
+                    parse(parser, document, element, XmlPullParser.END_TAG);
+
+                    // Expect the element's end tag here
+                    parser.require(XmlPullParser.END_TAG, "", name);
+                }
+            }
+
+            token = parser.nextToken();
+        }
+    }
+
+    @Override
+    public void setEntityResolver(EntityResolver resolver) {
+        entityResolver = resolver;
+    }
+
+    @Override
+    public void setErrorHandler(ErrorHandler handler) {
+        errorHandler = handler;
+    }
+
+    /**
+     * Controls whether this DocumentBuilder ignores comments.
+     * 
+     * @param value Turns comment ignorance on or off.
+     */
+    public void setIgnoreComments(boolean value) {
+        ignoreComments = value;
+    }
+
+    /**
+     * Controls whether this DocumentBuilder ignores element content whitespace.
+     * 
+     * @param value Turns element whitespace content ignorance on or off.
+     */
+    public void setIgnoreElementContentWhitespace(boolean value) {
+        ignoreElementContentWhitespace = value;
+    }
+
+    /**
+     * Controls whether this DocumentBuilder is namespace-aware.
+     * 
+     * @param value Turns namespace awareness on or off.
+     */
+    public void setNamespaceAware(boolean value) {
+        namespaceAware = value;
+    }
+
+    /**
+     * Resolves one of the five standard XML entities.
+     * 
+     * @param entity The name of the entity to resolve, not including
+     *               the ampersand or the semicolon.
+     * 
+     * @return The proper replacement, or null, if the entity is unknown.
+     */
+    private String resolveStandardEntity(String entity) {
+        if ("lt".equals(entity)) {
+            return "<";
+        } else if ("gt".equals(entity)) {
+            return ">";
+        } else if ("amp".equals(entity)) {
+            return "&";
+        } else if ("apos".equals(entity)) {
+            return "'";
+        } else if ("quot".equals(entity)) {
+            return "\"";
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java
new file mode 100644
index 0000000..6846216
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXNotRecognizedException;
+
+/**
+ * Provides a straightforward SAXParserFactory implementation based on
+ * Expat. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented.
+ */
+public class SAXParserFactoryImpl extends SAXParserFactory {
+
+    private static final String NAMESPACES
+            = "http://xml.org/sax/features/namespaces";
+    
+    private static final String VALIDATION
+            = "http://xml.org/sax/features/validation";
+    
+    private Map<String, Boolean> features = new HashMap<String, Boolean>();
+
+    @Override
+    public boolean getFeature(String name) throws SAXNotRecognizedException {
+        if (name == null) {
+            throw new NullPointerException();
+        }
+        
+        if (!name.startsWith("http://xml.org/sax/features/")) {
+            throw new SAXNotRecognizedException(name);
+        }
+        
+        return Boolean.TRUE.equals(features.get(name));
+    }
+
+    @Override
+    public boolean isNamespaceAware() {
+        try {
+            return getFeature(NAMESPACES);
+        } catch (SAXNotRecognizedException ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Override
+    public boolean isValidating() {
+        try {
+            return getFeature(VALIDATION);
+        } catch (SAXNotRecognizedException ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Override
+    public SAXParser newSAXParser() throws ParserConfigurationException {
+        if (isValidating()) {
+            throw new ParserConfigurationException(
+                    "No validating SAXParser implementation available");
+        }
+        
+        try {
+            return new SAXParserImpl(features);
+        } catch (Exception ex) {
+            throw new ParserConfigurationException(ex.toString());
+        }
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
+        if (name == null) {
+            throw new NullPointerException();
+        }
+        
+        if (!name.startsWith("http://xml.org/sax/features/")) {
+            throw new SAXNotRecognizedException(name);
+        }
+        
+        if (value) {
+            features.put(name, Boolean.TRUE);
+        } else {
+            // This is needed to disable features that are enabled by default.
+            features.put(name, Boolean.FALSE);
+        }
+    }
+
+    @Override
+    public void setNamespaceAware(boolean value) {
+        try {
+            setFeature(NAMESPACES, value);
+        } catch (SAXNotRecognizedException ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Override
+    public void setValidating(boolean value) {
+        try {
+            setFeature(VALIDATION, value);
+        } catch (SAXNotRecognizedException ex) {
+            throw new AssertionError(ex);
+        }
+    }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
new file mode 100644
index 0000000..b3af61f
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import org.apache.harmony.xml.ExpatReader;
+
+import java.util.Map;
+
+import javax.xml.parsers.SAXParser;
+
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderAdapter;
+
+/**
+ * Provides a straightforward SAXParser implementation based on ExpatReader.
+ * The class is used internally only, thus only notable members that are not
+ * already in the abstract superclass are documented. Hope that's ok.
+ */
+class SAXParserImpl extends SAXParser {
+
+    private XMLReader reader;
+
+    private Parser parser;
+
+    SAXParserImpl(Map<String, Boolean> features)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        reader = new ExpatReader();
+
+        for (Map.Entry<String,Boolean> entry : features.entrySet()) {
+            reader.setFeature(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    public Parser getParser() {
+        if (parser == null) {
+            parser = new XMLReaderAdapter(reader);
+        }
+
+        return parser;
+    }
+
+    @Override
+    public Object getProperty(String name) throws SAXNotRecognizedException,
+            SAXNotSupportedException {
+        return reader.getProperty(name);
+    }
+
+    @Override
+    public XMLReader getXMLReader() {
+        return reader;
+    }
+
+    @Override
+    public boolean isNamespaceAware() {
+        try {
+            return reader.getFeature("http://xml.org/sax/features/namespaces");
+        } catch (SAXException ex) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isValidating() {
+        return false;
+    }
+
+    @Override
+    public void setProperty(String name, Object value)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        reader.setProperty(name, value);
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
new file mode 100644
index 0000000..0727bc7
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/io/KXmlParser.java
@@ -0,0 +1,1440 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+// Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
+
+package org.kxml2.io;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+/** A simple, pull based XML parser. This classe replaces the kXML 1
+    XmlParser class and the corresponding event classes. */
+
+public class KXmlParser implements XmlPullParser {
+
+    private Object location;
+    static final private String UNEXPECTED_EOF = "Unexpected EOF";
+    static final private String ILLEGAL_TYPE = "Wrong event type";
+    static final private int LEGACY = 999;
+    static final private int XML_DECL = 998;
+
+    // general
+
+    private String version;
+    private Boolean standalone;
+
+    private boolean processNsp;
+    private boolean relaxed;
+    private Hashtable entityMap;
+    private int depth;
+    private String[] elementStack = new String[16];
+    private String[] nspStack = new String[8];
+    private int[] nspCounts = new int[4];
+
+    // source
+
+    private Reader reader;
+    private String encoding;
+    private char[] srcBuf;
+
+    private int srcPos;
+    private int srcCount;
+
+    private int line;
+    private int column;
+
+    // txtbuffer
+
+    private char[] txtBuf = new char[128];
+    private int txtPos;
+
+    // Event-related
+
+    private int type;
+    //private String text;
+    private boolean isWhitespace;
+    private String namespace;
+    private String prefix;
+    private String name;
+
+    private boolean degenerated;
+    private int attributeCount;
+    private String[] attributes = new String[16];
+    private int stackMismatch = 0;
+    private String error;
+
+    /** 
+     * A separate peek buffer seems simpler than managing
+     * wrap around in the first level read buffer */
+
+    private int[] peek = new int[2];
+    private int peekCount;
+    private boolean wasCR;
+
+    private boolean unresolved;
+    private boolean token;
+
+    public KXmlParser() {
+        // BEGIN android-changed
+        // We don't have a Runtime class at this time.
+        // srcBuf =
+        //         new char[Runtime.getRuntime().freeMemory() >= 1048576 ? 8192 : 128];
+        srcBuf = new char[8192];
+        // END android-changed
+    }
+
+    private final boolean isProp(String n1, boolean prop, String n2) {
+        if (!n1.startsWith("http://xmlpull.org/v1/doc/"))
+            return false;
+        if (prop)
+            return n1.substring(42).equals(n2);
+        else
+            return n1.substring(40).equals(n2);
+    }
+
+    private final boolean adjustNsp() throws XmlPullParserException {
+
+        boolean any = false;
+
+        for (int i = 0; i < attributeCount << 2; i += 4) {
+            // * 4 - 4; i >= 0; i -= 4) {
+
+            String attrName = attributes[i + 2];
+            int cut = attrName.indexOf(':');
+            String prefix;
+
+            if (cut != -1) {
+                prefix = attrName.substring(0, cut);
+                attrName = attrName.substring(cut + 1);
+            }
+            else if (attrName.equals("xmlns")) {
+                prefix = attrName;
+                attrName = null;
+            }
+            else
+                continue;
+
+            if (!prefix.equals("xmlns")) {
+                any = true;
+            }
+            else {
+                int j = (nspCounts[depth]++) << 1;
+
+                nspStack = ensureCapacity(nspStack, j + 2);
+                nspStack[j] = attrName;
+                nspStack[j + 1] = attributes[i + 3];
+
+                if (attrName != null && attributes[i + 3].equals(""))
+                    error("illegal empty namespace");
+
+                //  prefixMap = new PrefixMap (prefixMap, attrName, attr.getValue ());
+
+                //System.out.println (prefixMap);
+
+                System.arraycopy(
+                    attributes,
+                    i + 4,
+                    attributes,
+                    i,
+                    ((--attributeCount) << 2) - i);
+
+                i -= 4;
+            }
+        }
+
+        if (any) {
+            for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
+
+                String attrName = attributes[i + 2];
+                int cut = attrName.indexOf(':');
+
+                if (cut == 0 && !relaxed)
+                    throw new RuntimeException(
+                        "illegal attribute name: " + attrName + " at " + this);
+
+                else if (cut != -1) {
+                    String attrPrefix = attrName.substring(0, cut);
+
+                    attrName = attrName.substring(cut + 1);
+
+                    String attrNs = getNamespace(attrPrefix);
+
+                    if (attrNs == null && !relaxed)
+                        throw new RuntimeException(
+                            "Undefined Prefix: " + attrPrefix + " in " + this);
+
+                    attributes[i] = attrNs;
+                    attributes[i + 1] = attrPrefix;
+                    attributes[i + 2] = attrName;
+
+                    /*
+                                        if (!relaxed) {
+                                            for (int j = (attributeCount << 2) - 4; j > i; j -= 4)
+                                                if (attrName.equals(attributes[j + 2])
+                                                    && attrNs.equals(attributes[j]))
+                                                    exception(
+                                                        "Duplicate Attribute: {"
+                                                            + attrNs
+                                                            + "}"
+                                                            + attrName);
+                                        }
+                        */
+                }
+            }
+        }
+
+        int cut = name.indexOf(':');
+
+        if (cut == 0)
+            error("illegal tag name: " + name);
+
+        if (cut != -1) {
+            prefix = name.substring(0, cut);
+            name = name.substring(cut + 1);
+        }
+
+        this.namespace = getNamespace(prefix);
+
+        if (this.namespace == null) {
+            if (prefix != null)
+                error("undefined prefix: " + prefix);
+            this.namespace = NO_NAMESPACE;
+        }
+
+        return any;
+    }
+
+    private final String[] ensureCapacity(String[] arr, int required) {
+        if (arr.length >= required)
+            return arr;
+        String[] bigger = new String[required + 16];
+        System.arraycopy(arr, 0, bigger, 0, arr.length);
+        return bigger;
+    }
+
+    private final void error(String desc) throws XmlPullParserException {
+        if (relaxed) {
+            if (error == null)
+                error = "ERR: " + desc;
+        }
+        else
+            exception(desc);
+    }
+
+    private final void exception(String desc) throws XmlPullParserException {
+        throw new XmlPullParserException(
+            desc.length() < 100 ? desc : desc.substring(0, 100) + "\n",
+            this,
+            null);
+    }
+
+    /** 
+     * common base for next and nextToken. Clears the state, except from 
+     * txtPos and whitespace. Does not set the type variable */
+
+    private final void nextImpl() throws IOException, XmlPullParserException {
+
+        if (reader == null)
+            exception("No Input specified");
+
+        if (type == END_TAG)
+            depth--;
+
+        while (true) {
+            attributeCount = -1;
+
+            // degenerated needs to be handled before error because of possible
+            // processor expectations(!)
+
+            if (degenerated) {
+                degenerated = false;
+                type = END_TAG;
+                return;
+            }
+
+
+            if (error != null) {
+                for (int i = 0; i < error.length(); i++)
+                    push(error.charAt(i));
+                //                text = error;
+                error = null;
+                type = COMMENT;
+                return;
+            }
+
+
+            if (relaxed
+                && (stackMismatch > 0 || (peek(0) == -1 && depth > 0))) {
+                int sp = (depth - 1) << 2;
+                type = END_TAG;
+                namespace = elementStack[sp];
+                prefix = elementStack[sp + 1];
+                name = elementStack[sp + 2];
+                if (stackMismatch != 1)
+                    error = "missing end tag /" + name + " inserted";
+                if (stackMismatch > 0)
+                    stackMismatch--;
+                return;
+            }
+
+            prefix = null;
+            name = null;
+            namespace = null;
+            //            text = null;
+
+            type = peekType();
+
+            switch (type) {
+
+                case ENTITY_REF :
+                    pushEntity();
+                    return;
+
+                case START_TAG :
+                    parseStartTag(false);
+                    return;
+
+                case END_TAG :
+                    parseEndTag();
+                    return;
+
+                case END_DOCUMENT :
+                    return;
+
+                case TEXT :
+                    pushText('<', !token);
+                    if (depth == 0) {
+                        if (isWhitespace)
+                            type = IGNORABLE_WHITESPACE;
+                        // make exception switchable for instances.chg... !!!!
+                        //    else 
+                        //    exception ("text '"+getText ()+"' not allowed outside root element");
+                    }
+                    return;
+
+                default :
+                    type = parseLegacy(token);
+                    if (type != XML_DECL)
+                        return;
+            }
+        }
+    }
+
+    private final int parseLegacy(boolean push)
+        throws IOException, XmlPullParserException {
+
+        String req = "";
+        int term;
+        int result;
+        int prev = 0;
+
+        read(); // <
+        int c = read();
+
+        if (c == '?') {
+            if ((peek(0) == 'x' || peek(0) == 'X')
+                && (peek(1) == 'm' || peek(1) == 'M')) {
+
+                if (push) {
+                    push(peek(0));
+                    push(peek(1));
+                }
+                read();
+                read();
+
+                if ((peek(0) == 'l' || peek(0) == 'L') && peek(1) <= ' ') {
+
+                    if (line != 1 || column > 4)
+                        error("PI must not start with xml");
+
+                    parseStartTag(true);
+
+                    if (attributeCount < 1 || !"version".equals(attributes[2]))
+                        error("version expected");
+
+                    version = attributes[3];
+
+                    int pos = 1;
+
+                    if (pos < attributeCount
+                        && "encoding".equals(attributes[2 + 4])) {
+                        encoding = attributes[3 + 4];
+                        pos++;
+                    }
+
+                    if (pos < attributeCount
+                        && "standalone".equals(attributes[4 * pos + 2])) {
+                        String st = attributes[3 + 4 * pos];
+                        if ("yes".equals(st))
+                            standalone = new Boolean(true);
+                        else if ("no".equals(st))
+                            standalone = new Boolean(false);
+                        else
+                            error("illegal standalone value: " + st);
+                        pos++;
+                    }
+
+                    if (pos != attributeCount)
+                        error("illegal xmldecl");
+
+                    isWhitespace = true;
+                    txtPos = 0;
+
+                    return XML_DECL;
+                }
+            }
+
+            /*            int c0 = read ();
+                        int c1 = read ();
+                        int */
+
+            term = '?';
+            result = PROCESSING_INSTRUCTION;
+        }
+        else if (c == '!') {
+            if (peek(0) == '-') {
+                result = COMMENT;
+                req = "--";
+                term = '-';
+            }
+            else if (peek(0) == '[') {
+                result = CDSECT;
+                req = "[CDATA[";
+                term = ']';
+                push = true;
+            }
+            else {
+                result = DOCDECL;
+                req = "DOCTYPE";
+                term = -1;
+            }
+        }
+        else {
+            error("illegal: <" + c);
+            return COMMENT;
+        }
+
+        for (int i = 0; i < req.length(); i++)
+            read(req.charAt(i));
+
+        if (result == DOCDECL)
+            parseDoctype(push);
+        else {
+            while (true) {
+                c = read();
+                if (c == -1){
+                    error(UNEXPECTED_EOF);
+                    return COMMENT;
+                }
+
+                if (push)
+                    push(c);
+
+                if ((term == '?' || c == term)
+                    && peek(0) == term
+                    && peek(1) == '>')
+                    break;
+
+                prev = c;
+            }
+
+            if (term == '-' && prev == '-')
+                error("illegal comment delimiter: --->");
+
+            read();
+            read();
+
+            if (push && term != '?')
+                txtPos--;
+
+        }
+        return result;
+    }
+
+    /** precondition: &lt! consumed */
+
+    private final void parseDoctype(boolean push)
+        throws IOException, XmlPullParserException {
+
+        int nesting = 1;
+        boolean quoted = false;
+
+        // read();
+
+        while (true) {
+            int i = read();
+            switch (i) {
+
+                case -1 :
+                    error(UNEXPECTED_EOF);
+                    return;
+
+                case '\'' :
+                    quoted = !quoted;
+                    break;
+
+                case '<' :
+                    if (!quoted)
+                        nesting++;
+                    break;
+
+                case '>' :
+                    if (!quoted) {
+                        if ((--nesting) == 0)
+                            return;
+                    }
+                    break;
+            }
+            if (push)
+                push(i);
+        }
+    }
+
+    /* precondition: &lt;/ consumed */
+
+    private final void parseEndTag()
+        throws IOException, XmlPullParserException {
+
+        read(); // '<'
+        read(); // '/'
+        name = readName();
+        skip();
+        read('>');
+
+        int sp = (depth - 1) << 2;
+
+        if (depth == 0) {
+            error("element stack empty");
+            type = COMMENT;
+            return;
+        }
+
+        if (!name.equals(elementStack[sp + 3])) {
+            error("expected: /" + elementStack[sp + 3] + " read: " + name);
+
+            // become case insensitive in relaxed mode
+
+            int probe = sp;
+            while (probe >= 0 && !name.toLowerCase().equals(elementStack[probe + 3].toLowerCase())) {
+                stackMismatch++;
+                probe -= 4;
+            }
+
+            if (probe < 0) {
+                stackMismatch = 0;
+                //            text = "unexpected end tag ignored";
+                type = COMMENT;
+                return;
+            }
+        }
+
+        namespace = elementStack[sp];
+        prefix = elementStack[sp + 1];
+        name = elementStack[sp + 2];
+    }
+
+    private final int peekType() throws IOException {
+        switch (peek(0)) {
+            case -1 :
+                return END_DOCUMENT;
+            case '&' :
+                return ENTITY_REF;
+            case '<' :
+                switch (peek(1)) {
+                    case '/' :
+                        return END_TAG;
+                    case '?' :
+                    case '!' :
+                        return LEGACY;
+                    default :
+                        return START_TAG;
+                }
+            default :
+                return TEXT;
+        }
+    }
+
+    private final String get(int pos) {
+        return new String(txtBuf, pos, txtPos - pos);
+    }
+
+    /*
+    private final String pop (int pos) {
+    String result = new String (txtBuf, pos, txtPos - pos);
+    txtPos = pos;
+    return result;
+    }
+    */
+
+    private final void push(int c) {
+
+        isWhitespace &= c <= ' ';
+
+        if (txtPos == txtBuf.length) {
+            char[] bigger = new char[txtPos * 4 / 3 + 4];
+            System.arraycopy(txtBuf, 0, bigger, 0, txtPos);
+            txtBuf = bigger;
+        }
+
+        txtBuf[txtPos++] = (char) c;
+    }
+
+    /** Sets name and attributes */
+
+    private final void parseStartTag(boolean xmldecl)
+        throws IOException, XmlPullParserException {
+
+        if (!xmldecl)
+            read();
+        name = readName();
+        attributeCount = 0;
+
+        while (true) {
+            skip();
+
+            int c = peek(0);
+
+            if (xmldecl) {
+                if (c == '?') {
+                    read();
+                    read('>');
+                    return;
+                }
+            }
+            else {
+                if (c == '/') {
+                    degenerated = true;
+                    read();
+                    skip();
+                    read('>');
+                    break;
+                }
+
+                if (c == '>' && !xmldecl) {
+                    read();
+                    break;
+                }
+            }
+
+            if (c == -1) {
+                error(UNEXPECTED_EOF);
+                //type = COMMENT;
+                return;
+            }
+
+            String attrName = readName();
+
+            if (attrName.length() == 0) {
+                error("attr name expected");
+               //type = COMMENT;
+                break;
+            }
+
+            int i = (attributeCount++) << 2;
+
+            attributes = ensureCapacity(attributes, i + 4);
+
+            attributes[i++] = "";
+            attributes[i++] = null;
+            attributes[i++] = attrName;
+
+            skip();
+
+            if (peek(0) != '=') {
+                error("Attr.value missing f. "+attrName);
+                attributes[i] = "1";
+            }
+            else {
+                read('=');
+                skip();
+                int delimiter = peek(0);
+
+                if (delimiter != '\'' && delimiter != '"') {
+                    error("attr value delimiter missing!");
+                    delimiter = ' ';
+                }
+                else 
+                    read();
+                
+                int p = txtPos;
+                pushText(delimiter, true);
+
+                attributes[i] = get(p);
+                txtPos = p;
+
+                if (delimiter != ' ')
+                    read(); // skip endquote
+            }
+        }
+
+        int sp = depth++ << 2;
+
+        elementStack = ensureCapacity(elementStack, sp + 4);
+        elementStack[sp + 3] = name;
+
+        if (depth >= nspCounts.length) {
+            int[] bigger = new int[depth + 4];
+            System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
+            nspCounts = bigger;
+        }
+
+        nspCounts[depth] = nspCounts[depth - 1];
+
+        /*
+                if(!relaxed){
+                for (int i = attributeCount - 1; i > 0; i--) {
+                    for (int j = 0; j < i; j++) {
+                        if (getAttributeName(i).equals(getAttributeName(j)))
+                            exception("Duplicate Attribute: " + getAttributeName(i));
+                    }
+                }
+                }
+        */
+        if (processNsp)
+            adjustNsp();
+        else
+            namespace = "";
+
+        elementStack[sp] = namespace;
+        elementStack[sp + 1] = prefix;
+        elementStack[sp + 2] = name;
+    }
+
+    /** 
+     * result: isWhitespace; if the setName parameter is set,
+     * the name of the entity is stored in "name" */
+
+    private final void pushEntity()
+        throws IOException, XmlPullParserException {
+
+        push(read()); // &
+        
+        
+        int pos = txtPos;
+
+        while (true) {
+            int c = read();
+            if (c == ';')
+                break;
+            if (c < 128
+                && (c < '0' || c > '9')
+                && (c < 'a' || c > 'z')
+                && (c < 'A' || c > 'Z')
+                && c != '_'
+                && c != '-'
+                && c != '#') {
+                if(!relaxed){
+                    error("unterminated entity ref");
+                }
+                //; ends with:"+(char)c);           
+                if (c != -1)
+                    push(c);
+                return;
+            }
+
+            push(c);
+        }
+
+        String code = get(pos);
+        txtPos = pos - 1;
+        if (token && type == ENTITY_REF){
+            name = code;
+        }
+
+        if (code.charAt(0) == '#') {
+            int c =
+                (code.charAt(1) == 'x'
+                    ? Integer.parseInt(code.substring(2), 16)
+                    : Integer.parseInt(code.substring(1)));
+            push(c);
+            return;
+        }
+
+        String result = (String) entityMap.get(code);
+
+        unresolved = result == null;
+
+        if (unresolved) {
+            if (!token)
+                error("unresolved: &" + code + ";");
+        }
+        else {
+            for (int i = 0; i < result.length(); i++)
+                push(result.charAt(i));
+        }
+    }
+
+    /** types:
+    '<': parse to any token (for nextToken ())
+    '"': parse to quote
+    ' ': parse to whitespace or '>'
+    */
+
+    private final void pushText(int delimiter, boolean resolveEntities)
+        throws IOException, XmlPullParserException {
+
+        int next = peek(0);
+        int cbrCount = 0;
+
+        while (next != -1 && next != delimiter) { // covers eof, '<', '"'
+
+            if (delimiter == ' ')
+                if (next <= ' ' || next == '>')
+                    break;
+
+            if (next == '&') {
+                if (!resolveEntities)
+                    break;
+
+                pushEntity();
+            }
+            else if (next == '\n' && type == START_TAG) {
+                read();
+                push(' ');
+            }
+            else
+                push(read());
+
+            if (next == '>' && cbrCount >= 2 && delimiter != ']')
+                error("Illegal: ]]>");
+
+            if (next == ']')
+                cbrCount++;
+            else
+                cbrCount = 0;
+
+            next = peek(0);
+        }
+    }
+
+    private final void read(char c)
+        throws IOException, XmlPullParserException {
+        int a = read();
+        if (a != c)
+            error("expected: '" + c + "' actual: '" + ((char) a) + "'");
+    }
+
+    private final int read() throws IOException {
+        int result;
+
+        if (peekCount == 0)
+            result = peek(0);
+        else {
+            result = peek[0];
+            peek[0] = peek[1];
+        }
+        //        else {
+        //            result = peek[0]; 
+        //            System.arraycopy (peek, 1, peek, 0, peekCount-1);
+        //        }
+        peekCount--;
+
+        column++;
+
+        if (result == '\n') {
+
+            line++;
+            column = 1;
+        }
+
+        return result;
+    }
+
+    /** Does never read more than needed */
+
+    private final int peek(int pos) throws IOException {
+
+        while (pos >= peekCount) {
+
+            int nw;
+
+            if (srcBuf.length <= 1)
+                nw = reader.read();
+            else if (srcPos < srcCount)
+                nw = srcBuf[srcPos++];
+            else {
+                srcCount = reader.read(srcBuf, 0, srcBuf.length);
+                if (srcCount <= 0)
+                    nw = -1;
+                else
+                    nw = srcBuf[0];
+
+                srcPos = 1;
+            }
+
+            if (nw == '\r') {
+                wasCR = true;
+                peek[peekCount++] = '\n';
+            }
+            else {
+                if (nw == '\n') {
+                    if (!wasCR)
+                        peek[peekCount++] = '\n';
+                }
+                else
+                    peek[peekCount++] = nw;
+
+                wasCR = false;
+            }
+        }
+
+        return peek[pos];
+    }
+
+    private final String readName()
+        throws IOException, XmlPullParserException {
+
+        int pos = txtPos;
+        int c = peek(0);
+        if ((c < 'a' || c > 'z')
+            && (c < 'A' || c > 'Z')
+            && c != '_'
+            && c != ':'
+            && c < 0x0c0
+            && !relaxed)
+            error("name expected");
+
+        do {
+            push(read());
+            c = peek(0);
+        }
+        while ((c >= 'a' && c <= 'z')
+            || (c >= 'A' && c <= 'Z')
+            || (c >= '0' && c <= '9')
+            || c == '_'
+            || c == '-'
+            || c == ':'
+            || c == '.'
+            || c >= 0x0b7);
+
+        String result = get(pos);
+        txtPos = pos;
+        return result;
+    }
+
+    private final void skip() throws IOException {
+
+        while (true) {
+            int c = peek(0);
+            if (c > ' ' || c == -1)
+                break;
+            read();
+        }
+    }
+
+    //  public part starts here...
+
+    public void setInput(Reader reader) throws XmlPullParserException {
+        this.reader = reader;
+
+        line = 1;
+        column = 0;
+        type = START_DOCUMENT;
+        name = null;
+        namespace = null;
+        degenerated = false;
+        attributeCount = -1;
+        encoding = null;
+        version = null;
+        standalone = null;
+
+        if (reader == null)
+            return;
+
+        srcPos = 0;
+        srcCount = 0;
+        peekCount = 0;
+        depth = 0;
+
+        entityMap = new Hashtable();
+        entityMap.put("amp", "&");
+        entityMap.put("apos", "'");
+        entityMap.put("gt", ">");
+        entityMap.put("lt", "<");
+        entityMap.put("quot", "\"");
+    }
+
+    public void setInput(InputStream is, String _enc)
+        throws XmlPullParserException {
+
+        srcPos = 0;
+        srcCount = 0;
+        String enc = _enc;
+
+        if (is == null)
+            throw new IllegalArgumentException();
+
+        try {
+
+            if (enc == null) {
+                // read four bytes 
+
+                int chk = 0;
+
+                while (srcCount < 4) {
+                    int i = is.read();
+                    if (i == -1)
+                        break;
+                    chk = (chk << 8) | i;
+                    srcBuf[srcCount++] = (char) i;
+                }
+
+                if (srcCount == 4) {
+                    switch (chk) {
+                        case 0x00000FEFF :
+                            enc = "UTF-32BE";
+                            srcCount = 0;
+                            break;
+
+                        case 0x0FFFE0000 :
+                            enc = "UTF-32LE";
+                            srcCount = 0;
+                            break;
+
+                        case 0x03c :
+                            enc = "UTF-32BE";
+                            srcBuf[0] = '<';
+                            srcCount = 1;
+                            break;
+
+                        case 0x03c000000 :
+                            enc = "UTF-32LE";
+                            srcBuf[0] = '<';
+                            srcCount = 1;
+                            break;
+
+                        case 0x0003c003f :
+                            enc = "UTF-16BE";
+                            srcBuf[0] = '<';
+                            srcBuf[1] = '?';
+                            srcCount = 2;
+                            break;
+
+                        case 0x03c003f00 :
+                            enc = "UTF-16LE";
+                            srcBuf[0] = '<';
+                            srcBuf[1] = '?';
+                            srcCount = 2;
+                            break;
+
+                        case 0x03c3f786d :
+                            while (true) {
+                                int i = is.read();
+                                if (i == -1)
+                                    break;
+                                srcBuf[srcCount++] = (char) i;
+                                if (i == '>') {
+                                    String s = new String(srcBuf, 0, srcCount);
+                                    int i0 = s.indexOf("encoding");
+                                    if (i0 != -1) {
+                                        while (s.charAt(i0) != '"'
+                                            && s.charAt(i0) != '\'')
+                                            i0++;
+                                        char deli = s.charAt(i0++);
+                                        int i1 = s.indexOf(deli, i0);
+                                        enc = s.substring(i0, i1);
+                                    }
+                                    break;
+                                }
+                            }
+
+                        default :
+                            if ((chk & 0x0ffff0000) == 0x0FEFF0000) {
+                                enc = "UTF-16BE";
+                                srcBuf[0] =
+                                    (char) ((srcBuf[2] << 8) | srcBuf[3]);
+                                srcCount = 1;
+                            }
+                            else if ((chk & 0x0ffff0000) == 0x0fffe0000) {
+                                enc = "UTF-16LE";
+                                srcBuf[0] =
+                                    (char) ((srcBuf[3] << 8) | srcBuf[2]);
+                                srcCount = 1;
+                            }
+                            else if ((chk & 0x0ffffff00) == 0x0EFBBBF00) {
+                                enc = "UTF-8";
+                                srcBuf[0] = srcBuf[3];
+                                srcCount = 1;
+                            }
+                    }
+                }
+            }
+
+            if (enc == null)
+                enc = "UTF-8";
+
+            int sc = srcCount;
+            setInput(new InputStreamReader(is, enc));
+            encoding = _enc;
+            srcCount = sc;
+        }
+        catch (Exception e) {
+            throw new XmlPullParserException(
+                "Invalid stream or encoding: " + e.toString(),
+                this,
+                e);
+        }
+    }
+
+    public boolean getFeature(String feature) {
+        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+            return processNsp;
+        else if (isProp(feature, false, "relaxed"))
+            return relaxed;
+        else
+            return false;
+    }
+
+    public String getInputEncoding() {
+        return encoding;
+    }
+
+    public void defineEntityReplacementText(String entity, String value)
+        throws XmlPullParserException {
+        if (entityMap == null)
+            throw new RuntimeException("entity replacement text must be defined after setInput!");
+        entityMap.put(entity, value);
+    }
+
+    public Object getProperty(String property) {
+        if (isProp(property, true, "xmldecl-version"))
+            return version;
+        if (isProp(property, true, "xmldecl-standalone"))
+            return standalone;
+        if (isProp(property, true, "location"))            
+            return location != null ? location : reader.toString();
+        return null;
+    }
+
+    public int getNamespaceCount(int depth) {
+        if (depth > this.depth)
+            throw new IndexOutOfBoundsException();
+        return nspCounts[depth];
+    }
+
+    public String getNamespacePrefix(int pos) {
+        return nspStack[pos << 1];
+    }
+
+    public String getNamespaceUri(int pos) {
+        return nspStack[(pos << 1) + 1];
+    }
+
+    public String getNamespace(String prefix) {
+
+        if ("xml".equals(prefix))
+            return "http://www.w3.org/XML/1998/namespace";
+        if ("xmlns".equals(prefix))
+            return "http://www.w3.org/2000/xmlns/";
+
+        for (int i = (getNamespaceCount(depth) << 1) - 2; i >= 0; i -= 2) {
+            if (prefix == null) {
+                if (nspStack[i] == null)
+                    return nspStack[i + 1];
+            }
+            else if (prefix.equals(nspStack[i]))
+                return nspStack[i + 1];
+        }
+        return null;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
+    public String getPositionDescription() {
+
+        StringBuffer buf =
+            new StringBuffer(type < TYPES.length ? TYPES[type] : "unknown");
+        buf.append(' ');
+
+        if (type == START_TAG || type == END_TAG) {
+            if (degenerated)
+                buf.append("(empty) ");
+            buf.append('<');
+            if (type == END_TAG)
+                buf.append('/');
+
+            if (prefix != null)
+                buf.append("{" + namespace + "}" + prefix + ":");
+            buf.append(name);
+
+            int cnt = attributeCount << 2;
+            for (int i = 0; i < cnt; i += 4) {
+                buf.append(' ');
+                if (attributes[i + 1] != null)
+                    buf.append(
+                        "{" + attributes[i] + "}" + attributes[i + 1] + ":");
+                buf.append(attributes[i + 2] + "='" + attributes[i + 3] + "'");
+            }
+
+            buf.append('>');
+        }
+        else if (type == IGNORABLE_WHITESPACE);
+        else if (type != TEXT)
+            buf.append(getText());
+        else if (isWhitespace)
+            buf.append("(whitespace)");
+        else {
+            String text = getText();
+            if (text.length() > 16)
+                text = text.substring(0, 16) + "...";
+            buf.append(text);
+        }
+
+        buf.append("@"+line + ":" + column);
+        if(location != null){
+            buf.append(" in ");
+            buf.append(location);
+        }
+        else if(reader != null){
+            buf.append(" in ");
+            buf.append(reader.toString());
+        }
+        return buf.toString();
+    }
+
+    public int getLineNumber() {
+        return line;
+    }
+
+    public int getColumnNumber() {
+        return column;
+    }
+
+    public boolean isWhitespace() throws XmlPullParserException {
+        if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT)
+            exception(ILLEGAL_TYPE);
+        return isWhitespace;
+    }
+
+    public String getText() {
+        return type < TEXT
+            || (type == ENTITY_REF && unresolved) ? null : get(0);
+    }
+
+    public char[] getTextCharacters(int[] poslen) {
+        if (type >= TEXT) {
+            if (type == ENTITY_REF) {
+                poslen[0] = 0;
+                poslen[1] = name.length();
+                return name.toCharArray();
+            }
+            poslen[0] = 0;
+            poslen[1] = txtPos;
+            return txtBuf;
+        }
+
+        poslen[0] = -1;
+        poslen[1] = -1;
+        return null;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public boolean isEmptyElementTag() throws XmlPullParserException {
+        if (type != START_TAG)
+            exception(ILLEGAL_TYPE);
+        return degenerated;
+    }
+
+    public int getAttributeCount() {
+        return attributeCount;
+    }
+
+    public String getAttributeType(int index) {
+        return "CDATA";
+    }
+
+    public boolean isAttributeDefault(int index) {
+        return false;
+    }
+
+    public String getAttributeNamespace(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[index << 2];
+    }
+
+    public String getAttributeName(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 2];
+    }
+
+    public String getAttributePrefix(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 1];
+    }
+
+    public String getAttributeValue(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 3];
+    }
+
+    public String getAttributeValue(String namespace, String name) {
+
+        for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
+            if (attributes[i + 2].equals(name)
+                && (namespace == null || attributes[i].equals(namespace)))
+                return attributes[i + 3];
+        }
+
+        return null;
+    }
+
+    public int getEventType() throws XmlPullParserException {
+        return type;
+    }
+
+    public int next() throws XmlPullParserException, IOException {
+
+        txtPos = 0;
+        isWhitespace = true;
+        int minType = 9999;
+        token = false;
+
+        do {
+            nextImpl();
+            if (type < minType)
+                minType = type;
+            //        if (curr <= TEXT) type = curr; 
+        }
+        while (minType > ENTITY_REF // ignorable
+            || (minType >= TEXT && peekType() >= TEXT));
+
+        type = minType;
+        if (type > TEXT)
+            type = TEXT;
+
+        return type;
+    }
+
+    public int nextToken() throws XmlPullParserException, IOException {
+
+        isWhitespace = true;
+        txtPos = 0;
+
+        token = true;
+        nextImpl();
+        return type;
+    }
+
+    //
+    // utility methods to make XML parsing easier ...
+
+    public int nextTag() throws XmlPullParserException, IOException {
+
+        next();
+        if (type == TEXT && isWhitespace)
+            next();
+
+        if (type != END_TAG && type != START_TAG)
+            exception("unexpected type");
+
+        return type;
+    }
+
+    public void require(int type, String namespace, String name)
+        throws XmlPullParserException, IOException {
+
+        if (type != this.type
+            || (namespace != null && !namespace.equals(getNamespace()))
+            || (name != null && !name.equals(getName())))
+            exception(
+                "expected: " + TYPES[type] + " {" + namespace + "}" + name);
+    }
+
+    public String nextText() throws XmlPullParserException, IOException {
+        if (type != START_TAG)
+            exception("precondition: START_TAG");
+
+        next();
+
+        String result;
+
+        if (type == TEXT) {
+            result = getText();
+            next();
+        }
+        else
+            result = "";
+
+        if (type != END_TAG)
+            exception("END_TAG expected");
+
+        return result;
+    }
+
+    public void setFeature(String feature, boolean value)
+        throws XmlPullParserException {
+        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+            processNsp = value;
+        else if (isProp(feature, false, "relaxed"))
+            relaxed = value;
+        else
+            exception("unsupported feature: " + feature);
+    }
+
+    public void setProperty(String property, Object value)
+        throws XmlPullParserException {
+        if(isProp(property, true, "location"))
+            location = value;
+        else
+            throw new XmlPullParserException("unsupported property: " + property);
+    }
+
+    /**
+      * Skip sub tree that is currently porser positioned on.
+      * <br>NOTE: parser must be on START_TAG and when funtion returns
+      * parser will be positioned on corresponding END_TAG. 
+      */
+
+    //    Implementation copied from Alek's mail... 
+
+    public void skipSubTree() throws XmlPullParserException, IOException {
+        require(START_TAG, null, null);
+        int level = 1;
+        while (level > 0) {
+            int eventType = next();
+            if (eventType == END_TAG) {
+                --level;
+            }
+            else if (eventType == START_TAG) {
+                ++level;
+            }
+        }
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
new file mode 100644
index 0000000..d63ed04
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
@@ -0,0 +1,562 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+ 
+
+package org.kxml2.io;
+
+import java.io.*;
+import org.xmlpull.v1.*;
+
+public class KXmlSerializer implements XmlSerializer {
+
+    //    static final String UNDEFINED = ":";
+
+    // BEGIN android-added
+    /** size (in characters) for the write buffer */
+    private static final int WRITE_BUFFER_SIZE = 500;
+    // END android-added   
+
+    // BEGIN android-changed
+    // (Guarantee that the writer is always buffered.)
+    private BufferedWriter writer;
+    // END android-changed
+
+    private boolean pending;
+    private int auto;
+    private int depth;
+
+    private String[] elementStack = new String[12];
+    //nsp/prefix/name
+    private int[] nspCounts = new int[4];
+    private String[] nspStack = new String[8];
+    //prefix/nsp; both empty are ""
+    private boolean[] indent = new boolean[4];
+    private boolean unicode;
+    private String encoding;
+
+    private final void check(boolean close) throws IOException {
+        if (!pending)
+            return;
+
+        depth++;
+        pending = false;
+
+        if (indent.length <= depth) {
+            boolean[] hlp = new boolean[depth + 4];
+            System.arraycopy(indent, 0, hlp, 0, depth);
+            indent = hlp;
+        }
+        indent[depth] = indent[depth - 1];
+
+        for (int i = nspCounts[depth - 1];
+            i < nspCounts[depth];
+            i++) {
+            writer.write(' ');
+            writer.write("xmlns");
+            if (!"".equals(nspStack[i * 2])) {
+                writer.write(':');
+                writer.write(nspStack[i * 2]);
+            }
+            else if ("".equals(getNamespace()) && !"".equals(nspStack[i * 2 + 1]))
+                throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+            writer.write("=\"");
+            writeEscaped(nspStack[i * 2 + 1], '"');
+            writer.write('"');
+        }
+
+        if (nspCounts.length <= depth + 1) {
+            int[] hlp = new int[depth + 8];
+            System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
+            nspCounts = hlp;
+        }
+
+        nspCounts[depth + 1] = nspCounts[depth];
+        //   nspCounts[depth + 2] = nspCounts[depth];
+
+        writer.write(close ? " />" : ">");
+    }
+
+    private final void writeEscaped(String s, int quot)
+        throws IOException {
+
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '\n':
+                case '\r':
+                case '\t':
+                    if(quot == -1) 
+                        writer.write(c);
+                    else 
+                        writer.write("&#"+((int) c)+';');
+                    break;
+                case '&' :
+                    writer.write("&amp;");
+                    break;
+                case '>' :
+                    writer.write("&gt;");
+                    break;
+                case '<' :
+                    writer.write("&lt;");
+                    break;
+                case '"' :
+                case '\'' :
+                    if (c == quot) {
+                        writer.write(
+                            c == '"' ? "&quot;" : "&apos;");
+                        break;
+                    }
+                default :
+                    //if(c < ' ')
+                    //    throw new IllegalArgumentException("Illegal control code:"+((int) c));
+
+                    if (c >= ' ' && c !='@' && (c < 127 || unicode))
+                        writer.write(c);
+                    else
+                        writer.write("&#" + ((int) c) + ";");
+
+            }
+        }
+    }
+
+    /*
+        private final void writeIndent() throws IOException {
+            writer.write("\r\n");
+            for (int i = 0; i < depth; i++)
+                writer.write(' ');
+        }*/
+
+    public void docdecl(String dd) throws IOException {
+        writer.write("<!DOCTYPE");
+        writer.write(dd);
+        writer.write(">");
+    }
+
+    public void endDocument() throws IOException {
+        while (depth > 0) {
+            endTag(
+                elementStack[depth * 3 - 3],
+                elementStack[depth * 3 - 1]);
+        }
+        flush();
+    }
+
+    public void entityRef(String name) throws IOException {
+        check(false);
+        writer.write('&');
+        writer.write(name);
+        writer.write(';');
+    }
+
+    public boolean getFeature(String name) {
+        //return false;
+        return (
+            "http://xmlpull.org/v1/doc/features.html#indent-output"
+                .equals(
+                name))
+            ? indent[depth]
+            : false;
+    }
+
+    public String getPrefix(String namespace, boolean create) {
+        try {
+            return getPrefix(namespace, false, create);
+        }
+        catch (IOException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+
+    private final String getPrefix(
+        String namespace,
+        boolean includeDefault,
+        boolean create)
+        throws IOException {
+
+        for (int i = nspCounts[depth + 1] * 2 - 2;
+            i >= 0;
+            i -= 2) {
+            if (nspStack[i + 1].equals(namespace)
+                && (includeDefault || !nspStack[i].equals(""))) {
+                String cand = nspStack[i];
+                for (int j = i + 2;
+                    j < nspCounts[depth + 1] * 2;
+                    j++) {
+                    if (nspStack[j].equals(cand)) {
+                        cand = null;
+                        break;
+                    }
+                }
+                if (cand != null)
+                    return cand;
+            }
+        }
+
+        if (!create)
+            return null;
+
+        String prefix;
+
+        if ("".equals(namespace))
+            prefix = "";
+        else {
+            do {
+                prefix = "n" + (auto++);
+                for (int i = nspCounts[depth + 1] * 2 - 2;
+                    i >= 0;
+                    i -= 2) {
+                    if (prefix.equals(nspStack[i])) {
+                        prefix = null;
+                        break;
+                    }
+                }
+            }
+            while (prefix == null);
+        }
+
+        boolean p = pending;
+        pending = false;
+        setPrefix(prefix, namespace);
+        pending = p;
+        return prefix;
+    }
+
+    public Object getProperty(String name) {
+        throw new RuntimeException("Unsupported property");
+    }
+
+    public void ignorableWhitespace(String s)
+        throws IOException {
+        text(s);
+    }
+
+    public void setFeature(String name, boolean value) {
+        if ("http://xmlpull.org/v1/doc/features.html#indent-output"
+            .equals(name)) {
+            indent[depth] = value;
+        }
+        else
+            throw new RuntimeException("Unsupported Feature");
+    }
+
+    public void setProperty(String name, Object value) {
+        throw new RuntimeException(
+            "Unsupported Property:" + value);
+    }
+
+    public void setPrefix(String prefix, String namespace)
+        throws IOException {
+
+        check(false);
+        if (prefix == null)
+            prefix = "";
+        if (namespace == null)
+            namespace = "";
+
+        String defined = getPrefix(namespace, true, false);
+
+        // boil out if already defined
+
+        if (prefix.equals(defined))
+            return;
+
+        int pos = (nspCounts[depth + 1]++) << 1;
+
+        if (nspStack.length < pos + 1) {
+            String[] hlp = new String[nspStack.length + 16];
+            System.arraycopy(nspStack, 0, hlp, 0, pos);
+            nspStack = hlp;
+        }
+
+        nspStack[pos++] = prefix;
+        nspStack[pos] = namespace;
+    }
+
+    public void setOutput(Writer writer) {
+        // BEGIN android-changed
+        // Guarantee that the writer is always buffered.
+        if (writer instanceof BufferedWriter) {
+            this.writer = (BufferedWriter) writer;
+        } else {
+            this.writer = new BufferedWriter(writer, WRITE_BUFFER_SIZE);
+        }
+        // END android-changed
+
+        // elementStack = new String[12]; //nsp/prefix/name
+        //nspCounts = new int[4];
+        //nspStack = new String[8]; //prefix/nsp
+        //indent = new boolean[4];
+
+        nspCounts[0] = 2;
+        nspCounts[1] = 2;
+        nspStack[0] = "";
+        nspStack[1] = "";
+        nspStack[2] = "xml";
+        nspStack[3] = "http://www.w3.org/XML/1998/namespace";
+        pending = false;
+        auto = 0;
+        depth = 0;
+
+        unicode = false;
+    }
+
+    public void setOutput(OutputStream os, String encoding)
+        throws IOException {
+        if (os == null)
+            throw new IllegalArgumentException();
+        setOutput(
+            encoding == null
+                ? new OutputStreamWriter(os)
+                : new OutputStreamWriter(os, encoding));
+        this.encoding = encoding;
+        if (encoding != null
+            && encoding.toLowerCase().startsWith("utf"))
+            unicode = true;
+    }
+
+    public void startDocument(
+        String encoding,
+        Boolean standalone)
+        throws IOException {
+        writer.write("<?xml version='1.0' ");
+
+        if (encoding != null) {
+            this.encoding = encoding;
+            if (encoding.toLowerCase().startsWith("utf"))
+                unicode = true;
+        }
+
+        if (this.encoding != null) {
+            writer.write("encoding='");
+            writer.write(this.encoding);
+            writer.write("' ");
+        }
+
+        if (standalone != null) {
+            writer.write("standalone='");
+            writer.write(
+                standalone.booleanValue() ? "yes" : "no");
+            writer.write("' ");
+        }
+        writer.write("?>");
+    }
+
+    public XmlSerializer startTag(String namespace, String name)
+        throws IOException {
+        check(false);
+
+        //        if (namespace == null)
+        //            namespace = "";
+
+        if (indent[depth]) {
+            writer.write("\r\n");
+            for (int i = 0; i < depth; i++)
+                writer.write("  ");
+        }
+
+        int esp = depth * 3;
+
+        if (elementStack.length < esp + 3) {
+            String[] hlp = new String[elementStack.length + 12];
+            System.arraycopy(elementStack, 0, hlp, 0, esp);
+            elementStack = hlp;
+        }
+
+        String prefix =
+            namespace == null
+                ? ""
+                : getPrefix(namespace, true, true);
+
+        if ("".equals(namespace)) {
+            for (int i = nspCounts[depth];
+                i < nspCounts[depth + 1];
+                i++) {
+                if ("".equals(nspStack[i * 2]) && !"".equals(nspStack[i * 2 + 1])) {
+                    throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+                }
+            }
+        }
+
+        elementStack[esp++] = namespace;
+        elementStack[esp++] = prefix;
+        elementStack[esp] = name;
+
+        writer.write('<');
+        if (!"".equals(prefix)) {
+            writer.write(prefix);
+            writer.write(':');
+        }
+
+        writer.write(name);
+
+        pending = true;
+
+        return this;
+    }
+
+    public XmlSerializer attribute(
+        String namespace,
+        String name,
+        String value)
+        throws IOException {
+        if (!pending)
+            throw new IllegalStateException("illegal position for attribute");
+
+        //        int cnt = nspCounts[depth];
+
+        if (namespace == null)
+            namespace = "";
+
+        //        depth--;
+        //        pending = false;
+
+        String prefix =
+            "".equals(namespace)
+                ? ""
+                : getPrefix(namespace, false, true);
+
+        //        pending = true;
+        //        depth++;
+
+        /*        if (cnt != nspCounts[depth]) {
+                    writer.write(' ');
+                    writer.write("xmlns");
+                    if (nspStack[cnt * 2] != null) {
+                        writer.write(':');
+                        writer.write(nspStack[cnt * 2]);
+                    }
+                    writer.write("=\"");
+                    writeEscaped(nspStack[cnt * 2 + 1], '"');
+                    writer.write('"');
+                }
+                */
+
+        writer.write(' ');
+        if (!"".equals(prefix)) {
+            writer.write(prefix);
+            writer.write(':');
+        }
+        writer.write(name);
+        writer.write('=');
+        char q = value.indexOf('"') == -1 ? '"' : '\'';
+        writer.write(q);
+        writeEscaped(value, q);
+        writer.write(q);
+
+        return this;
+    }
+
+    public void flush() throws IOException {
+        check(false);
+        writer.flush();
+    }
+    /*
+        public void close() throws IOException {
+            check();
+            writer.close();
+        }
+    */
+    public XmlSerializer endTag(String namespace, String name)
+        throws IOException {
+
+        if (!pending)
+            depth--;
+        //        if (namespace == null)
+        //          namespace = "";
+
+        if ((namespace == null
+            && elementStack[depth * 3] != null)
+            || (namespace != null
+                && !namespace.equals(elementStack[depth * 3]))
+            || !elementStack[depth * 3 + 2].equals(name))
+            throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
+
+        if (pending) {
+            check(true);
+            depth--;
+        }
+        else {
+            if (indent[depth + 1]) {
+                writer.write("\r\n");
+                for (int i = 0; i < depth; i++)
+                    writer.write("  ");
+            }
+
+            writer.write("</");
+            String prefix = elementStack[depth * 3 + 1];
+            if (!"".equals(prefix)) {
+                writer.write(prefix);
+                writer.write(':');
+            }
+            writer.write(name);
+            writer.write('>');
+        }
+
+        nspCounts[depth + 1] = nspCounts[depth];
+        return this;
+    }
+
+    public String getNamespace() {
+        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
+    }
+
+    public String getName() {
+        return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
+    }
+
+    public int getDepth() {
+        return pending ? depth + 1 : depth;
+    }
+
+    public XmlSerializer text(String text) throws IOException {
+        check(false);
+        indent[depth] = false;
+        writeEscaped(text, -1);
+        return this;
+    }
+
+    public XmlSerializer text(char[] text, int start, int len)
+        throws IOException {
+        text(new String(text, start, len));
+        return this;
+    }
+
+    public void cdsect(String data) throws IOException {
+        check(false);
+        writer.write("<![CDATA[");
+        writer.write(data);
+        writer.write("]]>");
+    }
+
+    public void comment(String comment) throws IOException {
+        check(false);
+        writer.write("<!--");
+        writer.write(comment);
+        writer.write("-->");
+    }
+
+    public void processingInstruction(String pi)
+        throws IOException {
+        check(false);
+        writer.write("<?");
+        writer.write(pi);
+        writer.write("?>");
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/kdom/Document.java b/xml/src/main/java/org/kxml2/kdom/Document.java
new file mode 100644
index 0000000..859334c
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Document.java
@@ -0,0 +1,129 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+ 
+
+package org.kxml2.kdom;
+
+import java.io.*;
+
+import org.xmlpull.v1.*;
+/** The document consists of some legacy events and a single root
+    element. This class basically adds some consistency checks to
+    Node. */
+
+public class Document extends Node {
+
+    protected int rootIndex = -1;
+    String encoding;
+    Boolean standalone;
+
+    /** returns "#document" */
+
+    public String getEncoding () {
+        return encoding;
+    }
+    
+    public void setEncoding(String enc) {
+        this.encoding = enc;
+    }
+    
+    public void setStandalone (Boolean standalone) {
+        this.standalone = standalone;
+    }
+    
+    public Boolean getStandalone() {
+        return standalone;
+    }
+
+
+    public String getName() {
+        return "#document";
+    }
+
+    /** Adds a child at the given index position. Throws
+    an exception when a second root element is added */
+
+    public void addChild(int index, int type, Object child) {
+        if (type == ELEMENT) {
+         //   if (rootIndex != -1)
+           //     throw new RuntimeException("Only one document root element allowed");
+
+            rootIndex = index;
+        }
+        else if (rootIndex >= index)
+            rootIndex++;
+
+        super.addChild(index, type, child);
+    }
+
+    /** reads the document and checks if the last event
+    is END_DOCUMENT. If not, an exception is thrown.
+    The end event is consumed. For parsing partial
+        XML structures, consider using Node.parse (). */
+
+    public void parse(XmlPullParser parser)
+        throws IOException, XmlPullParserException {
+
+        parser.require(XmlPullParser.START_DOCUMENT, null, null);
+        parser.nextToken ();            
+
+        encoding = parser.getInputEncoding();
+        standalone = (Boolean)parser.getProperty ("http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone");
+        
+        super.parse(parser);
+
+        if (parser.getEventType() != XmlPullParser.END_DOCUMENT)
+            throw new RuntimeException("Document end expected!");
+
+    }
+
+    public void removeChild(int index) {
+        if (index == rootIndex)
+            rootIndex = -1;
+        else if (index < rootIndex)
+            rootIndex--;
+
+        super.removeChild(index);
+    }
+
+    /** returns the root element of this document. */
+
+    public Element getRootElement() {
+        if (rootIndex == -1)
+            throw new RuntimeException("Document has no root element!");
+
+        return (Element) getChild(rootIndex);
+    }
+    
+    
+    /** Writes this node to the given XmlWriter. For node and document,
+        this method is identical to writeChildren, except that the
+        stream is flushed automatically. */
+
+    public void write(XmlSerializer writer)
+        throws IOException {
+        
+        writer.startDocument(encoding, standalone);
+        writeChildren(writer);
+        writer.endDocument();
+    }
+    
+    
+}
\ No newline at end of file
diff --git a/xml/src/main/java/org/kxml2/kdom/Element.java b/xml/src/main/java/org/kxml2/kdom/Element.java
new file mode 100644
index 0000000..6a5777b
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Element.java
@@ -0,0 +1,335 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.kdom;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+/** 
+ * In order to create an element, please use the createElement method
+ * instead of invoking the constructor directly. The right place to
+ * add user defined initialization code is the init method. */
+
+public class Element extends Node {
+
+    protected String namespace;
+    protected String name;
+    protected Vector attributes;
+    protected Node parent;
+    protected Vector prefixes;
+
+    public Element() {
+    }
+
+    /** 
+     * called when all properties are set, but before children
+     * are parsed. Please do not use setParent for initialization
+     * code any longer. */
+
+    public void init() {
+    }
+
+
+
+
+    /** 
+     * removes all children and attributes */
+
+    public void clear() {
+        attributes = null;
+        children = null;
+    }
+
+    /** 
+     * Forwards creation request to parent if any, otherwise
+     * calls super.createElement. */
+
+    public Element createElement(
+        String namespace,
+        String name) { 
+
+        return (this.parent == null)
+            ? super.createElement(namespace, name)
+            : this.parent.createElement(namespace, name);
+    }
+
+    /** 
+     * Returns the number of attributes of this element. */
+
+    public int getAttributeCount() {
+        return attributes == null ? 0 : attributes.size();
+    }
+
+    public String getAttributeNamespace (int index) {
+        return ((String []) attributes.elementAt (index)) [0];
+    }
+
+/*    public String getAttributePrefix (int index) {
+        return ((String []) attributes.elementAt (index)) [1];
+    }*/
+
+    public String getAttributeName (int index) {
+        return ((String []) attributes.elementAt (index)) [1];
+    }
+    
+
+    public String getAttributeValue (int index) {
+        return ((String []) attributes.elementAt (index)) [2];
+    }
+    
+    
+    public String getAttributeValue (String namespace, String name) {
+        for (int i = 0; i < getAttributeCount (); i++) {
+            if (name.equals (getAttributeName (i)) 
+                && (namespace == null || namespace.equals (getAttributeNamespace(i)))) {
+                return getAttributeValue (i);
+            }
+        }                        
+        return null;            
+    }
+
+    /** 
+     * Returns the root node, determined by ascending to the 
+     * all parents un of the root element. */
+
+    public Node getRoot() {
+
+        Element current = this;
+        
+        while (current.parent != null) {
+            if (!(current.parent instanceof Element)) return current.parent;
+            current = (Element) current.parent;
+        }
+        
+        return current;
+    }
+
+    /** 
+     * returns the (local) name of the element */
+
+    public String getName() {
+        return name;
+    }
+
+    /** 
+     * returns the namespace of the element */
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+
+    /** 
+     * returns the namespace for the given prefix */
+    
+    public String getNamespaceUri (String prefix) {
+        int cnt = getNamespaceCount ();
+        for (int i = 0; i < cnt; i++) {
+            if (prefix == getNamespacePrefix (i) ||
+                (prefix != null && prefix.equals (getNamespacePrefix (i))))
+                return getNamespaceUri (i);    
+        }
+        return parent instanceof Element ? ((Element) parent).getNamespaceUri (prefix) : null;
+    }
+
+
+    /** 
+     * returns the number of declared namespaces, NOT including
+     * parent elements */
+
+    public int getNamespaceCount () {
+        return (prefixes == null ? 0 : prefixes.size ());
+    }
+
+
+    public String getNamespacePrefix (int i) {
+        return ((String []) prefixes.elementAt (i)) [0];
+    }
+
+    public String getNamespaceUri (int i) {
+        return ((String []) prefixes.elementAt (i)) [1];
+    }
+
+
+    /** 
+     * Returns the parent node of this element */
+
+    public Node getParent() {
+        return parent;
+    }
+
+    /* 
+     * Returns the parent element if available, null otherwise 
+
+    public Element getParentElement() {
+        return (parent instanceof Element)
+            ? ((Element) parent)
+            : null;
+    }
+*/
+
+    /** 
+     * Builds the child elements from the given Parser. By overwriting 
+     * parse, an element can take complete control over parsing its 
+     * subtree. */
+
+    public void parse(XmlPullParser parser)
+        throws IOException, XmlPullParserException {
+
+        for (int i = parser.getNamespaceCount (parser.getDepth () - 1);
+            i < parser.getNamespaceCount (parser.getDepth ()); i++) {
+            setPrefix (parser.getNamespacePrefix (i), parser.getNamespaceUri(i));
+        }
+        
+        
+        for (int i = 0; i < parser.getAttributeCount (); i++) 
+            setAttribute (parser.getAttributeNamespace (i),
+//                          parser.getAttributePrefix (i),
+                          parser.getAttributeName (i),
+                          parser.getAttributeValue (i));
+
+
+        //        if (prefixMap == null) throw new RuntimeException ("!!");
+
+        init();
+
+
+        if (parser.isEmptyElementTag()) 
+            parser.nextToken ();
+        else {
+            parser.nextToken ();
+            super.parse(parser);
+
+            if (getChildCount() == 0)
+                addChild(IGNORABLE_WHITESPACE, "");
+        }
+        
+        parser.require(
+            XmlPullParser.END_TAG,
+            getNamespace(),
+            getName());
+            
+        parser.nextToken ();
+    }
+
+
+    /** 
+     * Sets the given attribute; a value of null removes the attribute */
+
+    public void setAttribute (String namespace, String name, String value) {
+        if (attributes == null) 
+            attributes = new Vector ();
+
+        if (namespace == null) 
+            namespace = "";
+        
+        for (int i = attributes.size()-1; i >=0; i--){
+            String[] attribut = (String[]) attributes.elementAt(i);
+            if (attribut[0].equals(namespace) &&
+                attribut[1].equals(name)){
+                    
+                if (value == null) {
+                    attributes.removeElementAt(i);
+                }
+                else {
+                    attribut[2] = value;
+                }
+                return; 
+            }
+        }
+
+        attributes.addElement 
+            (new String [] {namespace, name, value});
+    }
+
+
+    /** 
+     * Sets the given prefix; a namespace value of null removess the 
+     * prefix */
+
+    public void setPrefix (String prefix, String namespace) {
+        if (prefixes == null) prefixes = new Vector ();
+        prefixes.addElement (new String [] {prefix, namespace});        
+    }
+
+
+    /** 
+     * sets the name of the element */
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /** 
+     * sets the namespace of the element. Please note: For no
+     * namespace, please use Xml.NO_NAMESPACE, null is not a legal
+     * value. Currently, null is converted to Xml.NO_NAMESPACE, but
+     * future versions may throw an exception. */
+
+    public void setNamespace(String namespace) {
+        if (namespace == null) 
+            throw new NullPointerException ("Use \"\" for empty namespace");
+        this.namespace = namespace;
+    }
+
+    /** 
+     * Sets the Parent of this element. Automatically called from the
+     * add method.  Please use with care, you can simply
+     * create inconsitencies in the document tree structure using
+     * this method!  */
+
+    protected void setParent(Node parent) {
+        this.parent = parent;
+    }
+
+
+    /** 
+     * Writes this element and all children to the given XmlWriter. */
+
+    public void write(XmlSerializer writer)
+        throws IOException {
+
+        if (prefixes != null) {
+            for (int i = 0; i < prefixes.size(); i++) {
+                writer.setPrefix (getNamespacePrefix (i), getNamespaceUri (i));
+            }
+        }
+
+        writer.startTag(
+            getNamespace(),
+            getName());
+
+        int len = getAttributeCount();
+
+        for (int i = 0; i < len; i++) {
+            writer.attribute(
+                getAttributeNamespace(i),
+                getAttributeName(i),
+                getAttributeValue(i));
+        }
+
+        writeChildren(writer);
+
+        writer.endTag(getNamespace (), getName ());
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/kdom/Node.java b/xml/src/main/java/org/kxml2/kdom/Node.java
new file mode 100644
index 0000000..a3cc78d
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Node.java
@@ -0,0 +1,366 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.kdom;
+
+import java.util.*;
+import java.io.*;
+import org.xmlpull.v1.*;
+/** A common base class for Document and Element, also used for
+    storing XML fragments. */
+
+public class Node { //implements XmlIO{
+
+    public static final int DOCUMENT = 0;
+    public static final int ELEMENT = 2;
+    public static final int TEXT = 4;
+    public static final int CDSECT = 5;
+    public static final int ENTITY_REF = 6;
+    public static final int IGNORABLE_WHITESPACE = 7;
+    public static final int PROCESSING_INSTRUCTION = 8;
+    public static final int COMMENT = 9;
+    public static final int DOCDECL = 10;
+
+    protected Vector children;
+    protected StringBuffer types;
+
+    /** inserts the given child object of the given type at the
+    given index. */
+
+    public void addChild(int index, int type, Object child) {
+
+        if (child == null)
+            throw new NullPointerException();
+
+        if (children == null) {
+            children = new Vector();
+            types = new StringBuffer();
+        }
+
+        if (type == ELEMENT) {
+            if (!(child instanceof Element))
+                throw new RuntimeException("Element obj expected)");
+
+            ((Element) child).setParent(this);
+        }
+        else if (!(child instanceof String))
+            throw new RuntimeException("String expected");
+
+        children.insertElementAt(child, index);
+        types.insert(index, (char) type);
+    }
+
+    /** convenience method for addChild (getChildCount (), child) */
+
+    public void addChild(int type, Object child) {
+        addChild(getChildCount(), type, child);
+    }
+
+    /** Builds a default element with the given properties. Elements
+    should always be created using this method instead of the
+    constructor in order to enable construction of specialized
+    subclasses by deriving custom Document classes. Please note:
+    For no namespace, please use Xml.NO_NAMESPACE, null is not a
+    legal value. Currently, null is converted to Xml.NO_NAMESPACE,
+    but future versions may throw an exception. */
+
+    public Element createElement(String namespace, String name) {
+
+        Element e = new Element();
+        e.namespace = namespace == null ? "" : namespace;
+        e.name = name;
+        return e;
+    }
+
+    /** Returns the child object at the given index.  For child
+        elements, an Element object is returned. For all other child
+        types, a String is returned. */
+
+    public Object getChild(int index) {
+        return children.elementAt(index);
+    }
+
+    /** Returns the number of child objects */
+
+    public int getChildCount() {
+        return children == null ? 0 : children.size();
+    }
+
+    /** returns the element at the given index. If the node at the
+    given index is a text node, null is returned */
+
+    public Element getElement(int index) {
+        Object child = getChild(index);
+        return (child instanceof Element) ? (Element) child : null;
+    }
+
+    /** Returns the element with the given namespace and name. If the
+        element is not found, or more than one matching elements are
+        found, an exception is thrown. */
+
+    public Element getElement(String namespace, String name) {
+
+        int i = indexOf(namespace, name, 0);
+        int j = indexOf(namespace, name, i + 1);
+
+        if (i == -1 || j != -1)
+            throw new RuntimeException(
+                "Element {"
+                    + namespace
+                    + "}"
+                    + name
+                    + (i == -1 ? " not found in " : " more than once in ")
+                    + this);
+
+        return getElement(i);
+    }
+
+    /* returns "#document-fragment". For elements, the element name is returned 
+    
+    public String getName() {
+        return "#document-fragment";
+    }
+    
+    /** Returns the namespace of the current element. For Node
+        and Document, Xml.NO_NAMESPACE is returned. 
+    
+    public String getNamespace() {
+        return "";
+    }
+    
+    public int getNamespaceCount () {
+        return 0;
+    }
+    
+    /** returns the text content if the element has text-only
+    content. Throws an exception for mixed content
+    
+    public String getText() {
+    
+        StringBuffer buf = new StringBuffer();
+        int len = getChildCount();
+    
+        for (int i = 0; i < len; i++) {
+            if (isText(i))
+                buf.append(getText(i));
+            else if (getType(i) == ELEMENT)
+                throw new RuntimeException("not text-only content!");
+        }
+    
+        return buf.toString();
+    }
+    */
+
+    /** Returns the text node with the given index or null if the node
+        with the given index is not a text node. */
+
+    public String getText(int index) {
+        return (isText(index)) ? (String) getChild(index) : null;
+    }
+
+    /** Returns the type of the child at the given index. Possible 
+    types are ELEMENT, TEXT, COMMENT, and PROCESSING_INSTRUCTION */
+
+    public int getType(int index) {
+        return types.charAt(index);
+    }
+
+    /** Convenience method for indexOf (getNamespace (), name,
+        startIndex). 
+    
+    public int indexOf(String name, int startIndex) {
+        return indexOf(getNamespace(), name, startIndex);
+    }
+    */
+
+    /** Performs search for an element with the given namespace and
+    name, starting at the given start index. A null namespace
+    matches any namespace, please use Xml.NO_NAMESPACE for no
+    namespace).  returns -1 if no matching element was found. */
+
+    public int indexOf(String namespace, String name, int startIndex) {
+
+        int len = getChildCount();
+
+        for (int i = startIndex; i < len; i++) {
+
+            Element child = getElement(i);
+
+            if (child != null
+                && name.equals(child.getName())
+                && (namespace == null || namespace.equals(child.getNamespace())))
+                return i;
+        }
+        return -1;
+    }
+
+    public boolean isText(int i) {
+        int t = getType(i);
+        return t == TEXT || t == IGNORABLE_WHITESPACE || t == CDSECT;
+    }
+
+    /** Recursively builds the child elements from the given parser
+    until an end tag or end document is found. 
+        The end tag is not consumed. */
+
+    public void parse(XmlPullParser parser)
+        throws IOException, XmlPullParserException {
+
+        boolean leave = false;
+
+        do {
+            int type = parser.getEventType();
+            
+   //         System.out.println(parser.getPositionDescription());
+            
+            switch (type) {
+
+                case XmlPullParser.START_TAG :
+                    {
+                        Element child =
+                            createElement(
+                                parser.getNamespace(),
+                                parser.getName());
+                        //    child.setAttributes (event.getAttributes ());
+                        addChild(ELEMENT, child);
+
+                        // order is important here since 
+                        // setparent may perform some init code!
+
+                        child.parse(parser);
+                        break;
+                    }
+
+                case XmlPullParser.END_DOCUMENT :
+                case XmlPullParser.END_TAG :
+                    leave = true;
+                    break;
+
+                default :
+                    if (parser.getText() != null)
+                        addChild(
+                            type == XmlPullParser.ENTITY_REF ? TEXT : type,
+                            parser.getText());
+                    else if (
+                        type == XmlPullParser.ENTITY_REF
+                            && parser.getName() != null) {
+                        addChild(ENTITY_REF, parser.getName());
+                    }
+                    parser.nextToken();
+            }
+        }
+        while (!leave);
+    }
+
+    /** Removes the child object at the given index */
+
+    public void removeChild(int idx) {
+        children.removeElementAt(idx);
+
+        /***  Modification by HHS - start ***/
+        //      types.deleteCharAt (index);
+        /***/
+        int n = types.length() - 1;
+
+        for (int i = idx; i < n; i++)
+            types.setCharAt(i, types.charAt(i + 1));
+
+        types.setLength(n);
+
+        /***  Modification by HHS - end   ***/
+    }
+
+    /* returns a valid XML representation of this Element including
+        attributes and children. 
+    public String toString() {
+        try {
+            ByteArrayOutputStream bos =
+                new ByteArrayOutputStream();
+            XmlWriter xw =
+                new XmlWriter(new OutputStreamWriter(bos));
+            write(xw);
+            xw.close();
+            return new String(bos.toByteArray());
+        }
+        catch (IOException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+    */
+
+    /** Writes this node to the given XmlWriter. For node and document,
+        this method is identical to writeChildren, except that the
+        stream is flushed automatically. */
+
+    public void write(XmlSerializer writer) throws IOException {
+        writeChildren(writer);
+        writer.flush();
+    }
+
+    /** Writes the children of this node to the given XmlWriter. */
+
+    public void writeChildren(XmlSerializer writer) throws IOException {
+        if (children == null)
+            return;
+
+        int len = children.size();
+
+        for (int i = 0; i < len; i++) {
+            int type = getType(i);
+            Object child = children.elementAt(i);
+            switch (type) {
+                case ELEMENT :
+                     ((Element) child).write(writer);
+                    break;
+
+                case TEXT :
+                    writer.text((String) child);
+                    break;
+
+                case IGNORABLE_WHITESPACE :
+                    writer.ignorableWhitespace((String) child);
+                    break;
+
+                case CDSECT :
+                    writer.cdsect((String) child);
+                    break;
+
+                case COMMENT :
+                    writer.comment((String) child);
+                    break;
+
+                case ENTITY_REF :
+                    writer.entityRef((String) child);
+                    break;
+
+                case PROCESSING_INSTRUCTION :
+                    writer.processingInstruction((String) child);
+                    break;
+
+                case DOCDECL :
+                    writer.docdecl((String) child);
+                    break;
+
+                default :
+                    throw new RuntimeException("Illegal type: " + type);
+            }
+        }
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/wap/Wbxml.java b/xml/src/main/java/org/kxml2/wap/Wbxml.java
new file mode 100644
index 0000000..5b0c2d3
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/Wbxml.java
@@ -0,0 +1,49 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.wap;
+
+
+/** contains the WBXML constants  */
+
+
+public interface Wbxml {
+
+    static public final int SWITCH_PAGE = 0;
+    static public final int END = 1;
+    static public final int ENTITY = 2;
+    static public final int STR_I = 3;
+    static public final int LITERAL = 4;
+    static public final int EXT_I_0 = 0x40;
+    static public final int EXT_I_1 = 0x41;
+    static public final int EXT_I_2 = 0x42;
+    static public final int PI = 0x43;
+    static public final int LITERAL_C = 0x44;
+    static public final int EXT_T_0 = 0x80;
+    static public final int EXT_T_1 = 0x81;
+    static public final int EXT_T_2 = 0x82;
+    static public final int STR_T = 0x83;
+    static public final int LITERAL_A = 0x084;
+    static public final int EXT_0 = 0x0c0;
+    static public final int EXT_1 = 0x0c1;
+    static public final int EXT_2 = 0x0c2;
+    static public final int OPAQUE = 0x0c3; 
+    static public final int LITERAL_AC = 0x0c4;
+}
diff --git a/xml/src/main/java/org/kxml2/wap/WbxmlParser.java b/xml/src/main/java/org/kxml2/wap/WbxmlParser.java
new file mode 100644
index 0000000..617e1d4
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/WbxmlParser.java
@@ -0,0 +1,1075 @@
+/* Copyright (c) 2002,2003,2004 Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+// Contributors: Bjorn Aadland, Chris Bartley, Nicola Fankhauser,
+//               Victor Havin,  Christian Kurzke, Bogdan Onoiu,
+//                Elias Ross, Jain Sanjay, David Santoro.
+
+package org.kxml2.wap;
+
+import java.io.*;
+import java.util.Vector;
+import java.util.Hashtable;
+
+import org.xmlpull.v1.*;
+
+
+public class WbxmlParser implements XmlPullParser {
+
+    static final String HEX_DIGITS = "0123456789abcdef";
+    
+    /** Parser event type for Wbxml-specific events. The Wbxml event code can be 
+     * accessed with getWapCode() */
+    
+    public static final int WAP_EXTENSION = 64;
+    
+    static final private String UNEXPECTED_EOF =
+    "Unexpected EOF";
+    static final private String ILLEGAL_TYPE =
+    "Wrong event type";
+    
+    private InputStream in;
+    
+    private int TAG_TABLE = 0;
+    private int ATTR_START_TABLE = 1;
+    private int ATTR_VALUE_TABLE = 2;
+    
+    private String[] attrStartTable;
+    private String[] attrValueTable;
+    private String[] tagTable;
+    private byte[] stringTable;
+    private Hashtable cacheStringTable = null;
+    private boolean processNsp;
+    
+    private int depth;
+    private String[] elementStack = new String[16];
+    private String[] nspStack = new String[8];
+    private int[] nspCounts = new int[4];
+    
+    private int attributeCount;
+    private String[] attributes = new String[16];
+    private int nextId = -2;
+    
+    private Vector tables = new Vector();
+    
+    private int version;
+    private int publicIdentifierId;
+    
+    //    StartTag current;
+    //    ParseEvent next;
+    
+    private String prefix;
+    private String namespace;
+    private String name;
+    private String text;
+
+    private Object wapExtensionData;
+    private int wapCode;
+    
+    private int type;
+    
+    private boolean degenerated;
+    private boolean isWhitespace;
+    private String encoding;
+    
+    public boolean getFeature(String feature) {
+        if (XmlPullParser
+        .FEATURE_PROCESS_NAMESPACES
+        .equals(feature))
+            return processNsp;
+        else
+            return false;
+    }
+    
+    public String getInputEncoding() {
+        return encoding;
+    }
+    
+    public void defineEntityReplacementText(
+    String entity,
+    String value)
+    throws XmlPullParserException {
+        
+        // just ignore, has no effect
+    }
+    
+    public Object getProperty(String property) {
+        return null;
+    }
+    
+    public int getNamespaceCount(int depth) {
+        if (depth > this.depth)
+            throw new IndexOutOfBoundsException();
+        return nspCounts[depth];
+    }
+    
+    public String getNamespacePrefix(int pos) {
+        return nspStack[pos << 1];
+    }
+    
+    public String getNamespaceUri(int pos) {
+        return nspStack[(pos << 1) + 1];
+    }
+    
+    public String getNamespace(String prefix) {
+        
+        if ("xml".equals(prefix))
+            return "http://www.w3.org/XML/1998/namespace";
+        if ("xmlns".equals(prefix))
+            return "http://www.w3.org/2000/xmlns/";
+        
+        for (int i = (getNamespaceCount(depth) << 1) - 2;
+        i >= 0;
+        i -= 2) {
+            if (prefix == null) {
+                if (nspStack[i] == null)
+                    return nspStack[i + 1];
+            }
+            else if (prefix.equals(nspStack[i]))
+                return nspStack[i + 1];
+        }
+        return null;
+    }
+    
+    public int getDepth() {
+        return depth;
+    }
+    
+    public String getPositionDescription() {
+        
+        StringBuffer buf =
+        new StringBuffer(
+        type < TYPES.length ? TYPES[type] : "unknown");
+        buf.append(' ');
+        
+        if (type == START_TAG || type == END_TAG) {
+            if (degenerated)
+                buf.append("(empty) ");
+            buf.append('<');
+            if (type == END_TAG)
+                buf.append('/');
+            
+            if (prefix != null)
+                buf.append("{" + namespace + "}" + prefix + ":");
+            buf.append(name);
+            
+            int cnt = attributeCount << 2;
+            for (int i = 0; i < cnt; i += 4) {
+                buf.append(' ');
+                if (attributes[i + 1] != null)
+                    buf.append(
+                    "{"
+                    + attributes[i]
+                    + "}"
+                    + attributes[i
+                    + 1]
+                    + ":");
+                buf.append(
+                attributes[i
+                + 2]
+                + "='"
+                + attributes[i
+                + 3]
+                + "'");
+            }
+            
+            buf.append('>');
+        }
+        else if (type == IGNORABLE_WHITESPACE);
+        else if (type != TEXT)
+            buf.append(getText());
+        else if (isWhitespace)
+            buf.append("(whitespace)");
+        else {
+            String text = getText();
+            if (text.length() > 16)
+                text = text.substring(0, 16) + "...";
+            buf.append(text);
+        }
+        
+        return buf.toString();
+    }
+    
+    public int getLineNumber() {
+        return -1;
+    }
+    
+    public int getColumnNumber() {
+        return -1;
+    }
+    
+    public boolean isWhitespace()
+    throws XmlPullParserException {
+        if (type != TEXT
+        && type != IGNORABLE_WHITESPACE
+        && type != CDSECT)
+            exception(ILLEGAL_TYPE);
+        return isWhitespace;
+    }
+    
+    public String getText() {
+        return text;
+    }
+    
+    public char[] getTextCharacters(int[] poslen) {
+        if (type >= TEXT) {
+            poslen[0] = 0;
+            poslen[1] = text.length();
+            char[] buf = new char[text.length()];
+            text.getChars(0, text.length(), buf, 0);
+            return buf;
+        }
+        
+        poslen[0] = -1;
+        poslen[1] = -1;
+        return null;
+    }
+    
+    public String getNamespace() {
+        return namespace;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public String getPrefix() {
+        return prefix;
+    }
+    
+    public boolean isEmptyElementTag()
+    throws XmlPullParserException {
+        if (type != START_TAG)
+            exception(ILLEGAL_TYPE);
+        return degenerated;
+    }
+    
+    public int getAttributeCount() {
+        return attributeCount;
+    }
+    
+    public String getAttributeType(int index) {
+        return "CDATA";
+    }
+    
+    public boolean isAttributeDefault(int index) {
+        return false;
+    }
+    
+    public String getAttributeNamespace(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[index << 2];
+    }
+    
+    public String getAttributeName(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 2];
+    }
+    
+    public String getAttributePrefix(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 1];
+    }
+    
+    public String getAttributeValue(int index) {
+        if (index >= attributeCount)
+            throw new IndexOutOfBoundsException();
+        return attributes[(index << 2) + 3];
+    }
+    
+    public String getAttributeValue(
+    String namespace,
+    String name) {
+        
+        for (int i = (attributeCount << 2) - 4;
+        i >= 0;
+        i -= 4) {
+            if (attributes[i + 2].equals(name)
+            && (namespace == null
+            || attributes[i].equals(namespace)))
+                return attributes[i + 3];
+        }
+        
+        return null;
+    }
+    
+    public int getEventType() throws XmlPullParserException {
+        return type;
+    }
+    
+    
+    // TODO: Reuse resolveWapExtension here? Raw Wap extensions would still be accessible
+    // via nextToken();  ....?
+    
+    public int next() throws XmlPullParserException, IOException {
+        
+        isWhitespace = true;
+        int minType = 9999;
+        
+        while (true) {
+            
+            String save = text;
+            
+            nextImpl();
+            
+            if (type < minType)
+                minType = type;
+            
+            if (minType > CDSECT) continue; // no "real" event so far
+            
+            if (minType >= TEXT) {  // text, see if accumulate
+                
+                if (save != null) text = text == null ? save : save + text;
+                
+                switch(peekId()) {
+                    case Wbxml.ENTITY:
+                    case Wbxml.STR_I:
+                    case Wbxml.STR_T:
+                    case Wbxml.LITERAL:
+                    case Wbxml.LITERAL_C:
+                    case Wbxml.LITERAL_A:
+                    case Wbxml.LITERAL_AC: continue;
+                }
+            }
+            
+            break;
+        }
+        
+        type = minType;
+        
+        if (type > TEXT)
+            type = TEXT;
+        
+        return type;
+    }
+    
+    
+    public int nextToken() throws XmlPullParserException, IOException {
+        
+        isWhitespace = true;
+        nextImpl();
+        return type;
+    }
+    
+    
+    
+    public int nextTag() throws XmlPullParserException, IOException {
+        
+        next();
+        if (type == TEXT && isWhitespace)
+            next();
+        
+        if (type != END_TAG && type != START_TAG)
+            exception("unexpected type");
+        
+        return type;
+    }
+    
+    
+    public String nextText() throws XmlPullParserException, IOException {
+        if (type != START_TAG)
+            exception("precondition: START_TAG");
+        
+        next();
+        
+        String result;
+        
+        if (type == TEXT) {
+            result = getText();
+            next();
+        }
+        else
+            result = "";
+        
+        if (type != END_TAG)
+            exception("END_TAG expected");
+        
+        return result;
+    }
+    
+    
+    public void require(int type, String namespace, String name)
+    throws XmlPullParserException, IOException {
+        
+        if (type != this.type
+        || (namespace != null && !namespace.equals(getNamespace()))
+        || (name != null && !name.equals(getName())))
+            exception(
+            "expected: " + (type == WAP_EXTENSION ? "WAP Ext." : (TYPES[type] + " {" + namespace + "}" + name)));
+    }
+    
+    
+    public void setInput(Reader reader) throws XmlPullParserException {
+        exception("InputStream required");
+    }
+    
+    public void setInput(InputStream in, String enc)
+    throws XmlPullParserException {
+        
+        this.in = in;
+        
+        try {
+            version = readByte();
+            publicIdentifierId = readInt();
+            
+            if (publicIdentifierId == 0)
+                readInt();
+            
+            int charset = readInt(); // skip charset
+            
+            if (null == enc){
+                switch (charset){
+                    case   4: encoding = "ISO-8859-1"; break;
+                    case 106: encoding = "UTF-8";      break;
+                    // add more if you need them
+                    // http://www.iana.org/assignments/character-sets
+                    // case MIBenum: encoding = Name  break;
+                    default:  throw new UnsupportedEncodingException(""+charset);
+                } 
+            }else{
+                encoding = enc;
+            }
+
+            int strTabSize = readInt();
+            stringTable = new byte[strTabSize];
+            
+            int ok = 0;
+            while(ok < strTabSize){
+                int cnt = in.read(stringTable, ok, strTabSize - ok);
+                if(cnt <= 0) break;
+                ok += cnt;
+            }
+            
+            selectPage(0, true);
+            selectPage(0, false);
+        }
+        catch (IOException e) {
+            exception("Illegal input format");
+        }
+    }
+    
+    public void setFeature(String feature, boolean value)
+    throws XmlPullParserException {
+        if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+            processNsp = value;
+        else
+            exception("unsupported feature: " + feature);
+    }
+    
+    public void setProperty(String property, Object value)
+    throws XmlPullParserException {
+        throw new XmlPullParserException("unsupported property: " + property);
+    }
+    
+    // ---------------------- private / internal methods
+    
+    private final boolean adjustNsp()
+    throws XmlPullParserException {
+        
+        boolean any = false;
+        
+        for (int i = 0; i < attributeCount << 2; i += 4) {
+            // * 4 - 4; i >= 0; i -= 4) {
+            
+            String attrName = attributes[i + 2];
+            int cut = attrName.indexOf(':');
+            String prefix;
+            
+            if (cut != -1) {
+                prefix = attrName.substring(0, cut);
+                attrName = attrName.substring(cut + 1);
+            }
+            else if (attrName.equals("xmlns")) {
+                prefix = attrName;
+                attrName = null;
+            }
+            else
+                continue;
+            
+            if (!prefix.equals("xmlns")) {
+                any = true;
+            }
+            else {
+                int j = (nspCounts[depth]++) << 1;
+                
+                nspStack = ensureCapacity(nspStack, j + 2);
+                nspStack[j] = attrName;
+                nspStack[j + 1] = attributes[i + 3];
+                
+                if (attrName != null
+                && attributes[i + 3].equals(""))
+                    exception("illegal empty namespace");
+                
+                //  prefixMap = new PrefixMap (prefixMap, attrName, attr.getValue ());
+                
+                //System.out.println (prefixMap);
+                
+                System.arraycopy(
+                attributes,
+                i + 4,
+                attributes,
+                i,
+                ((--attributeCount) << 2) - i);
+                
+                i -= 4;
+            }
+        }
+        
+        if (any) {
+            for (int i = (attributeCount << 2) - 4;
+            i >= 0;
+            i -= 4) {
+                
+                String attrName = attributes[i + 2];
+                int cut = attrName.indexOf(':');
+                
+                if (cut == 0)
+                    throw new RuntimeException(
+                    "illegal attribute name: "
+                    + attrName
+                    + " at "
+                    + this);
+                
+                else if (cut != -1) {
+                    String attrPrefix =
+                    attrName.substring(0, cut);
+                    
+                    attrName = attrName.substring(cut + 1);
+                    
+                    String attrNs = getNamespace(attrPrefix);
+                    
+                    if (attrNs == null)
+                        throw new RuntimeException(
+                        "Undefined Prefix: "
+                        + attrPrefix
+                        + " in "
+                        + this);
+                    
+                    attributes[i] = attrNs;
+                    attributes[i + 1] = attrPrefix;
+                    attributes[i + 2] = attrName;
+                    
+                    for (int j = (attributeCount << 2) - 4;
+                    j > i;
+                    j -= 4)
+                        if (attrName.equals(attributes[j + 2])
+                        && attrNs.equals(attributes[j]))
+                            exception(
+                            "Duplicate Attribute: {"
+                            + attrNs
+                            + "}"
+                            + attrName);
+                }
+            }
+        }
+        
+        int cut = name.indexOf(':');
+        
+        if (cut == 0)
+            exception("illegal tag name: " + name);
+        else if (cut != -1) {
+            prefix = name.substring(0, cut);
+            name = name.substring(cut + 1);
+        }
+        
+        this.namespace = getNamespace(prefix);
+        
+        if (this.namespace == null) {
+            if (prefix != null)
+                exception("undefined prefix: " + prefix);
+            this.namespace = NO_NAMESPACE;
+        }
+        
+        return any;
+    }
+    
+    private final void setTable(int page, int type, String[] table) {
+        if(stringTable != null){
+            throw new RuntimeException("setXxxTable must be called before setInput!");
+        }
+        while(tables.size() < 3*page +3){
+            tables.addElement(null);
+        }
+        tables.setElementAt(table, page*3+type);
+    }
+    
+    
+    
+    
+    
+    private final void exception(String desc)
+    throws XmlPullParserException {
+        throw new XmlPullParserException(desc, this, null);
+    }
+    
+    
+    private void selectPage(int nr, boolean tags) throws XmlPullParserException{
+        if(tables.size() == 0 && nr == 0) return;
+        
+        if(nr*3 > tables.size())
+            exception("Code Page "+nr+" undefined!");
+        
+        if(tags)
+            tagTable = (String[]) tables.elementAt(nr * 3 + TAG_TABLE);
+        else {
+            attrStartTable = (String[]) tables.elementAt(nr * 3 + ATTR_START_TABLE);
+            attrValueTable = (String[]) tables.elementAt(nr * 3 + ATTR_VALUE_TABLE);
+        }
+    }
+    
+    private final void nextImpl()
+    throws IOException, XmlPullParserException {
+        
+        String s;
+        
+        if (type == END_TAG) {
+            depth--;
+        }
+        
+        if (degenerated) {
+            type = XmlPullParser.END_TAG;
+            degenerated = false;
+            return;
+        }
+        
+        text = null;
+        prefix = null;
+        name = null;
+        
+        int id = peekId ();
+        while(id == Wbxml.SWITCH_PAGE){
+            nextId = -2;
+            selectPage(readByte(), true);
+            id = peekId();
+        }
+        nextId = -2;
+        
+        switch (id) {
+            case -1 :
+                type = XmlPullParser.END_DOCUMENT;
+                break;
+                
+            case Wbxml.END : 
+            {
+                int sp = (depth - 1) << 2;
+                
+                type = END_TAG;
+                namespace = elementStack[sp];
+                prefix = elementStack[sp + 1];
+                name = elementStack[sp + 2];
+            }
+            break;
+            
+            case Wbxml.ENTITY : 
+            {
+                type = ENTITY_REF;
+                char c = (char) readInt();
+                text = "" + c;
+                name = "#" + ((int) c);
+            }
+            
+            break;
+            
+            case Wbxml.STR_I :
+                type = TEXT;
+                text = readStrI();
+                break;
+                
+            case Wbxml.EXT_I_0 :
+            case Wbxml.EXT_I_1 :
+            case Wbxml.EXT_I_2 :
+            case Wbxml.EXT_T_0 :
+            case Wbxml.EXT_T_1 :
+            case Wbxml.EXT_T_2 :
+            case Wbxml.EXT_0 :
+            case Wbxml.EXT_1 :
+            case Wbxml.EXT_2 :
+            case Wbxml.OPAQUE :
+                
+                type = WAP_EXTENSION;
+                wapCode = id;
+                wapExtensionData = parseWapExtension(id);
+                break;
+                
+            case Wbxml.PI :
+                throw new RuntimeException("PI curr. not supp.");
+                // readPI;
+                // break;
+                
+            case Wbxml.STR_T : 
+            {
+                type = TEXT;
+                text = readStrT();
+            }
+            break;
+            
+            default :
+                parseElement(id);
+        }
+        //        }
+        //      while (next == null);
+        
+        //        return next;
+    }
+    
+    /** Overwrite this method to intercept all wap events */
+    
+    public Object parseWapExtension(int id)  throws IOException, XmlPullParserException {
+        
+        switch (id) {
+            case Wbxml.EXT_I_0 :
+            case Wbxml.EXT_I_1 :
+            case Wbxml.EXT_I_2 :
+                return readStrI();
+                
+            case Wbxml.EXT_T_0 :
+            case Wbxml.EXT_T_1 :
+            case Wbxml.EXT_T_2 :
+                return new Integer(readInt());
+                
+            case Wbxml.EXT_0 :
+            case Wbxml.EXT_1 :
+            case Wbxml.EXT_2 :
+                return null;
+                
+            case Wbxml.OPAQUE : 
+            {
+                int count = readInt();
+                byte[] buf = new byte[count];
+                
+                while(count > 0){
+                    count -= in.read(buf, buf.length-count, count);
+                }
+                
+                return buf;
+            } // case OPAQUE
+    
+            
+            default:
+                exception("illegal id: "+id);
+                return null; // dead code
+        } // SWITCH
+    }
+    
+    public void readAttr() throws IOException, XmlPullParserException {
+        
+        int id = readByte();
+        int i = 0;
+        
+        while (id != 1) {
+            
+            while(id == Wbxml.SWITCH_PAGE){
+                selectPage(readByte(), false);
+                id = readByte();
+            }
+            
+            String name = resolveId(attrStartTable, id);
+            StringBuffer value;
+            
+            int cut = name.indexOf('=');
+            
+            if (cut == -1)
+                value = new StringBuffer();
+            else {
+                value =
+                new StringBuffer(name.substring(cut + 1));
+                name = name.substring(0, cut);
+            }
+            
+            id = readByte();
+            while (id > 128
+            || id == Wbxml.SWITCH_PAGE
+            || id == Wbxml.ENTITY
+            || id == Wbxml.STR_I
+            || id == Wbxml.STR_T
+            || (id >= Wbxml.EXT_I_0 && id <= Wbxml.EXT_I_2)
+            || (id >= Wbxml.EXT_T_0 && id <= Wbxml.EXT_T_2)) {
+                
+                switch (id) {
+                    case Wbxml.SWITCH_PAGE :
+                        selectPage(readByte(), false);
+                        break;
+                        
+                    case Wbxml.ENTITY :
+                        value.append((char) readInt());
+                        break;
+                        
+                    case Wbxml.STR_I :
+                        value.append(readStrI());
+                        break;
+                        
+                    case Wbxml.EXT_I_0 :
+                    case Wbxml.EXT_I_1 :
+                    case Wbxml.EXT_I_2 :
+                    case Wbxml.EXT_T_0 :
+                    case Wbxml.EXT_T_1 :
+                    case Wbxml.EXT_T_2 :
+                    case Wbxml.EXT_0 :
+                    case Wbxml.EXT_1 :
+                    case Wbxml.EXT_2 :
+                    case Wbxml.OPAQUE :
+                        value.append(resolveWapExtension(id, parseWapExtension(id)));
+                        break;
+                        
+                    case Wbxml.STR_T :
+                        value.append(readStrT());
+                        break;
+                        
+                    default :
+                        value.append(
+                        resolveId(attrValueTable, id));
+                }
+                
+                id = readByte();
+            }
+            
+            attributes = ensureCapacity(attributes, i + 4);
+            
+            attributes[i++] = "";
+            attributes[i++] = null;
+            attributes[i++] = name;
+            attributes[i++] = value.toString();
+            
+            attributeCount++;
+        }
+    }
+    
+    private int peekId () throws IOException {
+        if (nextId == -2) {
+            nextId = in.read ();
+        }
+        return nextId;
+    }
+    
+    /** overwrite for own WAP extension handling in attributes and high level parsing 
+     * (above nextToken() level) */
+    
+    protected String resolveWapExtension(int id, Object data){
+        
+        if(data instanceof byte[]){
+            StringBuffer sb = new StringBuffer();
+            byte[] b = (byte[]) data;
+            
+            for (int i = 0; i < b.length; i++) {
+                sb.append(HEX_DIGITS.charAt((b[i] >> 4) & 0x0f));
+                sb.append(HEX_DIGITS.charAt(b[i] & 0x0f));
+            }
+            return sb.toString();
+        }
+
+        return "$("+data+")";
+    }
+    
+    String resolveId(String[] tab, int id) throws IOException {
+        int idx = (id & 0x07f) - 5;
+        if (idx == -1){
+            wapCode = -1;
+            return readStrT();
+        }
+        if (idx < 0
+        || tab == null
+        || idx >= tab.length
+        || tab[idx] == null)
+            throw new IOException("id " + id + " undef.");
+        
+        wapCode = idx+5;
+        
+        return tab[idx];
+    }
+    
+    void parseElement(int id)
+    throws IOException, XmlPullParserException {
+        
+        type = START_TAG;
+        name = resolveId(tagTable, id & 0x03f);
+        
+        attributeCount = 0;
+        if ((id & 128) != 0) {
+            readAttr();
+        }
+        
+        degenerated = (id & 64) == 0;
+        
+        int sp = depth++ << 2;
+        
+        // transfer to element stack
+        
+        elementStack = ensureCapacity(elementStack, sp + 4);
+        elementStack[sp + 3] = name;
+        
+        if (depth >= nspCounts.length) {
+            int[] bigger = new int[depth + 4];
+            System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
+            nspCounts = bigger;
+        }
+        
+        nspCounts[depth] = nspCounts[depth - 1];
+        
+        for (int i = attributeCount - 1; i > 0; i--) {
+            for (int j = 0; j < i; j++) {
+                if (getAttributeName(i)
+                .equals(getAttributeName(j)))
+                    exception(
+                    "Duplicate Attribute: "
+                    + getAttributeName(i));
+            }
+        }
+        
+        if (processNsp)
+            adjustNsp();
+        else
+            namespace = "";
+        
+        elementStack[sp] = namespace;
+        elementStack[sp + 1] = prefix;
+        elementStack[sp + 2] = name;
+        
+    }
+    
+    private final String[] ensureCapacity(
+    String[] arr,
+    int required) {
+        if (arr.length >= required)
+            return arr;
+        String[] bigger = new String[required + 16];
+        System.arraycopy(arr, 0, bigger, 0, arr.length);
+        return bigger;
+    }
+    
+    int readByte() throws IOException {
+        int i = in.read();
+        if (i == -1)
+            throw new IOException("Unexpected EOF");
+        return i;
+    }
+    
+    int readInt() throws IOException {
+        int result = 0;
+        int i;
+        
+        do {
+            i = readByte();
+            result = (result << 7) | (i & 0x7f);
+        }
+        while ((i & 0x80) != 0);
+        
+        return result;
+    }
+    
+    String readStrI() throws IOException {
+        ByteArrayOutputStream buf = new ByteArrayOutputStream();
+        boolean wsp = true;
+        while (true){
+            int i = in.read();
+            if (i == 0){
+                break;
+            }
+            if (i == -1){
+                throw new IOException(UNEXPECTED_EOF);
+            }
+            if (i > 32){
+                wsp = false;
+            }
+            buf.write(i);
+        }
+        isWhitespace = wsp;
+        String result = new String(buf.toByteArray(), encoding);
+        buf.close();
+        return result;
+    }
+    
+    String readStrT() throws IOException {
+        int pos = readInt();
+        // As the main reason of stringTable is compression we build a cache of Strings
+        // stringTable is supposed to help create Strings from parts which means some cache hit rate
+        // This will help to minimize the Strings created when invoking readStrT() repeatedly
+        if (cacheStringTable == null){
+            //Lazy init if device is not using StringTable but inline 0x03 strings
+            cacheStringTable = new Hashtable();
+        }
+        String forReturn = (String) cacheStringTable.get(new Integer(pos));
+        if (forReturn == null){
+
+            int end = pos;
+            while(end < stringTable.length && stringTable[end] != '\0'){
+                end++;
+            }
+            forReturn = new String(stringTable, pos, end-pos, encoding);
+            cacheStringTable.put(new Integer(pos), forReturn);
+        }
+        return forReturn;
+    }
+    
+    /**
+     * Sets the tag table for a given page.
+     * The first string in the array defines tag 5, the second tag 6 etc.
+     */
+    
+    public void setTagTable(int page, String[] table) {
+        setTable(page, TAG_TABLE, table);
+        
+        //        this.tagTable = tagTable;
+        //      if (page != 0)
+        //        throw new RuntimeException("code pages curr. not supp.");
+    }
+    
+    /** Sets the attribute start Table for a given page.
+     *  The first string in the array defines attribute
+     *  5, the second attribute 6 etc. Please use the
+     *  character '=' (without quote!) as delimiter
+     *  between the attribute name and the (start of the) value
+     */
+    
+    public void setAttrStartTable(
+    int page,
+    String[] table) {
+        
+        setTable(page, ATTR_START_TABLE, table);
+    }
+    
+    /** Sets the attribute value Table for a given page.
+     *  The first string in the array defines attribute value 0x85,
+     *  the second attribute value 0x86 etc.
+     */
+    
+    public void setAttrValueTable(
+    int page,
+    String[] table) {
+        
+        setTable(page, ATTR_VALUE_TABLE, table);
+    }
+    
+    /** Returns the token ID for start tags or the event type for wap proprietary events
+     * such as OPAQUE.
+     */
+    
+    public int getWapCode(){
+        return wapCode;
+    }
+    
+    public Object getWapExtensionData(){
+        return wapExtensionData;
+    }
+    
+    
+}
diff --git a/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java b/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java
new file mode 100644
index 0000000..8c1b598
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java
@@ -0,0 +1,512 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The  above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+//Contributors: Jonathan Cox, Bogdan Onoiu, Jerry Tian
+
+package org.kxml2.wap;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+// TODO: make some of the "direct" WBXML token writing methods public??
+
+/**
+ * A class for writing WBXML.
+ *
+ */
+
+
+
+public class WbxmlSerializer implements XmlSerializer {
+    
+    
+    Hashtable stringTable = new Hashtable();
+    
+    OutputStream out;
+    
+    ByteArrayOutputStream buf = new ByteArrayOutputStream();
+    ByteArrayOutputStream stringTableBuf = new ByteArrayOutputStream();
+    
+    String pending;
+    int depth;
+    String name;
+    String namespace;
+    Vector attributes = new Vector();
+    
+    Hashtable attrStartTable = new Hashtable();
+    Hashtable attrValueTable = new Hashtable();
+    Hashtable tagTable = new Hashtable();
+    
+    private int attrPage;
+    private int tagPage;
+    
+    private String encoding;
+    
+    
+    public XmlSerializer attribute(String namespace, String name, String value) {
+        attributes.addElement(name);
+        attributes.addElement(value);
+        return this;
+    }
+    
+    
+    public void cdsect (String cdsect) throws IOException{
+        text (cdsect);
+    }
+    
+    
+    
+    /* silently ignore comment */
+    
+    public void comment (String comment) {
+    }
+    
+    
+    public void docdecl (String docdecl) {
+        throw new RuntimeException ("Cannot write docdecl for WBXML");
+    }
+    
+    
+    public void entityRef (String er) {
+        throw new RuntimeException ("EntityReference not supported for WBXML");
+    }
+    
+    public int getDepth() {
+        return depth;
+    }
+    
+    
+    public boolean getFeature (String name) {
+        return false;
+    }
+    
+    public String getNamespace() {
+        throw new RuntimeException("NYI");
+    }
+    
+    public String getName() {
+        throw new RuntimeException("NYI");
+    }
+    
+    public String getPrefix(String nsp, boolean create) {
+        throw new RuntimeException ("NYI");
+    }
+    
+    
+    public Object getProperty (String name) {
+        return null;
+    }
+    
+    public void ignorableWhitespace (String sp) {
+    }
+    
+    
+    public void endDocument() throws IOException {
+        writeInt(out, stringTableBuf.size());
+        
+        // write StringTable
+        
+        out.write(stringTableBuf.toByteArray());
+        
+        // write buf
+        
+        out.write(buf.toByteArray());
+        
+        // ready!
+        
+        out.flush();
+    }
+    
+    
+    /** ATTENTION: flush cannot work since Wbxml documents require
+      buffering. Thus, this call does nothing. */
+    
+    public void flush() {
+    }
+    
+    
+    public void checkPending(boolean degenerated) throws IOException {
+        if (pending == null)
+            return;
+        
+        int len = attributes.size();
+        
+        int[] idx = (int[]) tagTable.get(pending);
+        
+        // if no entry in known table, then add as literal
+        if (idx == null) {
+            buf.write(
+            len == 0
+            ? (degenerated ? Wbxml.LITERAL : Wbxml.LITERAL_C)
+            : (degenerated ? Wbxml.LITERAL_A : Wbxml.LITERAL_AC));
+            
+            writeStrT(pending, false);
+        }
+        else {
+            if(idx[0] != tagPage){
+                tagPage=idx[0];
+                buf.write(Wbxml.SWITCH_PAGE);
+                buf.write(tagPage);
+            }
+            
+            buf.write(
+            len == 0
+            ? (degenerated ? idx[1] : idx[1] | 64)
+            : (degenerated
+            ? idx[1] | 128
+            : idx[1] | 192));
+           
+        }
+        
+        for (int i = 0; i < len;) {
+            idx = (int[]) attrStartTable.get(attributes.elementAt(i));
+            
+            if (idx == null) {
+                buf.write(Wbxml.LITERAL);
+                writeStrT((String) attributes.elementAt(i), false);
+            }
+            else {
+                if(idx[0] != attrPage){
+                        attrPage = idx[0];
+                    buf.write(0);
+                    buf.write(attrPage);
+                }
+                buf.write(idx[1]);
+            }
+            idx = (int[]) attrValueTable.get(attributes.elementAt(++i));
+            if (idx == null) {
+                writeStr((String) attributes.elementAt(i));
+            }
+            else {
+                if(idx[0] != attrPage){
+                        attrPage = idx[0];
+                    buf.write(0);
+                    buf.write(attrPage);                    
+                }
+                buf.write(idx[1]);
+            }
+            ++i;
+        }
+        
+        if (len > 0)
+            buf.write(Wbxml.END);
+        
+        pending = null;
+        attributes.removeAllElements();
+    }
+    
+    
+    public void processingInstruction(String pi) {
+        throw new RuntimeException ("PI NYI");
+    }
+    
+    
+    public void setFeature(String name, boolean value) {
+        throw new IllegalArgumentException ("unknown feature "+name);
+    }
+    
+    
+    
+    public void setOutput (Writer writer) {
+        throw new RuntimeException ("Wbxml requires an OutputStream!");
+    }
+    
+    public void setOutput (OutputStream out, String encoding) throws IOException {
+        
+        this.encoding = encoding == null ? "UTF-8" : encoding;
+        this.out = out;
+        
+        buf = new ByteArrayOutputStream();
+        stringTableBuf = new ByteArrayOutputStream();
+        
+        // ok, write header
+    }
+    
+    
+    public void setPrefix(String prefix, String nsp) {
+        throw new RuntimeException("NYI");
+    }
+    
+    public void setProperty(String property, Object value) {
+        throw new IllegalArgumentException ("unknown property "+property);
+    }
+    
+    
+    public void startDocument(String s, Boolean b) throws IOException{
+        out.write(0x03); // version 1.3
+        // http://www.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.htm
+        out.write(0x01); // unknown or missing public identifier
+
+        // default encoding is UTF-8
+        
+        if(s != null){
+            encoding = s;
+        }
+        
+        if (encoding.toUpperCase().equals("UTF-8")){
+            out.write(106);
+        }else if (encoding.toUpperCase().equals("ISO-8859-1")){
+            out.write(0x04);
+        }else{
+            throw new UnsupportedEncodingException(s);
+        }
+    }
+    
+    
+    public XmlSerializer startTag(String namespace, String name) throws IOException {
+        
+        if (namespace != null && !"".equals(namespace))
+            throw new RuntimeException ("NSP NYI");
+        
+        //current = new State(current, prefixMap, name);
+        
+        checkPending(false);
+        pending = name;
+        depth++;
+        
+        return this;
+    }
+    
+    public XmlSerializer text(char[] chars, int start, int len) throws IOException {
+
+        checkPending(false);
+        
+        writeStr(new String(chars, start, len));
+        
+        return this;
+    }
+    
+    public XmlSerializer text(String text) throws IOException {
+        
+        checkPending(false);
+        
+        writeStr(text);
+    
+        return this;
+    }
+    
+
+    /** Used in text() and attribute() to write text */
+    
+    private void writeStr(String text) throws IOException{
+        int p0 = 0;
+        int lastCut = 0;
+        int len = text.length();
+        
+        while(p0 < len){
+            while(p0 < len && text.charAt(p0) < 'A' ){ // skip interpunctation
+                p0++;
+            }
+            int p1 = p0;
+            while(p1 < len && text.charAt(p1) >= 'A'){
+                p1++;
+            }
+            
+            if(p1 - p0 > 10) {
+
+                if(p0 > lastCut && text.charAt(p0-1) == ' ' 
+                    && stringTable.get(text.substring(p0, p1)) == null){
+                    
+                       buf.write(Wbxml.STR_T);
+                       writeStrT(text.substring(lastCut, p1), false);
+                }
+                else {
+
+                    if(p0 > lastCut && text.charAt(p0-1) == ' '){
+                        p0--;
+                    }
+
+                    if(p0 > lastCut){
+                        buf.write(Wbxml.STR_T);
+                        writeStrT(text.substring(lastCut, p0), false);
+                    }
+                    buf.write(Wbxml.STR_T);
+                    writeStrT(text.substring(p0, p1), true);
+                }
+                lastCut = p1;
+            }
+            p0 = p1;
+        }
+
+        if(lastCut < len){
+            buf.write(Wbxml.STR_T);
+            writeStrT(text.substring(lastCut, len), false);
+        }
+    }
+    
+    
+
+    public XmlSerializer endTag(String namespace, String name) throws IOException {
+        
+        //        current = current.prev;
+        
+        if (pending != null)
+            checkPending(true);
+        else
+            buf.write(Wbxml.END);
+        
+        depth--;
+        
+        return this;
+    }
+    
+    /** 
+     * @throws IOException */
+    
+    public void writeWapExtension(int type, Object data) throws IOException {
+        checkPending(false);
+        buf.write(type);
+        switch(type){
+        case Wbxml.EXT_0:
+        case Wbxml.EXT_1:
+        case Wbxml.EXT_2:
+            break;
+        
+        case Wbxml.OPAQUE:
+            byte[] bytes = (byte[]) data;
+            writeInt(buf, bytes.length);
+            buf.write(bytes);
+            break;
+            
+        case Wbxml.EXT_I_0:
+        case Wbxml.EXT_I_1:
+        case Wbxml.EXT_I_2:
+            writeStrI(buf, (String) data);
+            break;
+
+        case Wbxml.EXT_T_0:
+        case Wbxml.EXT_T_1:
+        case Wbxml.EXT_T_2:
+            writeStrT((String) data, false);
+            break;
+            
+        default: 
+            throw new IllegalArgumentException();
+        }
+    }
+    
+    // ------------- internal methods --------------------------
+    
+    static void writeInt(OutputStream out, int i) throws IOException {
+        byte[] buf = new byte[5];
+        int idx = 0;
+        
+        do {
+            buf[idx++] = (byte) (i & 0x7f);
+            i = i >> 7;
+        }
+        while (i != 0);
+        
+        while (idx > 1) {
+            out.write(buf[--idx] | 0x80);
+        }
+        out.write(buf[0]);
+    }
+    
+    void writeStrI(OutputStream out, String s) throws IOException {
+        byte[] data = s.getBytes(encoding);
+        out.write(data);
+        out.write(0);
+    }
+    
+    private final void writeStrT(String s, boolean mayPrependSpace) throws IOException {
+        
+        Integer idx = (Integer) stringTable.get(s);
+        
+        if (idx != null) {
+            writeInt(buf, idx.intValue());
+        }
+        else{
+            int i = stringTableBuf.size();
+            if(s.charAt(0) >= '0' && mayPrependSpace){
+                s = ' ' + s;
+                writeInt(buf, i+1);
+            }
+            else{
+                writeInt(buf, i);
+            }
+            
+               stringTable.put(s, new Integer(i));
+               if(s.charAt(0) == ' '){
+                   stringTable.put(s.substring(1), new Integer(i+1));
+               }
+               int j = s.lastIndexOf(' ');
+               if(j > 1){
+                   stringTable.put(s.substring(j), new Integer(i+j));
+                   stringTable.put(s.substring(j+1), new Integer(i+j+1));
+               }
+                
+            writeStrI(stringTableBuf, s);
+            stringTableBuf.flush();
+        }
+        
+    }
+    
+    /**
+     * Sets the tag table for a given page.
+     * The first string in the array defines tag 5, the second tag 6 etc.
+     */
+    
+    public void setTagTable(int page, String[] tagTable) {
+        // TODO: clear entries in tagTable?
+        
+        for (int i = 0; i < tagTable.length; i++) {
+            if (tagTable[i] != null) {
+                Object idx = new int[]{page, i+5};
+                this.tagTable.put(tagTable[i], idx);
+            }
+        }
+    }
+    
+    /**
+     * Sets the attribute start Table for a given page.
+     * The first string in the array defines attribute
+     * 5, the second attribute 6 etc.
+     *  Please use the
+     *  character '=' (without quote!) as delimiter
+     *  between the attribute name and the (start of the) value
+     */
+    public void setAttrStartTable(int page, String[] attrStartTable) {
+        
+        for (int i = 0; i < attrStartTable.length; i++) {
+            if (attrStartTable[i] != null) {
+                Object idx = new int[] {page, i + 5};
+                this.attrStartTable.put(attrStartTable[i], idx);
+            }
+        }
+    }
+    
+    /**
+     * Sets the attribute value Table for a given page.
+     * The first string in the array defines attribute value 0x85,
+     * the second attribute value 0x86 etc.
+     */
+    public void setAttrValueTable(int page, String[] attrValueTable) {
+        // clear entries in this.table!
+        for (int i = 0; i < attrValueTable.length; i++) {
+            if (attrValueTable[i] != null) {
+                Object idx = new int[]{page, i + 0x085};
+                this.attrValueTable.put(attrValueTable[i], idx);
+            }
+        }
+    }
+}
diff --git a/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java b/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java
new file mode 100644
index 0000000..5ea8496
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java
@@ -0,0 +1,192 @@
+package org.kxml2.wap.syncml;
+
+import org.kxml2.wap.*;
+
+public abstract class SyncML {
+    
+    
+    // SyncML-Common (-//SYNCML//DTD SyncML 1.2//EN and -//SYNCML//DTD MetInf 1.2//EN) support
+    
+    public static WbxmlParser createParser() {
+        WbxmlParser p = new WbxmlParser();
+        p.setTagTable(0, TAG_TABLE_0);
+        p.setTagTable(1, TAG_TABLE_1);
+        return p;
+    }
+
+    public static WbxmlSerializer createSerializer() {
+        WbxmlSerializer s = new WbxmlSerializer();
+        s.setTagTable(0, TAG_TABLE_0);
+        s.setTagTable(1, TAG_TABLE_1);
+        return s;
+    }
+    
+    
+    // SyncML-Common + DMDDF (-//OMA//DTD-DM-DDF 1.2//EN) support
+    
+    public static WbxmlParser createDMParser() {
+        WbxmlParser p = createParser();
+        p.setTagTable(2, TAG_TABLE_2_DM);
+        return p;
+    }
+
+    public static WbxmlSerializer createDMSerializer() {
+        WbxmlSerializer s = createSerializer();
+        s.setTagTable(2, TAG_TABLE_2_DM);
+        return s;
+    }
+
+    // Tables
+    
+    public static final String [] TAG_TABLE_0 = {
+        
+         //  -//SYNCML//DTD SyncML 1.2//EN
+        
+         "Add",            // 0x05 
+         "Alert",          // 0x06 
+         "Archive",        // 0x07 
+         "Atomic",         // 0x08 
+         "Chal",           // 0x09 
+         "Cmd",            // 0x0a 
+         "CmdID",          // 0x0b 
+         "CmdRef",         // 0x0c 
+         "Copy",           // 0x0d 
+         "Cred",           // 0x0e 
+         "Data",           // 0x0f 
+         "Delete",         // 0x10 
+         "Exec",           // 0x11 
+         "Final",          // 0x12 
+         "Get",            // 0x13 
+         "Item",           // 0x14 
+         "Lang",           // 0x15 
+         "LocName",        // 0x16 
+         "LocURI",         // 0x17 
+         "Map",            // 0x18 
+         "MapItem",        // 0x19 
+         "Meta",           // 0x1a 
+         "MsgID",          // 0x1b 
+         "MsgRef",         // 0x1c 
+         "NoResp",         // 0x1d 
+         "NoResults",      // 0x1e 
+         "Put",            // 0x1f 
+         "Replace",        // 0x20 
+         "RespURI",        // 0x21 
+         "Results",        // 0x22 
+         "Search",         // 0x23 
+         "Sequence",       // 0x24 
+         "SessionID",      // 0x25 
+         "SftDel",         // 0x26 
+         "Source",         // 0x27 
+         "SourceRef",      // 0x28 
+         "Status",         // 0x29 
+         "Sync",           // 0x2a 
+         "SyncBody",       // 0x2b 
+         "SyncHdr",        // 0x2c 
+         "SyncML",         // 0x2d 
+         "Target",         // 0x2e 
+         "TargetRef",      // 0x2f 
+         "Reserved for future use",    // 0x30 
+         "VerDTD",         // 0x31 
+         "VerProto",       // 0x32 
+         "NumberOfChanged",// 0x33 
+         "MoreData",       // 0x34 
+         "Field",          // 0x35
+         "Filter",         // 0x36
+         "Record",         // 0x37
+         "FilterType",     // 0x38
+         "SourceParent",   // 0x39
+         "TargetParent",   // 0x3a
+         "Move",           // 0x3b
+         "Correlator"      // 0x3c
+    };  
+    
+    public static final String [] TAG_TABLE_1 = {
+       
+         //  -//SYNCML//DTD MetInf 1.2//EN 
+        
+         "Anchor",         // 0x05 
+         "EMI",            // 0x06 
+         "Format",         // 0x07 
+         "FreeID",         // 0x08 
+         "FreeMem",        // 0x09 
+         "Last",           // 0x0a 
+         "Mark",           // 0x0b 
+         "MaxMsgSize",     // 0x0c 
+         "Mem",            // 0x0d 
+         "MetInf",         // 0x0e 
+         "Next",           // 0x0f 
+         "NextNonce",      // 0x10 
+         "SharedMem",      // 0x11 
+         "Size",           // 0x12 
+         "Type",           // 0x13 
+         "Version",        // 0x14 
+         "MaxObjSize",     // 0x15
+         "FieldLevel"      // 0x16
+         
+    };
+
+    public static final String [] TAG_TABLE_2_DM = {
+        
+        //  -//OMA//DTD-DM-DDF 1.2//EN 
+       
+        "AccessType",         // 0x05 
+        "ACL",                // 0x06 
+        "Add",                // 0x07 
+        "b64",                // 0x08 
+        "bin",                // 0x09 
+        "bool",               // 0x0a 
+        "chr",                // 0x0b 
+        "CaseSense",          // 0x0c 
+        "CIS",                // 0x0d 
+        "Copy",               // 0x0e 
+        "CS",                 // 0x0f 
+        "date",               // 0x10 
+        "DDFName",            // 0x11 
+        "DefaultValue",       // 0x12 
+        "Delete",             // 0x13 
+        "Description",        // 0x14 
+        "DDFFormat",          // 0x15 
+        "DFProperties",       // 0x16 
+        "DFTitle",            // 0x17 
+        "DFType",             // 0x18 
+        "Dynamic",            // 0x19 
+        "Exec",               // 0x1a 
+        "float",              // 0x1b 
+        "Format",             // 0x1c 
+        "Get",                // 0x1d 
+        "int",                // 0x1e 
+        "Man",                // 0x1f 
+        "MgmtTree",           // 0x20 
+        "MIME",               // 0x21 
+        "Mod",                // 0x22 
+        "Name",               // 0x23 
+        "Node",               // 0x24 
+        "node",               // 0x25 
+        "NodeName",           // 0x26 
+        "null",               // 0x27 
+        "Occurence",          // 0x28 
+        "One",                // 0x29 
+        "OneOrMore",          // 0x2a 
+        "OneOrN",             // 0x2b 
+        "Path",               // 0x2c 
+        "Permanent",          // 0x2d 
+        "Replace",            // 0x2e 
+        "RTProperties",       // 0x2f 
+        "Scope",              // 0x30 
+        "Size",               // 0x31 
+        "time",               // 0x32 
+        "Title",              // 0x33 
+        "TStamp",             // 0x34 
+        "Type",               // 0x35
+        "Value",              // 0x36
+        "VerDTD",             // 0x37
+        "VerNo",              // 0x38
+        "xml",                // 0x39
+        "ZeroOrMore",         // 0x3a
+        "ZeroOrN",            // 0x3b
+        "ZeroOrOne"           // 0x3c
+        
+   };
+    
+}
+
diff --git a/xml/src/main/java/org/kxml2/wap/wml/Wml.java b/xml/src/main/java/org/kxml2/wap/wml/Wml.java
new file mode 100644
index 0000000..7e925d8
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/wml/Wml.java
@@ -0,0 +1,233 @@
+package org.kxml2.wap.wml;
+
+import org.kxml2.wap.*;
+
+
+/** This class contains the wml coding tables for elements 
+ *  and attributes needed by the WmlParser. 
+ */
+
+
+public abstract class Wml {
+
+    /** Creates a WbxmlParser with the WML code pages set */
+
+    public static WbxmlParser createParser() {
+        WbxmlParser p = new WbxmlParser();
+        p.setTagTable(0, TAG_TABLE);
+        p.setAttrStartTable(0, ATTR_START_TABLE);
+        p.setAttrValueTable(0, ATTR_VALUE_TABLE);
+        return p;
+    }
+
+    public static WbxmlSerializer createSerializer() {
+        WbxmlSerializer s = new WbxmlSerializer();
+        s.setTagTable(0, TAG_TABLE);
+        s.setAttrStartTable(0, ATTR_START_TABLE);
+        s.setAttrValueTable(0, ATTR_VALUE_TABLE);
+        return s;
+    }
+
+
+    public static final String [] TAG_TABLE = {
+
+    null, // 05
+    null, // 06
+    null, // 07
+    null, // 08
+    null, // 09
+    null, // 0A
+    null, // 0B
+    null, // 0C
+    null, // 0D
+    null, // 0E
+    null, // 0F
+
+    null, // 10
+    null, // 11
+    null, // 12
+    null, // 13
+    null, // 14
+    null, // 15
+    null, // 16
+    null, // 17
+    null, // 18
+    null, // 19
+    null, // 1A
+    null, // 1B
+    "a",  // 1C
+    "td", // 1D
+    "tr", // 1E
+    "table", // 1F
+
+    "p", // 20
+    "postfield", // 21
+    "anchor", // 22
+    "access", // 23
+    "b",  // 24
+    "big", // 25
+    "br", // 26
+    "card", // 27
+    "do", // 28
+    "em", // 29
+    "fieldset", // 2A
+    "go", // 2B
+    "head", // 2C
+    "i", // 2D
+    "img", // 2E
+    "input", // 2F
+
+    "meta", // 30
+    "noop", // 31
+    "prev", // 32
+    "onevent", // 33
+    "optgroup", // 34
+    "option", // 35
+    "refresh", // 36
+    "select", // 37
+    "small", // 38
+    "strong", // 39
+    null, // 3A
+    "template", // 3B
+    "timer", // 3C
+    "u", // 3D
+    "setvar", // 3E
+    "wml", // 3F
+    };
+
+    
+    public static final String [] ATTR_START_TABLE = { 
+    "accept-charset", // 05
+    "align=bottom", // 06
+    "align=center", // 07
+    "align=left", // 08
+    "align=middle", // 09
+    "align=right", // 0A
+    "align=top", // 0B
+    "alt", // 0C
+    "content", // 0D
+    null, // 0E
+    "domain", // 0F
+    
+    "emptyok=false", // 10
+    "emptyok=true", // 11
+    "format", // 12
+    "height", // 13
+    "hspace", // 14
+    "ivalue", // 15
+    "iname", // 16
+    null, // 17
+    "label", // 18
+    "localsrc", // 19
+    "maxlength", // 1A
+    "method=get", // 1B
+    "method=post", // 1C
+    "mode=nowrap", // 1D
+    "mode=wrap", // 1E
+    "multiple=false", // 1F
+
+    "multiple=true", // 20
+    "name", // 21
+    "newcontext=false", // 22
+    "newcontext=true", // 23
+    "onpick", // 24
+    "onenterbackward", // 25
+    "onenterforward", // 26
+    "ontimer", // 27
+    "optimal=false", // 28
+    "optimal=true", // 29
+    "path", // 2A
+    null, // 2B
+    null, // 2C
+    null, // 2D
+    "scheme", // 2E
+    "sendreferer=false", // 2F
+    
+    "sendreferer=true", // 30
+    "size", // 31
+    "src", // 32
+    "ordered=true", // 33
+    "ordered=false", // 34
+    "tabindex", // 35
+    "title", // 36
+    "type", // 37
+    "type=accept", // 38
+    "type=delete", // 39
+    "type=help", // 3A
+    "type=password", // 3B
+    "type=onpick", // 3C
+    "type=onenterbackward", // 3D
+    "type=onenterforward", // 3E
+    "type=ontimer", // 3F
+
+    null, // 40
+    null, // 41
+    null, // 42
+    null, // 43
+    null, // 44
+    "type=options", // 45
+    "type=prev", // 46
+    "type=reset", // 47
+    "type=text", // 48
+    "type=vnd.", // 49
+    "href", // 4A
+    "href=http://", // 4B
+    "href=https://", // 4C
+    "value", // 4D
+    "vspace", // 4E
+    "width", // 4F
+
+    "xml:lang", // 50
+    null, // 51
+    "align", // 52
+    "columns", // 53
+    "class", // 54
+    "id", // 55
+    "forua=false", // 56
+    "forua=true", // 57
+    "src=http://", // 58
+    "src=https://", // 59
+    "http-equiv", // 5A
+    "http-equiv=Content-Type", // 5B
+    "content=application/vnd.wap.wmlc;charset=", // 5C
+    "http-equiv=Expires", // 5D
+    null, // 5E
+    null, // 5F
+    };
+
+
+    public static final String [] ATTR_VALUE_TABLE = {
+    ".com/", // 85
+    ".edu/", // 86
+    ".net/", // 87
+    ".org/", // 88
+    "accept", // 89
+    "bottom", // 8A
+    "clear", // 8B
+    "delete", // 8C
+    "help", // 8D
+    "http://", // 8E
+    "http://www.", // 8F
+    
+    "https://", // 90
+    "https://www.", // 91
+    null, // 92
+    "middle", // 93
+    "nowrap", // 94
+    "onpick", // 95
+    "onenterbackward", // 96
+    "onenterforward", // 97
+    "ontimer", // 98
+    "options", // 99
+    "password", // 9A
+    "reset", // 9B
+    null, // 9C
+    "text", // 9D
+    "top", // 9E
+    "unknown", // 9F
+    
+    "wrap", // A0
+    "www.", // A1
+    };
+}    
+
diff --git a/xml/src/main/java/org/kxml2/wap/wv/WV.java b/xml/src/main/java/org/kxml2/wap/wv/WV.java
new file mode 100644
index 0000000..e2afbfb
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/wv/WV.java
@@ -0,0 +1,593 @@
+package org.kxml2.wap.wv;
+
+import java.io.IOException;
+
+import org.kxml2.wap.*;
+
+/*
+
+ * WV.java
+
+ *
+
+ * Created on 25 September 2003, 10:40
+
+ */
+
+
+
+
+
+   /** 
+     *    Wireless Village CSP 1.1 ("OMA-WV-CSP-V1_1-20021001-A.pdf")
+     *    Wireless Village CSP 1.2 ("OMA-IMPS-WV-CSP_WBXML-v1_2-20030221-C.PDF")
+     *    There are some bugs in the 1.2 spec but this is Ok. 1.2 is candidate  
+ *
+
+ * @author  Bogdan Onoiu
+
+ */
+
+public abstract class WV {
+
+    
+
+    
+    
+    public static WbxmlParser createParser () throws IOException {
+        
+        WbxmlParser parser = new WbxmlParser();
+
+        parser.setTagTable (0, WV.tagTablePage0);
+        parser.setTagTable (1, WV.tagTablePage1);
+        parser.setTagTable (2, WV.tagTablePage2);
+        parser.setTagTable (3, WV.tagTablePage3);
+        parser.setTagTable (4, WV.tagTablePage4);
+        parser.setTagTable (5, WV.tagTablePage5);
+        parser.setTagTable (6, WV.tagTablePage6);
+        parser.setTagTable (7, WV.tagTablePage7);
+        parser.setTagTable (8, WV.tagTablePage8);
+        parser.setTagTable (9, WV.tagTablePage9);
+        parser.setTagTable (10, WV.tagTablePageA);
+
+        parser.setAttrStartTable (0, WV.attrStartTable);
+        
+        parser.setAttrValueTable (0, WV.attrValueTable);
+
+        return parser;
+    }
+    
+   
+    
+    public static final String [] tagTablePage0 = {
+        /* Common ... continue on Page 0x09 */
+        "Acceptance",     //0x00, 0x05
+        "AddList",        //0x00, 0x06
+        "AddNickList",    //0x00, 0x07
+        "SName",          //0x00, 0x08
+        "WV-CSP-Message", //0x00, 0x09
+        "ClientID",       //0x00, 0x0A
+        "Code",           //0x00, 0x0B
+        "ContactList",    //0x00, 0x0C
+        "ContentData",    //0x00, 0x0D
+        "ContentEncoding",//0x00, 0x0E
+        "ContentSize",    //0x00, 0x0F
+        "ContentType",    //0x00, 0x10
+        "DateTime",       //0x00, 0x11
+        "Description",    //0x00, 0x12
+        "DetailedResult", //0x00, 0x13
+        "EntityList",     //0x00, 0x14
+        "Group",          //0x00, 0x15
+        "GroupID",        //0x00, 0x16
+        "GroupList",      //0x00, 0x17
+        "InUse",          //0x00, 0x18
+        "Logo",           //0x00, 0x19
+        "MessageCount",   //0x00, 0x1A
+        "MessageID",      //0x00, 0x1B
+        "MessageURI",     //0x00, 0x1C
+        "MSISDN",         //0x00, 0x1D
+        "Name",           //0x00, 0x1E
+        "NickList",       //0x00, 0x1F
+        "NickName",       //0x00, 0x20
+        "Poll",           //0x00, 0x21
+        "Presence",       //0x00, 0x22
+        "PresenceSubList",//0x00, 0x23
+        "PresenceValue",  //0x00, 0x24
+        "Property",       //0x00, 0x25
+        "Qualifier",      //0x00, 0x26
+        "Recipient",      //0x00, 0x27
+        "RemoveList",     //0x00, 0x28
+        "RemoveNickList", //0x00, 0x29
+        "Result",         //0x00, 0x2A
+        "ScreenName",     //0x00, 0x2B
+        "Sender",         //0x00, 0x2C
+        "Session",        //0x00, 0x2D
+        "SessionDescriptor",//0x00, 0x2E
+        "SessionID",      //0x00, 0x2F
+        "SessionType",    //0x00, 0x30
+        "Status",         //0x00, 0x31
+        "Transaction",    //0x00, 0x32
+        "TransactionContent",//0x00, 0x33
+        "TransactionDescriptor",//0x00, 0x34
+        "TransactionID",  //0x00, 0x35
+        "TransactionMode",//0x00, 0x36
+        "URL",            //0x00, 0x37
+        "URLList",        //0x00, 0x38
+        "User",           //0x00, 0x39
+        "UserID",         //0x00, 0x3A
+        "UserList",       //0x00, 0x3B
+        "Validity",       //0x00, 0x3C
+        "Value",          //0x00, 0x3D
+    };
+    
+    public static final String [] tagTablePage1 = {
+        /* Access ... continue on Page 0x0A */
+        "AllFunctions",             //  0x01, 0x05
+        "AllFunctionsRequest",      //  0x01, 0x06
+        "CancelInvite-Request",     //  0x01, 0x07
+        "CancelInviteUser-Request", //  0x01, 0x08
+        "Capability",               //  0x01, 0x09
+        "CapabilityList",           //  0x01, 0x0A
+        "CapabilityRequest",        //  0x01, 0x0B
+        "ClientCapability-Request", //  0x01, 0x0C
+        "ClientCapability-Response",//  0x01, 0x0D
+        "DigestBytes",          //  0x01, 0x0E
+        "DigestSchema",         //  0x01, 0x0F
+        "Disconnect",           //  0x01, 0x10
+        "Functions",            //  0x01, 0x11
+        "GetSPInfo-Request",    //  0x01, 0x12
+        "GetSPInfo-Response",   //  0x01, 0x13
+        "InviteID",             //  0x01, 0x14
+        "InviteNote",           //  0x01, 0x15
+        "Invite-Request",       //  0x01, 0x16
+        "Invite-Response",      //  0x01, 0x17
+        "InviteType",           //  0x01, 0x18
+        "InviteUser-Request",   //  0x01, 0x19
+        "InviteUser-Response",  //  0x01, 0x1A
+        "KeepAlive-Request",    //  0x01, 0x1B
+        "KeepAliveTime",        //  0x01, 0x1C
+        "Login-Request",        //  0x01, 0x1D
+        "Login-Response",       //  0x01, 0x1E
+        "Logout-Request",       //  0x01, 0x1F
+        "Nonce",                //  0x01, 0x20
+        "Password",             //  0x01, 0x21
+        "Polling-Request",      //  0x01, 0x22
+        "ResponseNote",         //  0x01, 0x23
+        "SearchElement",        //  0x01, 0x24
+        "SearchFindings",       //  0x01, 0x25
+        "SearchID",             //  0x01, 0x26
+        "SearchIndex",          //  0x01, 0x27
+        "SearchLimit",          //  0x01, 0x28
+        "KeepAlive-Response",   //  0x01, 0x29
+        "SearchPairList",       //  0x01, 0x2A
+        "Search-Request",       //  0x01, 0x2B
+        "Search-Response",      //  0x01, 0x2C
+        "SearchResult",         //  0x01, 0x2D
+        "Service-Request",      //  0x01, 0x2E
+        "Service-Response",     //  0x01, 0x2F
+        "SessionCookie",        //  0x01, 0x30
+        "StopSearch-Request",   //  0x01, 0x31
+        "TimeToLive",           //  0x01, 0x32
+        "SearchString",         //  0x01, 0x33
+        "CompletionFlag",       //  0x01, 0x34
+        null,                   //  0x01, 0x35
+        "ReceiveList",          //  0x01, 0x36 /* WV 1.2 */
+        "VerifyID-Request",     //  0x01, 0x37 /* WV 1.2 */
+        "Extended-Request",     //  0x01, 0x38 /* WV 1.2 */
+        "Extended-Response",    //  0x01, 0x39 /* WV 1.2 */
+        "AgreedCapabilityList", //  0x01, 0x3A /* WV 1.2 */
+        "Extended-Data",        //  0x01, 0x3B /* WV 1.2 */
+        "OtherServer",          //  0x01, 0x3C /* WV 1.2 */
+        "PresenceAttributeNSName",//0x01, 0x3D /* WV 1.2 */
+        "SessionNSName",        //  0x01, 0x3E /* WV 1.2 */
+        "TransactionNSName",    //  0x01, 0x3F /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage2 = {
+        /* Service ... continue on Page 0x08 */
+        "ADDGM",        //  0x02, 0x05
+        "AttListFunc",  //  0x02, 0x06
+        "BLENT",        //  0x02, 0x07
+        "CAAUT",        //  0x02, 0x08
+        "CAINV",        //  0x02, 0x09
+        "CALI",         //  0x02, 0x0A
+        "CCLI",         //  0x02, 0x0B
+        "ContListFunc", //  0x02, 0x0C
+        "CREAG",        //  0x02, 0x0D
+        "DALI",         //  0x02, 0x0E
+        "DCLI",         //  0x02, 0x0F
+        "DELGR",        //  0x02, 0x10
+        "FundamentalFeat",//0x02, 0x11
+        "FWMSG",        //  0x02, 0x12
+        "GALS",         //  0x02, 0x13
+        "GCLI",         //  0x02, 0x14
+        "GETGM",        //  0x02, 0x15
+        "GETGP",        //  0x02, 0x16
+        "GETLM",        //  0x02, 0x17
+        "GETM",         //  0x02, 0x18
+        "GETPR",        //  0x02, 0x19
+        "GETSPI",       //  0x02, 0x1A
+        "GETWL",        //  0x02, 0x1B
+        "GLBLU",        //  0x02, 0x1C
+        "GRCHN",        //  0x02, 0x1D
+        "GroupAuthFunc",//  0x02, 0x1E
+        "GroupFeat",    //  0x02, 0x1F
+        "GroupMgmtFunc",//  0x02, 0x20
+        "GroupUseFunc", //  0x02, 0x21
+        "IMAuthFunc",   //  0x02, 0x22
+        "IMFeat",       //  0x02, 0x23
+        "IMReceiveFunc",//  0x02, 0x24
+        "IMSendFunc",   //  0x02, 0x25
+        "INVIT",        //  0x02, 0x26
+        "InviteFunc",   //  0x02, 0x27
+        "MBRAC",        //  0x02, 0x28
+        "MCLS",         //  0x02, 0x29
+        "MDELIV",       //  0x02, 0x2A
+        "NEWM",         //  0x02, 0x2B
+        "NOTIF",        //  0x02, 0x2C
+        "PresenceAuthFunc",//0x02, 0x2D
+        "PresenceDeliverFunc",//0x02, 0x2E
+        "PresenceFeat", //  0x02, 0x2F
+        "REACT",        //  0x02, 0x30
+        "REJCM",        //  0x02, 0x31
+        "REJEC",        //  0x02, 0x32
+        "RMVGM",        //  0x02, 0x33
+        "SearchFunc",   //  0x02, 0x34
+        "ServiceFunc",  //  0x02, 0x35
+        "SETD",         //  0x02, 0x36
+        "SETGP",        //  0x02, 0x37
+        "SRCH",         //  0x02, 0x38
+        "STSRC",        //  0x02, 0x39
+        "SUBGCN",       //  0x02, 0x3A
+        "UPDPR",        //  0x02, 0x3B
+        "WVCSPFeat",    //  0x02, 0x3C
+        "MF",           //  0x02, 0x3D /* WV 1.2 */
+        "MG",           //  0x02, 0x3E /* WV 1.2 */
+        "MM"            //  0x02, 0x3F /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage3 = {
+        /* Client Capability */
+        "AcceptedCharset",          //  0x03, 0x05
+        "AcceptedContentLength",    //  0x03, 0x06
+        "AcceptedContentType",      //  0x03, 0x07
+        "AcceptedTransferEncoding", //  0x03, 0x08
+        "AnyContent",               //  0x03, 0x09
+        "DefaultLanguage",          //  0x03, 0x0A
+        "InitialDeliveryMethod",    //  0x03, 0x0B
+        "MultiTrans",               //  0x03, 0x0C
+        "ParserSize",               //  0x03, 0x0D
+        "ServerPollMin",            //  0x03, 0x0E
+        "SupportedBearer",          //  0x03, 0x0F
+        "SupportedCIRMethod",       //  0x03, 0x10
+        "TCPAddress",               //  0x03, 0x11
+        "TCPPort",                  //  0x03, 0x12
+        "UDPPort"                  //  0x03, 0x13
+    };
+    
+    public static final String [] tagTablePage4 = {
+        /* Presence Primitive */
+        "CancelAuth-Request",           //  0x04, 0x05
+        "ContactListProperties",        //  0x04, 0x06
+        "CreateAttributeList-Request",  //  0x04, 0x07
+        "CreateList-Request",           //  0x04, 0x08
+        "DefaultAttributeList",         //  0x04, 0x09
+        "DefaultContactList",           //  0x04, 0x0A
+        "DefaultList",                  //  0x04, 0x0B
+        "DeleteAttributeList-Request",  //  0x04, 0x0C
+        "DeleteList-Request",           //  0x04, 0x0D
+        "GetAttributeList-Request",     //  0x04, 0x0E
+        "GetAttributeList-Response",    //  0x04, 0x0F
+        "GetList-Request",              //  0x04, 0x10
+        "GetList-Response",             //  0x04, 0x11
+        "GetPresence-Request",          //  0x04, 0x12
+        "GetPresence-Response",         //  0x04, 0x13
+        "GetWatcherList-Request",       //  0x04, 0x14
+        "GetWatcherList-Response",      //  0x04, 0x15
+        "ListManage-Request",           //  0x04, 0x16
+        "ListManage-Response",          //  0x04, 0x17
+        "UnsubscribePresence-Request",  //  0x04, 0x18
+        "PresenceAuth-Request",         //  0x04, 0x19
+        "PresenceAuth-User",            //  0x04, 0x1A
+        "PresenceNotification-Request", //  0x04, 0x1B
+        "UpdatePresence-Request",       //  0x04, 0x1C
+        "SubscribePresence-Request",    //  0x04, 0x1D
+        "Auto-Subscribe",               //  0x04, 0x1E /* WV 1.2 */
+        "GetReactiveAuthStatus-Request",//  0x04, 0x1F /* WV 1.2 */
+        "GetReactiveAuthStatus-Response",// 0x04, 0x20 /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage5 = {
+        /* Presence Attribute */
+        "Accuracy",         //  0x05, 0x05
+        "Address",          //  0x05, 0x06
+        "AddrPref",         //  0x05, 0x07
+        "Alias",            //  0x05, 0x08
+        "Altitude",         //  0x05, 0x09
+        "Building",         //  0x05, 0x0A
+        "Caddr",            //  0x05, 0x0B
+        "City",             //  0x05, 0x0C
+        "ClientInfo",       //  0x05, 0x0D
+        "ClientProducer",   //  0x05, 0x0E
+        "ClientType",       //  0x05, 0x0F
+        "ClientVersion",    //  0x05, 0x10
+        "CommC",            //  0x05, 0x11
+        "CommCap",          //  0x05, 0x12
+        "ContactInfo",      //  0x05, 0x13
+        "ContainedvCard",   //  0x05, 0x14
+        "Country",          //  0x05, 0x15
+        "Crossing1",        //  0x05, 0x16
+        "Crossing2",        //  0x05, 0x17
+        "DevManufacturer",  //  0x05, 0x18
+        "DirectContent",    //  0x05, 0x19
+        "FreeTextLocation", //  0x05, 0x1A
+        "GeoLocation",      //  0x05, 0x1B
+        "Language",         //  0x05, 0x1C
+        "Latitude",         //  0x05, 0x1D
+        "Longitude",        //  0x05, 0x1E
+        "Model",            //  0x05, 0x1F
+        "NamedArea",        //  0x05, 0x20
+        "OnlineStatus",     //  0x05, 0x21
+        "PLMN",             //  0x05, 0x22
+        "PrefC",            //  0x05, 0x23
+        "PreferredContacts",//  0x05, 0x24
+        "PreferredLanguage",//  0x05, 0x25
+        "PreferredContent", //  0x05, 0x26
+        "PreferredvCard",   //  0x05, 0x27
+        "Registration",     //  0x05, 0x28
+        "StatusContent",    //  0x05, 0x29
+        "StatusMood",       //  0x05, 0x2A
+        "StatusText",       //  0x05, 0x2B
+        "Street",           //  0x05, 0x2C
+        "TimeZone",         //  0x05, 0x2D
+        "UserAvailability", //  0x05, 0x2E
+        "Cap",              //  0x05, 0x2F
+        "Cname",            //  0x05, 0x30
+        "Contact",          //  0x05, 0x31
+        "Cpriority",        //  0x05, 0x32
+        "Cstatus",          //  0x05, 0x33
+        "Note",             //  0x05, 0x34 /* WV 1.2 */
+        "Zone",             //  0x05, 0x35
+        null,
+        "Inf_link",         //  0x05, 0x37 /* WV 1.2 */
+        "InfoLink",         //  0x05, 0x38 /* WV 1.2 */
+        "Link",             //  0x05, 0x39 /* WV 1.2 */
+        "Text",             //  0x05, 0x3A /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage6 = {
+        /* Messaging */
+        "BlockList",                //  0x06, 0x05
+//      "BlockUser-Request",        //  0x06, 0x06  //This is a bug in the spec
+        "BlockEntity-Request",        //  0x06, 0x06  
+        "DeliveryMethod",           //  0x06, 0x07
+        "DeliveryReport",           //  0x06, 0x08
+        "DeliveryReport-Request",   //  0x06, 0x09
+        "ForwardMessage-Request",   //  0x06, 0x0A
+        "GetBlockedList-Request",   //  0x06, 0x0B
+        "GetBlockedList-Response",  //  0x06, 0x0C
+        "GetMessageList-Request",   //  0x06, 0x0D
+        "GetMessageList-Response",  //  0x06, 0x0E
+        "GetMessage-Request",       //  0x06, 0x0F
+        "GetMessage-Response",      //  0x06, 0x10
+        "GrantList",                //  0x06, 0x11
+        "MessageDelivered",         //  0x06, 0x12
+        "MessageInfo",              //  0x06, 0x13
+        "MessageNotification",      //  0x06, 0x14
+        "NewMessage",               //  0x06, 0x15
+        "RejectMessage-Request",    //  0x06, 0x16
+        "SendMessage-Request",      //  0x06, 0x17
+        "SendMessage-Response",     //  0x06, 0x18
+        "SetDeliveryMethod-Request",//  0x06, 0x19
+        "DeliveryTime",             //  0x06, 0x1A
+    };
+    
+    public static final String [] tagTablePage7 = {
+        /* Group */
+        "AddGroupMembers-Request",  //  0x07, 0x05
+        "Admin",                    //  0x07, 0x06
+        "CreateGroup-Request",      //  0x07, 0x07
+        "DeleteGroup-Request",      //  0x07, 0x08
+        "GetGroupMembers-Request",  //  0x07, 0x09
+        "GetGroupMembers-Response", //  0x07, 0x0A
+        "GetGroupProps-Request",    //  0x07, 0x0B
+        "GetGroupProps-Response",   //  0x07, 0x0C
+        "GroupChangeNotice",        //  0x07, 0x0D
+        "GroupProperties",          //  0x07, 0x0E
+        "Joined",                   //  0x07, 0x0F
+        "JoinedRequest",            //  0x07, 0x10
+        "JoinGroup-Request",        //  0x07, 0x11
+        "JoinGroup-Response",       //  0x07, 0x12
+        "LeaveGroup-Request",       //  0x07, 0x13
+        "LeaveGroup-Response",      //  0x07, 0x14
+        "Left",                     //  0x07, 0x15
+        "MemberAccess-Request",     //  0x07, 0x16
+        "Mod",                      //  0x07, 0x17
+        "OwnProperties",            //  0x07, 0x18
+        "RejectList-Request",       //  0x07, 0x19
+        "RejectList-Response",      //  0x07, 0x1A
+        "RemoveGroupMembers-Request",// 0x07, 0x1B
+        "SetGroupProps-Request",    //  0x07, 0x1C
+        "SubscribeGroupNotice-Request", //  0x07, 0x1D
+        "SubscribeGroupNotice-Response",//  0x07, 0x1E
+        "Users",                    //  0x07, 0x1F
+        "WelcomeNote",              //  0x07, 0x20
+        "JoinGroup",                //  0x07, 0x21
+        "SubscribeNotification",    //  0x07, 0x22
+        "SubscribeType",            //  0x07, 0x23
+        "GetJoinedUsers-Request",   //  0x07, 0x24 /* WV 1.2 */
+        "GetJoinedUsers-Response",  //  0x07, 0x25 /* WV 1.2 */
+        "AdminMapList",             //  0x07, 0x26 /* WV 1.2 */
+        "AdminMapping",             //  0x07, 0x27 /* WV 1.2 */
+        "Mapping",                  //  0x07, 0x28 /* WV 1.2 */
+        "ModMapping",               //  0x07, 0x29 /* WV 1.2 */
+        "UserMapList",              //  0x07, 0x2A /* WV 1.2 */
+        "UserMapping",              //  0x07, 0x2B /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage8 = {
+        /* Service ... continued */
+        "MP",                       //  0x08, 0x05 /* WV 1.2 */
+        "GETAUT",                   //  0x08, 0x06 /* WV 1.2 */
+        "GETJU",                    //  0x08, 0x07 /* WV 1.2 */
+        "VRID",                     //  0x08, 0x08 /* WV 1.2 */
+        "VerifyIDFunc",             //  0x08, 0x09 /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePage9 = {
+        /* Common ... continued */
+        "CIR",                      //  0x09, 0x05 /* WV 1.2 */
+        "Domain",                   //  0x09, 0x06 /* WV 1.2 */
+        "ExtBlock",                 //  0x09, 0x07 /* WV 1.2 */
+        "HistoryPeriod",            //  0x09, 0x08 /* WV 1.2 */
+        "IDList",                   //  0x09, 0x09 /* WV 1.2 */
+        "MaxWatcherList",           //  0x09, 0x0A /* WV 1.2 */
+        "ReactiveAuthState",        //  0x09, 0x0B /* WV 1.2 */
+        "ReactiveAuthStatus",       //  0x09, 0x0C /* WV 1.2 */
+        "ReactiveAuthStatusList",   //  0x09, 0x0D /* WV 1.2 */
+        "Watcher",                  //  0x09, 0x0E /* WV 1.2 */
+        "WatcherStatus"             //  0x09, 0x0F /* WV 1.2 */
+    };
+    
+    public static final String [] tagTablePageA = {
+        /* Access ... continued */
+        "WV-CSP-NSDiscovery-Request",  //0x0A, 0x05 /* WV 1.2 */
+        "WV-CSP-NSDiscovery-Response", //0x0A, 0x06 /* WV 1.2 */
+        "VersionList"                  //0x0A, 0x07 /* WV 1.2 */
+    };
+    
+    public static final String [] attrStartTable = {
+        "xmlns=http://www.wireless-village.org/CSP",//  0x00, 0x05
+        "xmlns=http://www.wireless-village.org/PA", //  0x00, 0x06
+        "xmlns=http://www.wireless-village.org/TRC",//  0x00, 0x07
+        "xmlns=http://www.openmobilealliance.org/DTD/WV-CSP",   //  0x00, 0x08
+        "xmlns=http://www.openmobilealliance.org/DTD/WV-PA",    //  0x00, 0x09
+        "xmlns=http://www.openmobilealliance.org/DTD/WV-TRC",   //  0x00, 0x0A
+    };
+    
+    public static final String [] attrValueTable = {
+      
+        "AccessType",                           // 0x00 /* Common value token */
+        "ActiveUsers",                          // 0x01 /* Common value token */
+        "Admin",                                // 0x02 /* Common value token */
+        "application/",                         // 0x03 /* Common value token */
+        "application/vnd.wap.mms-message",      // 0x04 /* Common value token */
+        "application/x-sms",                    // 0x05 /* Common value token */
+        "AutoJoin",                             // 0x06 /* Common value token */
+        "BASE64",                               // 0x07 /* Common value token */
+        "Closed",                               // 0x08 /* Common value token */
+        "Default",                              // 0x09 /* Common value token */
+        "DisplayName",                          // 0x0a /* Common value token */
+        "F",                                    // 0x0b /* Common value token */
+        "G",                                    // 0x0c /* Common value token */
+        "GR",                                   // 0x0d /* Common value token */
+        "http://",                              // 0x0e /* Common value token */
+        "https://",                             // 0x0f /* Common value token */
+        "image/",                               // 0x10 /* Common value token */
+        "Inband",                               // 0x11 /* Common value token */
+        "IM",                                   // 0x12 /* Common value token */
+        "MaxActiveUsers",                       // 0x13 /* Common value token */
+        "Mod",                                  // 0x14 /* Common value token */
+        "Name",                                 // 0x15 /* Common value token */
+        "None",                                 // 0x16 /* Common value token */
+        "N",                                    // 0x17 /* Common value token */
+        "Open",                                 // 0x18 /* Common value token */
+        "Outband",                              // 0x19 /* Common value token */
+        "PR",                                   // 0x1a /* Common value token */
+        "Private",                              // 0x1b /* Common value token */
+        "PrivateMessaging",                     // 0x1c /* Common value token */
+        "PrivilegeLevel",                       // 0x1d /* Common value token */
+        "Public",                               // 0x1e /* Common value token */
+        "P",                                    // 0x1f /* Common value token */
+        "Request",                              // 0x20 /* Common value token */
+        "Response",                             // 0x21 /* Common value token */
+        "Restricted",                           // 0x22 /* Common value token */
+        "ScreenName",                           // 0x23 /* Common value token */
+        "Searchable",                           // 0x24 /* Common value token */
+        "S",                                    // 0x25 /* Common value token */
+        "SC",                                   // 0x26 /* Common value token */
+        "text/",                                // 0x27 /* Common value token */
+        "text/plain",                           // 0x28 /* Common value token */
+        "text/x-vCalendar",                     // 0x29 /* Common value token */
+        "text/x-vCard",                         // 0x2a /* Common value token */
+        "Topic",                                // 0x2b /* Common value token */
+        "T",                                    // 0x2c /* Common value token */
+        "Type",                                 // 0x2d /* Common value token */
+        "U",                                    // 0x2e /* Common value token */
+        "US",                                   // 0x2f /* Common value token */
+        "www.wireless-village.org",             // 0x30 /* Common value token */
+        "AutoDelete",                           // 0x31 /* Common value token */ /* WV 1.2 */
+        "GM",                                   // 0x32 /* Common value token */ /* WV 1.2 */
+        "Validity",                             // 0x33 /* Common value token */ /* WV 1.2 */
+        "ShowID",                               // 0x34 /* Common value token */ /* WV 1.2 */
+        "GRANTED",                              // 0x35 /* Common value token */ /* WV 1.2 */
+        "PENDING",                              // 0x36 /* Common value token */ /* WV 1.2 */
+        null,                                   // 0x37
+        null,                                   // 0x38
+        null,                                   // 0x39
+        null,                                   // 0x3a
+        null,                                   // 0x3b
+        null,                                   // 0x3c
+        "GROUP_ID",                             // 0x3d /* Access value token */
+        "GROUP_NAME",                           // 0x3e /* Access value token */
+        "GROUP_TOPIC",                          // 0x3f /* Access value token */
+        "GROUP_USER_ID_JOINED",                 // 0x40 /* Access value token */
+        "GROUP_USER_ID_OWNER",                  // 0x41 /* Access value token */
+        "HTTP",                                 // 0x42 /* Access value token */
+        "SMS",                                  // 0x43 /* Access value token */
+        "STCP",                                 // 0x44 /* Access value token */
+        "SUDP",                                 // 0x45 /* Access value token */
+        "USER_ALIAS",                           // 0x46 /* Access value token */
+        "USER_EMAIL_ADDRESS",                   // 0x47 /* Access value token */
+        "USER_FIRST_NAME",                      // 0x48 /* Access value token */
+        "USER_ID",                              // 0x49 /* Access value token */
+        "USER_LAST_NAME",                       // 0x4a /* Access value token */
+        "USER_MOBILE_NUMBER",                   // 0x4b /* Access value token */
+        "USER_ONLINE_STATUS",                   // 0x4c /* Access value token */
+        "WAPSMS",                               // 0x4d /* Access value token */
+        "WAPUDP",                               // 0x4e /* Access value token */
+        "WSP",                                  // 0x4f /* Access value token */
+        "GROUP_USER_ID_AUTOJOIN",               // 0x50 /* Access value token */ /* WV 1.2 */
+        null,                                   // 0x51
+        null,                                   // 0x52
+        null,                                   // 0x53
+        null,                                   // 0x54
+        null,                                   // 0x55
+        null,                                   // 0x56
+        null,                                   // 0x57
+        null,                                   // 0x58
+        null,                                   // 0x59
+        null,                                   // 0x5a
+        "ANGRY",                                // 0x5b /* Presence value token */
+        "ANXIOUS",                              // 0x5c /* Presence value token */
+        "ASHAMED",                              // 0x5d /* Presence value token */
+        "AUDIO_CALL",                           // 0x5e /* Presence value token */
+        "AVAILABLE",                            // 0x5f /* Presence value token */
+        "BORED",                                // 0x60 /* Presence value token */
+        "CALL",                                 // 0x61 /* Presence value token */
+        "CLI",                                  // 0x62 /* Presence value token */
+        "COMPUTER",                             // 0x63 /* Presence value token */
+        "DISCREET",                             // 0x64 /* Presence value token */
+        "EMAIL",                                // 0x65 /* Presence value token */
+        "EXCITED",                              // 0x66 /* Presence value token */
+        "HAPPY",                                // 0x67 /* Presence value token */
+        "IM",                                   // 0x68 /* Presence value token */
+        "IM_OFFLINE",                           // 0x69 /* Presence value token */
+        "IM_ONLINE",                            // 0x6a /* Presence value token */
+        "IN_LOVE",                              // 0x6b /* Presence value token */
+        "INVINCIBLE",                           // 0x6c /* Presence value token */
+        "JEALOUS",                              // 0x6d /* Presence value token */
+        "MMS",                                  // 0x6e /* Presence value token */
+        "MOBILE_PHONE",                         // 0x6f /* Presence value token */
+        "NOT_AVAILABLE",                        // 0x70 /* Presence value token */
+        "OTHER",                                // 0x71 /* Presence value token */
+        "PDA",                                  // 0x72 /* Presence value token */
+        "SAD",                                  // 0x73 /* Presence value token */
+        "SLEEPY",                               // 0x74 /* Presence value token */
+        "SMS",                                  // 0x75 /* Presence value token */
+        "VIDEO_CALL",                           // 0x76 /* Presence value token */
+        "VIDEO_STREAM",                         // 0x77 /* Presence value token */
+    };
+    
+    
+}
diff --git a/xml/src/main/java/org/w3c/dom/Attr.java b/xml/src/main/java/org/w3c/dom/Attr.java
new file mode 100644
index 0000000..3bfde52
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Attr.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ *  The <code>Attr</code> interface represents an attribute in an 
+ * <code>Element</code> object. Typically the allowable values for the 
+ * attribute are defined in a document type definition.
+ * <p><code>Attr</code> objects inherit the <code>Node</code> interface, but 
+ * since they are not actually child nodes of the element they describe, the 
+ * DOM does not consider them part of the document tree. Thus, the 
+ * <code>Node</code> attributes <code>parentNode</code>, 
+ * <code>previousSibling</code>, and <code>nextSibling</code> have a 
+ * <code>null</code> value for <code>Attr</code> objects. The DOM takes the 
+ * view that attributes are properties of elements rather than having a 
+ * separate identity from the elements they are associated with; this should 
+ * make it more efficient to implement such features as default attributes 
+ * associated with all elements of a given type. Furthermore, 
+ * <code>Attr</code> nodes may not be immediate children of a 
+ * <code>DocumentFragment</code>. However, they can be associated with 
+ * <code>Element</code> nodes contained within a 
+ * <code>DocumentFragment</code>. In short, users and implementors of the 
+ * DOM need to be aware that <code>Attr</code> nodes have some things in 
+ * common with other objects inheriting the <code>Node</code> interface, but 
+ * they also are quite distinct.
+ * <p> The attribute's effective value is determined as follows: if this 
+ * attribute has been explicitly assigned any value, that value is the 
+ * attribute's effective value; otherwise, if there is a declaration for 
+ * this attribute, and that declaration includes a default value, then that 
+ * default value is the attribute's effective value; otherwise, the 
+ * attribute does not exist on this element in the structure model until it 
+ * has been explicitly added. Note that the <code>nodeValue</code> attribute 
+ * on the <code>Attr</code> instance can also be used to retrieve the string 
+ * version of the attribute's value(s). 
+ * <p>In XML, where the value of an attribute can contain entity references, 
+ * the child nodes of the <code>Attr</code> node may be either 
+ * <code>Text</code> or <code>EntityReference</code> nodes (when these are 
+ * in use; see the description of <code>EntityReference</code> for 
+ * discussion). Because the DOM Core is not aware of attribute types, it 
+ * treats all attribute values as simple strings, even if the DTD or schema 
+ * declares them as having tokenized types. 
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Attr extends Node {
+    /**
+     * Returns the name of this attribute.
+     * 
+     * @return the name of the attribute.
+     */
+    public String getName();
+
+    /**
+     * If this attribute was explicitly given a value in the original 
+     * document, this is <code>true</code>; otherwise, it is 
+     * <code>false</code>. Note that the implementation is in charge of this 
+     * attribute, not the user. If the user changes the value of the 
+     * attribute (even if it ends up having the same value as the default 
+     * value) then the <code>specified</code> flag is automatically flipped 
+     * to <code>true</code>. To re-specify the attribute as the default 
+     * value from the DTD, the user must delete the attribute. The 
+     * implementation will then make a new attribute available with 
+     * <code>specified</code> set to <code>false</code> and the default 
+     * value (if one exists).
+     * <br>In summary:  If the attribute has an assigned value in the document 
+     * then <code>specified</code> is <code>true</code>, and the value is 
+     * the assigned value.  If the attribute has no assigned value in the 
+     * document and has a default value in the DTD, then 
+     * <code>specified</code> is <code>false</code>, and the value is the 
+     * default value in the DTD. If the attribute has no assigned value in 
+     * the document and has a value of #IMPLIED in the DTD, then the 
+     * attribute does not appear in the structure model of the document. If 
+     * the <code>ownerElement</code> attribute is <code>null</code> (i.e. 
+     * because it was just created or was set to <code>null</code> by the 
+     * various removal and cloning operations) <code>specified</code> is 
+     * <code>true</code>.
+     * 
+     * @return <code>true</code> if the attribute was specified,
+     *         <code>false</false> otherwise.
+     */
+    public boolean getSpecified();
+
+    /**
+     * Returns the value of the attribute is returned as a string. 
+     * Character and general entity references are replaced with their 
+     * values. See also the method <code>getAttribute</code> on the 
+     * <code>Element</code> interface.
+     * 
+     * @return the attribute value as a string.
+     */
+    public String getValue();
+    
+    /**
+     * Sets the value of the attribute. This creates a <code>Text</code> node
+     * with the unparsed contents of the string. I.e. any characters that an
+     * XML processor would recognize as markup are instead treated as literal
+     * text. See also the method <code>setAttribute</code> on the
+     * <code>Element</code> 
+     * interface.
+     * 
+     * @param value the new attribute value.
+     * 
+     * @exception DOMException 
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     */
+    public void setValue(String value)
+                            throws DOMException;
+
+    /**
+     * The <code>Element</code> node this attribute is attached to or 
+     * <code>null</code> if this attribute is not in use.
+     * 
+     * @return the owner <code>Element</element>, or <code>null</code> is the
+     *         attribute is unused.
+     * 
+     * @since DOM Level 2
+     */
+    public Element getOwnerElement();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/CDATASection.java b/xml/src/main/java/org/w3c/dom/CDATASection.java
new file mode 100644
index 0000000..9e74734
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/CDATASection.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * CDATA sections are used to escape blocks of text containing characters that 
+ * would otherwise be regarded as markup. The only delimiter that is 
+ * recognized in a CDATA section is the "]]&gt;" string that ends the CDATA 
+ * section. CDATA sections cannot be nested. Their primary purpose is for 
+ * including material such as XML fragments, without needing to escape all 
+ * the delimiters.
+ * <p>The <code>DOMString</code> attribute of the <code>Text</code> node holds 
+ * the text that is contained by the CDATA section. Note that this may 
+ * contain characters that need to be escaped outside of CDATA sections and 
+ * that, depending on the character encoding ("charset") chosen for 
+ * serialization, it may be impossible to write out some characters as part 
+ * of a CDATA section. 
+ * <p> The <code>CDATASection</code> interface inherits from the 
+ * <code>CharacterData</code> interface through the <code>Text</code> 
+ * interface. Adjacent <code>CDATASection</code> nodes are not merged by use 
+ * of the <code>normalize</code> method of the <code>Node</code> interface.
+ * Because no markup is recognized within a <code>CDATASection</code>, 
+ * character numeric references cannot be used as an escape mechanism when 
+ * serializing. Therefore, action needs to be taken when serializing a 
+ * <code>CDATASection</code> with a character encoding where some of the 
+ * contained characters cannot be represented. Failure to do so would not 
+ * produce well-formed XML.One potential solution in the serialization 
+ * process is to end the CDATA section before the character, output the 
+ * character using a character reference or entity reference, and open a new 
+ * CDATA section for any further characters in the text node. Note, however, 
+ * that some code conversion libraries at the time of writing do not return 
+ * an error or exception when a character is missing from the encoding, 
+ * making the task of ensuring that data is not corrupted on serialization 
+ * more difficult.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface CDATASection extends Text {
+}
diff --git a/xml/src/main/java/org/w3c/dom/CharacterData.java b/xml/src/main/java/org/w3c/dom/CharacterData.java
new file mode 100644
index 0000000..47386e9
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/CharacterData.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>CharacterData</code> interface extends Node with a set of 
+ * attributes and methods for accessing character data in the DOM. For 
+ * clarity this set is defined here rather than on each object that uses 
+ * these attributes and methods. No DOM objects correspond directly to 
+ * <code>CharacterData</code>, though <code>Text</code> and others do 
+ * inherit the interface from it. All <code>offsets</code> in this interface 
+ * start from <code>0</code>.
+ * <p>As explained in the <code>DOMString</code> interface, text strings in 
+ * the DOM are represented in UTF-16, i.e. as a sequence of 16-bit units. In 
+ * the following, the term 16-bit units is used whenever necessary to 
+ * indicate that indexing on CharacterData is done in 16-bit units.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface CharacterData extends Node {
+    /**
+     * Returns the character data of the node that implements this interface.
+     * The DOM implementation may not put arbitrary limits on the amount of data 
+     * that may be stored in a <code>CharacterData</code> node. However, 
+     * implementation limits may mean that the entirety of a node's data may 
+     * not fit into a single <code>DOMString</code>. In such cases, the user 
+     * may call <code>substringData</code> to retrieve the data in 
+     * appropriately sized pieces.
+     * 
+     * @return the character data as a string.
+     * 
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than 
+     *   fit in a <code>DOMString</code> variable on the implementation 
+     *   platform.
+     */
+    public String getData()
+                            throws DOMException;
+    /**
+     * Sets the character data of the node that implements this interface. The
+     * DOM implementation may not put arbitrary limits on the amount of data 
+     * that may be stored in a <code>CharacterData</code> node. However, 
+     * implementation limits may mean that the entirety of a node's data may 
+     * not fit into a single <code>DOMString</code>. In such cases, the user 
+     * may call <code>substringData</code> to retrieve the data in 
+     * appropriately sized pieces.
+     * 
+     * @param data the new character data.
+     * 
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     */
+    public void setData(String data)
+                            throws DOMException;
+
+    /**
+     * The number of 16-bit units that are available through <code>data</code> 
+     * and the <code>substringData</code> method below. This may have the 
+     * value zero, i.e., <code>CharacterData</code> nodes may be empty.
+     * 
+     * @return the length in characters.
+     */
+    public int getLength();
+
+    /**
+     * Extracts a range of data from the node.
+     * @param offset Start offset of substring to extract.
+     * @param count The number of 16-bit units to extract.
+     * @return The specified substring. If the sum of <code>offset</code> and 
+     *   <code>count</code> exceeds the <code>length</code>, then all 16-bit 
+     *   units to the end of the data are returned.
+     * @exception DOMException
+     *   INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
+     *   negative or greater than the number of 16-bit units in 
+     *   <code>data</code>, or if the specified <code>count</code> is 
+     *   negative.
+     *   <br>DOMSTRING_SIZE_ERR: Raised if the specified range of text does 
+     *   not fit into a <code>DOMString</code>.
+     */
+    public String substringData(int offset, 
+                                int count)
+                                throws DOMException;
+
+    /**
+     * Append the string to the end of the character data of the node. Upon 
+     * success, <code>data</code> provides access to the concatenation of 
+     * <code>data</code> and the <code>DOMString</code> specified.
+     * @param arg The <code>DOMString</code> to append.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void appendData(String arg)
+                           throws DOMException;
+
+    /**
+     * Insert a string at the specified 16-bit unit offset.
+     * @param offset The character offset at which to insert.
+     * @param arg The <code>DOMString</code> to insert.
+     * @exception DOMException
+     *   INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
+     *   negative or greater than the number of 16-bit units in 
+     *   <code>data</code>.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void insertData(int offset, 
+                           String arg)
+                           throws DOMException;
+
+    /**
+     * Remove a range of 16-bit units from the node. Upon success, 
+     * <code>data</code> and <code>length</code> reflect the change.
+     * @param offset The offset from which to start removing.
+     * @param count The number of 16-bit units to delete. If the sum of 
+     *   <code>offset</code> and <code>count</code> exceeds 
+     *   <code>length</code> then all 16-bit units from <code>offset</code> 
+     *   to the end of the data are deleted.
+     * @exception DOMException
+     *   INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
+     *   negative or greater than the number of 16-bit units in 
+     *   <code>data</code>, or if the specified <code>count</code> is 
+     *   negative.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void deleteData(int offset, 
+                           int count)
+                           throws DOMException;
+
+    /**
+     * Replace the characters starting at the specified 16-bit unit offset 
+     * with the specified string.
+     * @param offset The offset from which to start replacing.
+     * @param count The number of 16-bit units to replace. If the sum of 
+     *   <code>offset</code> and <code>count</code> exceeds 
+     *   <code>length</code>, then all 16-bit units to the end of the data 
+     *   are replaced; (i.e., the effect is the same as a <code>remove</code>
+     *    method call with the same range, followed by an <code>append</code>
+     *    method invocation).
+     * @param arg The <code>DOMString</code> with which the range must be 
+     *   replaced.
+     * @exception DOMException
+     *   INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is 
+     *   negative or greater than the number of 16-bit units in 
+     *   <code>data</code>, or if the specified <code>count</code> is 
+     *   negative.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void replaceData(int offset, 
+                            int count, 
+                            String arg)
+                            throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Comment.java b/xml/src/main/java/org/w3c/dom/Comment.java
new file mode 100644
index 0000000..1097921
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Comment.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * This interface inherits from <code>CharacterData</code> and represents the 
+ * content of a comment, i.e., all the characters between the starting '
+ * <code>&lt;!--</code>' and ending '<code>--&gt;</code>'. Note that this is 
+ * the definition of a comment in XML, and, in practice, HTML, although some 
+ * HTML tools may implement the full SGML comment structure.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Comment extends CharacterData {
+}
diff --git a/xml/src/main/java/org/w3c/dom/DOMException.java b/xml/src/main/java/org/w3c/dom/DOMException.java
new file mode 100644
index 0000000..76bac3c
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DOMException.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * DOM operations only raise exceptions in "exceptional" circumstances, i.e., 
+ * when an operation is impossible to perform (either for logical reasons, 
+ * because data is lost, or because the implementation has become unstable). 
+ * In general, DOM methods return specific error values in ordinary 
+ * processing situations, such as out-of-bound errors when using 
+ * <code>NodeList</code>. 
+ * <p>Implementations should raise other exceptions under other circumstances. 
+ * For example, implementations should raise an implementation-dependent 
+ * exception if a <code>null</code> argument is passed. 
+ * <p>Some languages and object systems do not support the concept of 
+ * exceptions. For such systems, error conditions may be indicated using 
+ * native error reporting mechanisms. For some bindings, for example, 
+ * methods may return error codes similar to those listed in the 
+ * corresponding method descriptions.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public class DOMException extends RuntimeException {
+    /**
+     * Creates a new <code>DOMException</code> with the given error code and
+     * human-readable message.
+     * @param code the error code.
+     * @param message the human-readable message.
+     */
+    public DOMException(short code, String message) {
+       super(message);
+       this.code = code;
+    }
+    /**
+     * Holds the error code of the <code>DOMException</code>.
+     */
+    public short   code;
+    // ExceptionCode
+    /**
+     * If index or size is negative, or greater than the allowed value
+     */
+    public static final short INDEX_SIZE_ERR            = 1;
+    /**
+     * If the specified range of text does not fit into a DOMString
+     */
+    public static final short DOMSTRING_SIZE_ERR        = 2;
+    /**
+     * If any node is inserted somewhere it doesn't belong
+     */
+    public static final short HIERARCHY_REQUEST_ERR     = 3;
+    /**
+     * If a node is used in a different document than the one that created it 
+     * (that doesn't support it)
+     */
+    public static final short WRONG_DOCUMENT_ERR        = 4;
+    /**
+     * If an invalid or illegal character is specified, such as in a name. See 
+     * production 2 in the XML specification for the definition of a legal 
+     * character, and production 5 for the definition of a legal name 
+     * character.
+     */
+    public static final short INVALID_CHARACTER_ERR     = 5;
+    /**
+     * If data is specified for a node which does not support data
+     */
+    public static final short NO_DATA_ALLOWED_ERR       = 6;
+    /**
+     * If an attempt is made to modify an object where modifications are not 
+     * allowed
+     */
+    public static final short NO_MODIFICATION_ALLOWED_ERR = 7;
+    /**
+     * If an attempt is made to reference a node in a context where it does 
+     * not exist
+     */
+    public static final short NOT_FOUND_ERR             = 8;
+    /**
+     * If the implementation does not support the requested type of object or 
+     * operation.
+     */
+    public static final short NOT_SUPPORTED_ERR         = 9;
+    /**
+     * If an attempt is made to add an attribute that is already in use 
+     * elsewhere
+     */
+    public static final short INUSE_ATTRIBUTE_ERR       = 10;
+    /**
+     * If an attempt is made to use an object that is not, or is no longer, 
+     * usable.
+     * @since DOM Level 2
+     */
+    public static final short INVALID_STATE_ERR         = 11;
+    /**
+     * If an invalid or illegal string is specified.
+     * @since DOM Level 2
+     */
+    public static final short SYNTAX_ERR                = 12;
+    /**
+     * If an attempt is made to modify the type of the underlying object.
+     * @since DOM Level 2
+     */
+    public static final short INVALID_MODIFICATION_ERR  = 13;
+    /**
+     * If an attempt is made to create or change an object in a way which is 
+     * incorrect with regard to namespaces.
+     * @since DOM Level 2
+     */
+    public static final short NAMESPACE_ERR             = 14;
+    /**
+     * If a parameter or an operation is not supported by the underlying 
+     * object.
+     * @since DOM Level 2
+     */
+    public static final short INVALID_ACCESS_ERR        = 15;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/DOMImplementation.java b/xml/src/main/java/org/w3c/dom/DOMImplementation.java
new file mode 100644
index 0000000..dcb19c9
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DOMImplementation.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+/**
+ * The <code>DOMImplementation</code> interface provides a number of methods 
+ * for performing operations that are independent of any particular instance 
+ * of the document object model.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DOMImplementation {
+    /**
+     * Test if the DOM implementation implements a specific feature.
+     * @param feature The name of the feature to test (case-insensitive). The 
+     *   values used by DOM features are defined throughout the DOM Level 2 
+     *   specifications and listed in the  section. The name must be an XML 
+     *   name. To avoid possible conflicts, as a convention, names referring 
+     *   to features defined outside the DOM specification should be made 
+     *   unique by reversing the name of the Internet domain name of the 
+     *   person (or the organization that the person belongs to) who defines 
+     *   the feature, component by component, and using this as a prefix. 
+     *   For instance, the W3C SVG Working Group defines the feature 
+     *   "org.w3c.dom.svg".
+     * @param version This is the version number of the feature to test. In 
+     *   Level 2, the string can be either "2.0" or "1.0". If the version is 
+     *   not specified, supporting any version of the feature causes the 
+     *   method to return <code>true</code>.
+     * @return <code>true</code> if the feature is implemented in the 
+     *   specified version, <code>false</code> otherwise.
+     */
+    public boolean hasFeature(String feature, 
+                              String version);
+
+    /**
+     * Creates an empty <code>DocumentType</code> node. Entity declarations 
+     * and notations are not made available. Entity reference expansions and 
+     * default attribute additions do not occur. It is expected that a 
+     * future version of the DOM will provide a way for populating a 
+     * <code>DocumentType</code>.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param qualifiedName The qualified name of the document type to be 
+     *   created. 
+     * @param publicId The external subset public identifier.
+     * @param systemId The external subset system identifier.
+     * @return A new <code>DocumentType</code> node with 
+     *   <code>Node.ownerDocument</code> set to <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name 
+     *   contains an illegal character.
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
+     *   malformed.
+     * @since DOM Level 2
+     */
+    public DocumentType createDocumentType(String qualifiedName, 
+                                           String publicId, 
+                                           String systemId)
+                                           throws DOMException;
+
+    /**
+     * Creates an XML <code>Document</code> object of the specified type with 
+     * its document element. HTML-only DOM implementations do not need to 
+     * implement this method.
+     * @param namespaceURI The namespace URI of the document element to create.
+     * @param qualifiedName The qualified name of the document element to be 
+     *   created.
+     * @param doctype The type of document to be created or <code>null</code>.
+     *   When <code>doctype</code> is not <code>null</code>, its 
+     *   <code>Node.ownerDocument</code> attribute is set to the document 
+     *   being created.
+     * @return A new <code>Document</code> object.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name 
+     *   contains an illegal character.
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
+     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
+     *   <code>namespaceURI</code> is <code>null</code>, or if the 
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace" .
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has already 
+     *   been used with a different document or was created from a different 
+     *   implementation.
+     * @since DOM Level 2
+     */
+    public Document createDocument(String namespaceURI, 
+                                   String qualifiedName, 
+                                   DocumentType doctype)
+                                   throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Document.java b/xml/src/main/java/org/w3c/dom/Document.java
new file mode 100644
index 0000000..3beddaa
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Document.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Document</code> interface represents the entire HTML or XML 
+ * document. Conceptually, it is the root of the document tree, and provides 
+ * the primary access to the document's data.
+ * <p>Since elements, text nodes, comments, processing instructions, etc. 
+ * cannot exist outside the context of a <code>Document</code>, the 
+ * <code>Document</code> interface also contains the factory methods needed 
+ * to create these objects. The <code>Node</code> objects created have a 
+ * <code>ownerDocument</code> attribute which associates them with the 
+ * <code>Document</code> within whose context they were created.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Document extends Node {
+    /**
+     * The Document Type Declaration (see <code>DocumentType</code>) 
+     * associated with this document. For HTML documents as well as XML 
+     * documents without a document type declaration this returns 
+     * <code>null</code>. The DOM Level 2 does not support editing the 
+     * Document Type Declaration. <code>docType</code> cannot be altered in 
+     * any way, including through the use of methods inherited from the 
+     * <code>Node</code> interface, such as <code>insertNode</code> or 
+     * <code>removeNode</code>.
+     * 
+     * @return the Document Type Declaration associated with this document, if
+     * any.
+     */
+    public DocumentType getDoctype();
+
+    /**
+     * The <code>DOMImplementation</code> object that handles this document. A 
+     * DOM application may use objects from multiple implementations.
+     * 
+     * @return <code>DOMImplementation</code> object that handles this document.
+     */
+    public DOMImplementation getImplementation();
+
+    /**
+     * This is a convenience attribute that allows direct access to the child 
+     * node that is the root element of the document. For HTML documents, 
+     * this is the element with the tagName "HTML".
+     * 
+     * @return the root element of this document. 
+     */
+    public Element getDocumentElement();
+
+    /**
+     * Creates an element of the type specified. Note that the instance 
+     * returned implements the <code>Element</code> interface, so attributes 
+     * can be specified directly on the returned object.
+     * <br>In addition, if there are known attributes with default values, 
+     * <code>Attr</code> nodes representing them are automatically created 
+     * and attached to the element.
+     * <br>To create an element with a qualified name and namespace URI, use 
+     * the <code>createElementNS</code> method.
+     * @param tagName The name of the element type to instantiate. For XML, 
+     *   this is case-sensitive. For HTML, the <code>tagName</code> 
+     *   parameter may be provided in any case, but it must be mapped to the 
+     *   canonical uppercase form by the DOM implementation. 
+     * @return A new <code>Element</code> object with the 
+     *   <code>nodeName</code> attribute set to <code>tagName</code>, and 
+     *   <code>localName</code>, <code>prefix</code>, and 
+     *   <code>namespaceURI</code> set to <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an 
+     *   illegal character.
+     */
+    public Element createElement(String tagName)
+                                 throws DOMException;
+
+    /**
+     * Creates an empty <code>DocumentFragment</code> object. 
+     * @return A new <code>DocumentFragment</code>.
+     */
+    public DocumentFragment createDocumentFragment();
+
+    /**
+     * Creates a <code>Text</code> node given the specified string.
+     * @param data The data for the node.
+     * @return The new <code>Text</code> object.
+     */
+    public Text createTextNode(String data);
+
+    /**
+     * Creates a <code>Comment</code> node given the specified string.
+     * @param data The data for the node.
+     * @return The new <code>Comment</code> object.
+     */
+    public Comment createComment(String data);
+
+    /**
+     * Creates a <code>CDATASection</code> node whose value is the specified 
+     * string.
+     * @param data The data for the <code>CDATASection</code> contents.
+     * @return The new <code>CDATASection</code> object.
+     * @exception DOMException
+     *   NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     */
+    public CDATASection createCDATASection(String data)
+                                           throws DOMException;
+
+    /**
+     * Creates a <code>ProcessingInstruction</code> node given the specified 
+     * name and data strings.
+     * @param target The target part of the processing instruction.
+     * @param data The data for the node.
+     * @return The new <code>ProcessingInstruction</code> object.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified target contains an 
+     *   illegal character.
+     *   <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     */
+    public ProcessingInstruction createProcessingInstruction(String target, 
+                                                             String data)
+                                                             throws DOMException;
+
+    /**
+     * Creates an <code>Attr</code> of the given name. Note that the 
+     * <code>Attr</code> instance can then be set on an <code>Element</code> 
+     * using the <code>setAttributeNode</code> method. 
+     * <br>To create an attribute with a qualified name and namespace URI, use 
+     * the <code>createAttributeNS</code> method.
+     * @param name The name of the attribute.
+     * @return A new <code>Attr</code> object with the <code>nodeName</code> 
+     *   attribute set to <code>name</code>, and <code>localName</code>, 
+     *   <code>prefix</code>, and <code>namespaceURI</code> set to 
+     *   <code>null</code>. The value of the attribute is the empty string.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an 
+     *   illegal character.
+     */
+    public Attr createAttribute(String name)
+                                throws DOMException;
+
+    /**
+     * Creates an <code>EntityReference</code> object. In addition, if the 
+     * referenced entity is known, the child list of the 
+     * <code>EntityReference</code> node is made the same as that of the 
+     * corresponding <code>Entity</code> node.If any descendant of the 
+     * <code>Entity</code> node has an unbound namespace prefix, the 
+     * corresponding descendant of the created <code>EntityReference</code> 
+     * node is also unbound; (its <code>namespaceURI</code> is 
+     * <code>null</code>). The DOM Level 2 does not support any mechanism to 
+     * resolve namespace prefixes.
+     * @param name The name of the entity to reference. 
+     * @return The new <code>EntityReference</code> object.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an 
+     *   illegal character.
+     *   <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     */
+    public EntityReference createEntityReference(String name)
+                                                 throws DOMException;
+
+    /**
+     * Returns a <code>NodeList</code> of all the <code>Elements</code> with a 
+     * given tag name in the order in which they are encountered in a 
+     * preorder traversal of the <code>Document</code> tree. 
+     * @param tagname The name of the tag to match on. The special value "*" 
+     *   matches all tags.
+     * @return A new <code>NodeList</code> object containing all the matched 
+     *   <code>Elements</code>.
+     */
+    public NodeList getElementsByTagName(String tagname);
+
+    /**
+     * Imports a node from another document to this document. The returned 
+     * node has no parent; (<code>parentNode</code> is <code>null</code>). 
+     * The source node is not altered or removed from the original document; 
+     * this method creates a new copy of the source node.
+     * <br>For all nodes, importing a node creates a node object owned by the 
+     * importing document, with attribute values identical to the source 
+     * node's <code>nodeName</code> and <code>nodeType</code>, plus the 
+     * attributes related to namespaces (<code>prefix</code>, 
+     * <code>localName</code>, and <code>namespaceURI</code>). As in the 
+     * <code>cloneNode</code> operation on a <code>Node</code>, the source 
+     * node is not altered.
+     * <br>Additional information is copied as appropriate to the 
+     * <code>nodeType</code>, attempting to mirror the behavior expected if 
+     * a fragment of XML or HTML source was copied from one document to 
+     * another, recognizing that the two documents may have different DTDs 
+     * in the XML case. The following list describes the specifics for each 
+     * type of node. 
+     * <dl>
+     * <dt>ATTRIBUTE_NODE</dt>
+     * <dd>The <code>ownerElement</code> attribute 
+     * is set to <code>null</code> and the <code>specified</code> flag is 
+     * set to <code>true</code> on the generated <code>Attr</code>. The 
+     * descendants of the source <code>Attr</code> are recursively imported 
+     * and the resulting nodes reassembled to form the corresponding subtree.
+     * Note that the <code>deep</code> parameter has no effect on 
+     * <code>Attr</code> nodes; they always carry their children with them 
+     * when imported.</dd>
+     * <dt>DOCUMENT_FRAGMENT_NODE</dt>
+     * <dd>If the <code>deep</code> option 
+     * was set to <code>true</code>, the descendants of the source element 
+     * are recursively imported and the resulting nodes reassembled to form 
+     * the corresponding subtree. Otherwise, this simply generates an empty 
+     * <code>DocumentFragment</code>.</dd>
+     * <dt>DOCUMENT_NODE</dt>
+     * <dd><code>Document</code> 
+     * nodes cannot be imported.</dd>
+     * <dt>DOCUMENT_TYPE_NODE</dt>
+     * <dd><code>DocumentType</code> 
+     * nodes cannot be imported.</dd>
+     * <dt>ELEMENT_NODE</dt>
+     * <dd>Specified attribute nodes of the 
+     * source element are imported, and the generated <code>Attr</code> 
+     * nodes are attached to the generated <code>Element</code>. Default 
+     * attributes are not copied, though if the document being imported into 
+     * defines default attributes for this element name, those are assigned. 
+     * If the <code>importNode</code> <code>deep</code> parameter was set to 
+     * <code>true</code>, the descendants of the source element are 
+     * recursively imported and the resulting nodes reassembled to form the 
+     * corresponding subtree.</dd>
+     * <dt>ENTITY_NODE</dt>
+     * <dd><code>Entity</code> nodes can be 
+     * imported, however in the current release of the DOM the 
+     * <code>DocumentType</code> is readonly. Ability to add these imported 
+     * nodes to a <code>DocumentType</code> will be considered for addition 
+     * to a future release of the DOM.On import, the <code>publicId</code>, 
+     * <code>systemId</code>, and <code>notationName</code> attributes are 
+     * copied. If a <code>deep</code> import is requested, the descendants 
+     * of the the source <code>Entity</code> are recursively imported and 
+     * the resulting nodes reassembled to form the corresponding subtree.</dd>
+     * <dt>
+     * ENTITY_REFERENCE_NODE</dt>
+     * <dd>Only the <code>EntityReference</code> itself is 
+     * copied, even if a <code>deep</code> import is requested, since the 
+     * source and destination documents might have defined the entity 
+     * differently. If the document being imported into provides a 
+     * definition for this entity name, its value is assigned.</dd>
+     * <dt>NOTATION_NODE</dt>
+     * <dd>
+     * <code>Notation</code> nodes can be imported, however in the current 
+     * release of the DOM the <code>DocumentType</code> is readonly. Ability 
+     * to add these imported nodes to a <code>DocumentType</code> will be 
+     * considered for addition to a future release of the DOM.On import, the 
+     * <code>publicId</code> and <code>systemId</code> attributes are copied.
+     * Note that the <code>deep</code> parameter has no effect on 
+     * <code>Notation</code> nodes since they never have any children.</dd>
+     * <dt>
+     * PROCESSING_INSTRUCTION_NODE</dt>
+     * <dd>The imported node copies its 
+     * <code>target</code> and <code>data</code> values from those of the 
+     * source node.</dd>
+     * <dt>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE</dt>
+     * <dd>These three 
+     * types of nodes inheriting from <code>CharacterData</code> copy their 
+     * <code>data</code> and <code>length</code> attributes from those of 
+     * the source node.</dd>
+     *  
+     * @param importedNode The node to import.
+     * @param deep If <code>true</code>, recursively import the subtree under 
+     *   the specified node; if <code>false</code>, import only the node 
+     *   itself, as explained above. This has no effect on <code>Attr</code>
+     *   , <code>EntityReference</code>, and <code>Notation</code> nodes.
+     * @return The imported node that belongs to this <code>Document</code>.
+     * @exception DOMException
+     *   NOT_SUPPORTED_ERR: Raised if the type of node being imported is not 
+     *   supported.
+     * @since DOM Level 2
+     */
+    public Node importNode(Node importedNode, 
+                           boolean deep)
+                           throws DOMException;
+
+    /**
+     * Creates an element of the given qualified name and namespace URI. 
+     * HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the element to create.
+     * @param qualifiedName The qualified name of the element type to 
+     *   instantiate.
+     * @return A new <code>Element</code> object with the following 
+     *   attributes:AttributeValue<code>Node.nodeName</code>
+     *   <code>qualifiedName</code><code>Node.namespaceURI</code>
+     *   <code>namespaceURI</code><code>Node.prefix</code>prefix, extracted 
+     *   from <code>qualifiedName</code>, or <code>null</code> if there is 
+     *   no prefix<code>Node.localName</code>local name, extracted from 
+     *   <code>qualifiedName</code><code>Element.tagName</code>
+     *   <code>qualifiedName</code>
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name 
+     *   contains an illegal character.
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
+     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
+     *   <code>namespaceURI</code> is <code>null</code>, or if the 
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace" .
+     * @since DOM Level 2
+     */
+    public Element createElementNS(String namespaceURI, 
+                                   String qualifiedName)
+                                   throws DOMException;
+
+    /**
+     * Creates an attribute of the given qualified name and namespace URI. 
+     * HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to create.
+     * @param qualifiedName The qualified name of the attribute to instantiate.
+     * @return A new <code>Attr</code> object with the following attributes:
+     *   AttributeValue<code>Node.nodeName</code>qualifiedName
+     *   <code>Node.namespaceURI</code><code>namespaceURI</code>
+     *   <code>Node.prefix</code>prefix, extracted from 
+     *   <code>qualifiedName</code>, or <code>null</code> if there is no 
+     *   prefix<code>Node.localName</code>local name, extracted from 
+     *   <code>qualifiedName</code><code>Attr.name</code>
+     *   <code>qualifiedName</code><code>Node.nodeValue</code>the empty 
+     *   string
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name 
+     *   contains an illegal character.
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
+     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
+     *   <code>namespaceURI</code> is <code>null</code>, if the 
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace", or if the 
+     *   <code>qualifiedName</code> is "xmlns" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/2000/xmlns/".
+     * @since DOM Level 2
+     */
+    public Attr createAttributeNS(String namespaceURI, 
+                                  String qualifiedName)
+                                  throws DOMException;
+
+    /**
+     * Returns a <code>NodeList</code> of all the <code>Elements</code> with a 
+     * given local name and namespace URI in the order in which they are 
+     * encountered in a preorder traversal of the <code>Document</code> tree.
+     * @param namespaceURI The namespace URI of the elements to match on. The 
+     *   special value "*" matches all namespaces.
+     * @param localName The local name of the elements to match on. The 
+     *   special value "*" matches all local names.
+     * @return A new <code>NodeList</code> object containing all the matched 
+     *   <code>Elements</code>.
+     * @since DOM Level 2
+     */
+    public NodeList getElementsByTagNameNS(String namespaceURI, 
+                                           String localName);
+
+    /**
+     * Returns the <code>Element</code> whose <code>ID</code> is given by 
+     * <code>elementId</code>. If no such element exists, returns 
+     * <code>null</code>. Behavior is not defined if more than one element 
+     * has this <code>ID</code>. The DOM implementation must have 
+     * information that says which attributes are of type ID. Attributes 
+     * with the name "ID" are not of type ID unless so defined. 
+     * Implementations that do not know whether attributes are of type ID or 
+     * not are expected to return <code>null</code>.
+     * @param elementId The unique <code>id</code> value for an element.
+     * @return The matching element.
+     * @since DOM Level 2
+     */
+    public Element getElementById(String elementId);
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/DocumentFragment.java b/xml/src/main/java/org/w3c/dom/DocumentFragment.java
new file mode 100644
index 0000000..6ade30c
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DocumentFragment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * <code>DocumentFragment</code> is a "lightweight" or "minimal" 
+ * <code>Document</code> object. It is very common to want to be able to 
+ * extract a portion of a document's tree or to create a new fragment of a 
+ * document. Imagine implementing a user command like cut or rearranging a 
+ * document by moving fragments around. It is desirable to have an object 
+ * which can hold such fragments and it is quite natural to use a Node for 
+ * this purpose. While it is true that a <code>Document</code> object could 
+ * fulfill this role, a <code>Document</code> object can potentially be a 
+ * heavyweight object, depending on the underlying implementation. What is 
+ * really needed for this is a very lightweight object. 
+ * <code>DocumentFragment</code> is such an object.
+ * <p>Furthermore, various operations -- such as inserting nodes as children 
+ * of another <code>Node</code> -- may take <code>DocumentFragment</code> 
+ * objects as arguments; this results in all the child nodes of the 
+ * <code>DocumentFragment</code> being moved to the child list of this node.
+ * <p>The children of a <code>DocumentFragment</code> node are zero or more 
+ * nodes representing the tops of any sub-trees defining the structure of 
+ * the document. <code>DocumentFragment</code> nodes do not need to be 
+ * well-formed XML documents (although they do need to follow the rules 
+ * imposed upon well-formed XML parsed entities, which can have multiple top 
+ * nodes). For example, a <code>DocumentFragment</code> might have only one 
+ * child and that child node could be a <code>Text</code> node. Such a 
+ * structure model represents neither an HTML document nor a well-formed XML 
+ * document.
+ * <p>When a <code>DocumentFragment</code> is inserted into a 
+ * <code>Document</code> (or indeed any other <code>Node</code> that may 
+ * take children) the children of the <code>DocumentFragment</code> and not 
+ * the <code>DocumentFragment</code> itself are inserted into the 
+ * <code>Node</code>. This makes the <code>DocumentFragment</code> very 
+ * useful when the user wishes to create nodes that are siblings; the 
+ * <code>DocumentFragment</code> acts as the parent of these nodes so that 
+ * the user can use the standard methods from the <code>Node</code> 
+ * interface, such as <code>insertBefore</code> and <code>appendChild</code>.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DocumentFragment extends Node {
+}
diff --git a/xml/src/main/java/org/w3c/dom/DocumentType.java b/xml/src/main/java/org/w3c/dom/DocumentType.java
new file mode 100644
index 0000000..685c073
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DocumentType.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * Each <code>Document</code> has a <code>doctype</code> attribute whose value 
+ * is either <code>null</code> or a <code>DocumentType</code> object. The 
+ * <code>DocumentType</code> interface in the DOM Core provides an interface 
+ * to the list of entities that are defined for the document, and little 
+ * else because the effect of namespaces and the various XML schema efforts 
+ * on DTD representation are not clearly understood as of this writing.
+ * <p>The DOM Level 2 doesn't support editing <code>DocumentType</code> nodes.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DocumentType extends Node {
+    /**
+     * The name of DTD; i.e., the name immediately following the 
+     * <code>DOCTYPE</code> keyword.
+     * 
+     * @return the name of the DTD.
+     */
+    public String getName();
+
+    /**
+     * A <code>NamedNodeMap</code> containing the general entities, both 
+     * external and internal, declared in the DTD. Parameter entities are 
+     * not contained. Duplicates are discarded. For example in: 
+     * <pre>&lt;!DOCTYPE 
+     * ex SYSTEM "ex.dtd" [ &lt;!ENTITY foo "foo"&gt; &lt;!ENTITY bar 
+     * "bar"&gt; &lt;!ENTITY bar "bar2"&gt; &lt;!ENTITY % baz "baz"&gt; 
+     * ]&gt; &lt;ex/&gt;</pre>
+     *  the interface provides access to <code>foo</code> 
+     * and the first declaration of <code>bar</code> but not the second 
+     * declaration of <code>bar</code> or <code>baz</code>. Every node in 
+     * this map also implements the <code>Entity</code> interface.
+     * <br>The DOM Level 2 does not support editing entities, therefore 
+     * <code>entities</code> cannot be altered in any way.
+     * 
+     * @return the entities declared in this DTD.
+     */
+    public NamedNodeMap getEntities();
+
+    /**
+     * A <code>NamedNodeMap</code> containing the notations declared in the 
+     * DTD. Duplicates are discarded. Every node in this map also implements 
+     * the <code>Notation</code> interface.
+     * <br>The DOM Level 2 does not support editing notations, therefore 
+     * <code>notations</code> cannot be altered in any way.
+     * 
+     * @return the notations declared in this DTD.
+     */
+    public NamedNodeMap getNotations();
+
+    /**
+     * The public identifier of the external subset.
+     * 
+     * @return the public identifier.
+     * 
+     * @since DOM Level 2
+     */
+    public String getPublicId();
+
+    /**
+     * The system identifier of the external subset.
+     * 
+     * @return the system identifier.
+     * 
+     * @since DOM Level 2
+     */
+    public String getSystemId();
+
+    /**
+     * The internal subset as a string. The actual content returned depends on 
+     * how much information is available to the implementation. This may 
+     * vary depending on various parameters, including the XML processor 
+     * used to build the document.
+     * 
+     * @return the internal subset.
+     * 
+     * @since DOM Level 2
+     */
+    public String getInternalSubset();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Element.java b/xml/src/main/java/org/w3c/dom/Element.java
new file mode 100644
index 0000000..72e3478
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Element.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Element</code> interface represents an element in an HTML or XML 
+ * document. Elements may have attributes associated with them; since the 
+ * <code>Element</code> interface inherits from <code>Node</code>, the 
+ * generic <code>Node</code> interface attribute <code>attributes</code> may 
+ * be used to retrieve the set of all attributes for an element. There are 
+ * methods on the <code>Element</code> interface to retrieve either an 
+ * <code>Attr</code> object by name or an attribute value by name. In XML, 
+ * where an attribute value may contain entity references, an 
+ * <code>Attr</code> object should be retrieved to examine the possibly 
+ * fairly complex sub-tree representing the attribute value. On the other 
+ * hand, in HTML, where all attributes have simple string values, methods to 
+ * directly access an attribute value can safely be used as a convenience.In 
+ * DOM Level 2, the method <code>normalize</code> is inherited from the 
+ * <code>Node</code> interface where it was moved.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Element extends Node {
+    /**
+     * The name of the element. For example, in: 
+     * <pre> &lt;elementExample 
+     * id="demo"&gt; ... &lt;/elementExample&gt; , </pre>
+     *  <code>tagName</code> has 
+     * the value <code>"elementExample"</code>. Note that this is 
+     * case-preserving in XML, as are all of the operations of the DOM. The 
+     * HTML DOM returns the <code>tagName</code> of an HTML element in the 
+     * canonical uppercase form, regardless of the case in the source HTML 
+     * document.
+     * 
+     * @return the name of the element.
+     */
+    public String getTagName();
+
+    /**
+     * Retrieves an attribute value by name.
+     * @param name The name of the attribute to retrieve.
+     * @return The <code>Attr</code> value as a string, or the empty string 
+     *   if that attribute does not have a specified or default value.
+     */
+    public String getAttribute(String name);
+
+    /**
+     * Adds a new attribute. If an attribute with that name is already present 
+     * in the element, its value is changed to be that of the value 
+     * parameter. This value is a simple string; it is not parsed as it is 
+     * being set. So any markup (such as syntax to be recognized as an 
+     * entity reference) is treated as literal text, and needs to be 
+     * appropriately escaped by the implementation when it is written out. 
+     * In order to assign an attribute value that contains entity 
+     * references, the user must create an <code>Attr</code> node plus any 
+     * <code>Text</code> and <code>EntityReference</code> nodes, build the 
+     * appropriate subtree, and use <code>setAttributeNode</code> to assign 
+     * it as the value of an attribute.
+     * <br>To set an attribute with a qualified name and namespace URI, use 
+     * the <code>setAttributeNS</code> method.
+     * @param name The name of the attribute to create or alter.
+     * @param value Value to set in string form.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an 
+     *   illegal character.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void setAttribute(String name, 
+                             String value)
+                             throws DOMException;
+
+    /**
+     * Removes an attribute by name. If the removed attribute is known to have 
+     * a default value, an attribute immediately appears containing the 
+     * default value as well as the corresponding namespace URI, local name, 
+     * and prefix when applicable.
+     * <br>To remove an attribute by local name and namespace URI, use the 
+     * <code>removeAttributeNS</code> method.
+     * @param name The name of the attribute to remove.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public void removeAttribute(String name)
+                                throws DOMException;
+
+    /**
+     * Retrieves an attribute node by name.
+     * <br>To retrieve an attribute node by qualified name and namespace URI, 
+     * use the <code>getAttributeNodeNS</code> method.
+     * @param name The name (<code>nodeName</code>) of the attribute to 
+     *   retrieve.
+     * @return The <code>Attr</code> node with the specified name (
+     *   <code>nodeName</code>) or <code>null</code> if there is no such 
+     *   attribute.
+     */
+    public Attr getAttributeNode(String name);
+
+    /**
+     * Adds a new attribute node. If an attribute with that name (
+     * <code>nodeName</code>) is already present in the element, it is 
+     * replaced by the new one.
+     * <br>To add a new attribute node with a qualified name and namespace 
+     * URI, use the <code>setAttributeNodeNS</code> method.
+     * @param newAttr The <code>Attr</code> node to add to the attribute list.
+     * @return If the <code>newAttr</code> attribute replaces an existing 
+     *   attribute, the replaced <code>Attr</code> node is returned, 
+     *   otherwise <code>null</code> is returned.
+     * @exception DOMException
+     *   WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a 
+     *   different document than the one that created the element.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an 
+     *   attribute of another <code>Element</code> object. The DOM user must 
+     *   explicitly clone <code>Attr</code> nodes to re-use them in other 
+     *   elements.
+     */
+    public Attr setAttributeNode(Attr newAttr)
+                                 throws DOMException;
+
+    /**
+     * Removes the specified attribute node. If the removed <code>Attr</code> 
+     * has a default value it is immediately replaced. The replacing 
+     * attribute has the same namespace URI and local name, as well as the 
+     * original prefix, when applicable.
+     * @param oldAttr The <code>Attr</code> node to remove from the attribute 
+     *   list.
+     * @return The <code>Attr</code> node that was removed.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>oldAttr</code> is not an attribute 
+     *   of the element.
+     */
+    public Attr removeAttributeNode(Attr oldAttr)
+                                    throws DOMException;
+
+    /**
+     * Returns a <code>NodeList</code> of all descendant <code>Elements</code> 
+     * with a given tag name, in the order in which they are encountered in 
+     * a preorder traversal of this <code>Element</code> tree.
+     * @param name The name of the tag to match on. The special value "*" 
+     *   matches all tags.
+     * @return A list of matching <code>Element</code> nodes.
+     */
+    public NodeList getElementsByTagName(String name);
+
+    /**
+     * Retrieves an attribute value by local name and namespace URI. HTML-only 
+     * DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to retrieve.
+     * @param localName The local name of the attribute to retrieve.
+     * @return The <code>Attr</code> value as a string, or the empty string 
+     *   if that attribute does not have a specified or default value.
+     * @since DOM Level 2
+     */
+    public String getAttributeNS(String namespaceURI, 
+                                 String localName);
+
+    /**
+     * Adds a new attribute. If an attribute with the same local name and 
+     * namespace URI is already present on the element, its prefix is 
+     * changed to be the prefix part of the <code>qualifiedName</code>, and 
+     * its value is changed to be the <code>value</code> parameter. This 
+     * value is a simple string; it is not parsed as it is being set. So any 
+     * markup (such as syntax to be recognized as an entity reference) is 
+     * treated as literal text, and needs to be appropriately escaped by the 
+     * implementation when it is written out. In order to assign an 
+     * attribute value that contains entity references, the user must create 
+     * an <code>Attr</code> node plus any <code>Text</code> and 
+     * <code>EntityReference</code> nodes, build the appropriate subtree, 
+     * and use <code>setAttributeNodeNS</code> or 
+     * <code>setAttributeNode</code> to assign it as the value of an 
+     * attribute.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to create or 
+     *   alter.
+     * @param qualifiedName The qualified name of the attribute to create or 
+     *   alter.
+     * @param value The value to set in string form.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name 
+     *   contains an illegal character.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is 
+     *   malformed, if the <code>qualifiedName</code> has a prefix and the 
+     *   <code>namespaceURI</code> is <code>null</code>, if the 
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace", or if the 
+     *   <code>qualifiedName</code> is "xmlns" and the 
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/2000/xmlns/".
+     * @since DOM Level 2
+     */
+    public void setAttributeNS(String namespaceURI, 
+                               String qualifiedName, 
+                               String value)
+                               throws DOMException;
+
+    /**
+     * Removes an attribute by local name and namespace URI. If the removed 
+     * attribute has a default value it is immediately replaced. The 
+     * replacing attribute has the same namespace URI and local name, as 
+     * well as the original prefix.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to remove.
+     * @param localName The local name of the attribute to remove.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     * @since DOM Level 2
+     */
+    public void removeAttributeNS(String namespaceURI, 
+                                  String localName)
+                                  throws DOMException;
+
+    /**
+     * Retrieves an <code>Attr</code> node by local name and namespace URI. 
+     * HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to retrieve.
+     * @param localName The local name of the attribute to retrieve.
+     * @return The <code>Attr</code> node with the specified attribute local 
+     *   name and namespace URI or <code>null</code> if there is no such 
+     *   attribute.
+     * @since DOM Level 2
+     */
+    public Attr getAttributeNodeNS(String namespaceURI, 
+                                   String localName);
+
+    /**
+     * Adds a new attribute. If an attribute with that local name and that 
+     * namespace URI is already present in the element, it is replaced by 
+     * the new one.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param newAttr The <code>Attr</code> node to add to the attribute list.
+     * @return If the <code>newAttr</code> attribute replaces an existing 
+     *   attribute with the same local name and namespace URI, the replaced 
+     *   <code>Attr</code> node is returned, otherwise <code>null</code> is 
+     *   returned.
+     * @exception DOMException
+     *   WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a 
+     *   different document than the one that created the element.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an 
+     *   attribute of another <code>Element</code> object. The DOM user must 
+     *   explicitly clone <code>Attr</code> nodes to re-use them in other 
+     *   elements.
+     * @since DOM Level 2
+     */
+    public Attr setAttributeNodeNS(Attr newAttr)
+                                   throws DOMException;
+
+    /**
+     * Returns a <code>NodeList</code> of all the descendant 
+     * <code>Elements</code> with a given local name and namespace URI in 
+     * the order in which they are encountered in a preorder traversal of 
+     * this <code>Element</code> tree.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the elements to match on. The 
+     *   special value "*" matches all namespaces.
+     * @param localName The local name of the elements to match on. The 
+     *   special value "*" matches all local names.
+     * @return A new <code>NodeList</code> object containing all the matched 
+     *   <code>Elements</code>.
+     * @since DOM Level 2
+     */
+    public NodeList getElementsByTagNameNS(String namespaceURI, 
+                                           String localName);
+
+    /**
+     * Returns <code>true</code> when an attribute with a given name is 
+     * specified on this element or has a default value, <code>false</code> 
+     * otherwise.
+     * @param name The name of the attribute to look for.
+     * @return <code>true</code> if an attribute with the given name is 
+     *   specified on this element or has a default value, <code>false</code>
+     *    otherwise.
+     * @since DOM Level 2
+     */
+    public boolean hasAttribute(String name);
+
+    /**
+     * Returns <code>true</code> when an attribute with a given local name and 
+     * namespace URI is specified on this element or has a default value, 
+     * <code>false</code> otherwise. HTML-only DOM implementations do not 
+     * need to implement this method.
+     * @param namespaceURI The namespace URI of the attribute to look for.
+     * @param localName The local name of the attribute to look for.
+     * @return <code>true</code> if an attribute with the given local name 
+     *   and namespace URI is specified or has a default value on this 
+     *   element, <code>false</code> otherwise.
+     * @since DOM Level 2
+     */
+    public boolean hasAttributeNS(String namespaceURI, 
+                                  String localName);
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Entity.java b/xml/src/main/java/org/w3c/dom/Entity.java
new file mode 100644
index 0000000..5b09608
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Entity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * This interface represents an entity, either parsed or unparsed, in an XML 
+ * document. Note that this models the entity itself not the entity 
+ * declaration. <code>Entity</code> declaration modeling has been left for a 
+ * later Level of the DOM specification.
+ * <p>The <code>nodeName</code> attribute that is inherited from 
+ * <code>Node</code> contains the name of the entity.
+ * <p>An XML processor may choose to completely expand entities before the 
+ * structure model is passed to the DOM; in this case there will be no 
+ * <code>EntityReference</code> nodes in the document tree.
+ * <p>XML does not mandate that a non-validating XML processor read and 
+ * process entity declarations made in the external subset or declared in 
+ * external parameter entities. This means that parsed entities declared in 
+ * the external subset need not be expanded by some classes of applications, 
+ * and that the replacement value of the entity may not be available. When 
+ * the replacement value is available, the corresponding <code>Entity</code> 
+ * node's child list represents the structure of that replacement text. 
+ * Otherwise, the child list is empty.
+ * <p>The DOM Level 2 does not support editing <code>Entity</code> nodes; if a 
+ * user wants to make changes to the contents of an <code>Entity</code>, 
+ * every related <code>EntityReference</code> node has to be replaced in the 
+ * structure model by a clone of the <code>Entity</code>'s contents, and 
+ * then the desired changes must be made to each of those clones instead. 
+ * <code>Entity</code> nodes and all their descendants are readonly.
+ * <p>An <code>Entity</code> node does not have any parent.If the entity 
+ * contains an unbound namespace prefix, the <code>namespaceURI</code> of 
+ * the corresponding node in the <code>Entity</code> node subtree is 
+ * <code>null</code>. The same is true for <code>EntityReference</code> 
+ * nodes that refer to this entity, when they are created using the 
+ * <code>createEntityReference</code> method of the <code>Document</code> 
+ * interface. The DOM Level 2 does not support any mechanism to resolve 
+ * namespace prefixes.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Entity extends Node {
+    /**
+     * The public identifier associated with the entity, if specified. If the 
+     * public identifier was not specified, this is <code>null</code>.
+     * 
+     * @return the public identifier of the entity or <code>null</code>, if the
+     * entity does not have a public identifier.
+     */
+    public String getPublicId();
+
+    /**
+     * The system identifier associated with the entity, if specified. If the 
+     * system identifier was not specified, this is <code>null</code>.
+     * 
+     * @return the system identifier of the entity or <code>null</code>, if the
+     * entity does not have a system identifier.
+     */
+    public String getSystemId();
+
+    /**
+     * For unparsed entities, the name of the notation for the entity. For 
+     * parsed entities, this is <code>null</code>. 
+     * 
+     * @return the notation name of the entity or <code>null</code>, if the
+     * entity is parsed.
+     */
+    public String getNotationName();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/EntityReference.java b/xml/src/main/java/org/w3c/dom/EntityReference.java
new file mode 100644
index 0000000..ff3cf9d
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/EntityReference.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * <code>EntityReference</code> objects may be inserted into the structure 
+ * model when an entity reference is in the source document, or when the 
+ * user wishes to insert an entity reference. Note that character references 
+ * and references to predefined entities are considered to be expanded by 
+ * the HTML or XML processor so that characters are represented by their 
+ * Unicode equivalent rather than by an entity reference. Moreover, the XML 
+ * processor may completely expand references to entities while building the 
+ * structure model, instead of providing <code>EntityReference</code> 
+ * objects. If it does provide such objects, then for a given 
+ * <code>EntityReference</code> node, it may be that there is no 
+ * <code>Entity</code> node representing the referenced entity. If such an 
+ * <code>Entity</code> exists, then the subtree of the 
+ * <code>EntityReference</code> node is in general a copy of the 
+ * <code>Entity</code> node subtree. However, this may not be true when an 
+ * entity contains an unbound namespace prefix. In such a case, because the 
+ * namespace prefix resolution depends on where the entity reference is, the 
+ * descendants of the <code>EntityReference</code> node may be bound to 
+ * different namespace URIs.
+ * <p>As for <code>Entity</code> nodes, <code>EntityReference</code> nodes and 
+ * all their descendants are readonly.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface EntityReference extends Node {
+}
diff --git a/xml/src/main/java/org/w3c/dom/NamedNodeMap.java b/xml/src/main/java/org/w3c/dom/NamedNodeMap.java
new file mode 100644
index 0000000..a6cbf09
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/NamedNodeMap.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * Objects implementing the <code>NamedNodeMap</code> interface are used to 
+ * represent collections of nodes that can be accessed by name. Note that 
+ * <code>NamedNodeMap</code> does not inherit from <code>NodeList</code>; 
+ * <code>NamedNodeMaps</code> are not maintained in any particular order. 
+ * Objects contained in an object implementing <code>NamedNodeMap</code> may 
+ * also be accessed by an ordinal index, but this is simply to allow 
+ * convenient enumeration of the contents of a <code>NamedNodeMap</code>, 
+ * and does not imply that the DOM specifies an order to these Nodes. 
+ * <p><code>NamedNodeMap</code> objects in the DOM are live.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface NamedNodeMap {
+    /**
+     * Retrieves a node specified by name.
+     * @param name The <code>nodeName</code> of a node to retrieve.
+     * @return A <code>Node</code> (of any type) with the specified 
+     *   <code>nodeName</code>, or <code>null</code> if it does not identify 
+     *   any node in this map.
+     */
+    public Node getNamedItem(String name);
+
+    /**
+     * Adds a node using its <code>nodeName</code> attribute. If a node with 
+     * that name is already present in this map, it is replaced by the new 
+     * one.
+     * <br>As the <code>nodeName</code> attribute is used to derive the name 
+     * which the node must be stored under, multiple nodes of certain types 
+     * (those that have a "special" string value) cannot be stored as the 
+     * names would clash. This is seen as preferable to allowing nodes to be 
+     * aliased.
+     * @param arg A node to store in this map. The node will later be 
+     *   accessible using the value of its <code>nodeName</code> attribute.
+     * @return If the new <code>Node</code> replaces an existing node the 
+     *   replaced <code>Node</code> is returned, otherwise <code>null</code> 
+     *   is returned.
+     * @exception DOMException
+     *   WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a 
+     *   different document than the one that created this map.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+     *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an 
+     *   <code>Attr</code> that is already an attribute of another 
+     *   <code>Element</code> object. The DOM user must explicitly clone 
+     *   <code>Attr</code> nodes to re-use them in other elements.
+     */
+    public Node setNamedItem(Node arg)
+                             throws DOMException;
+
+    /**
+     * Removes a node specified by name. When this map contains the attributes 
+     * attached to an element, if the removed attribute is known to have a 
+     * default value, an attribute immediately appears containing the 
+     * default value as well as the corresponding namespace URI, local name, 
+     * and prefix when applicable.
+     * @param name The <code>nodeName</code> of the node to remove.
+     * @return The node removed from this map if a node with such a name 
+     *   exists.
+     * @exception DOMException
+     *   NOT_FOUND_ERR: Raised if there is no node named <code>name</code> in 
+     *   this map.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+     */
+    public Node removeNamedItem(String name)
+                                throws DOMException;
+
+    /**
+     * Returns the <code>index</code>th item in the map. If <code>index</code> 
+     * is greater than or equal to the number of nodes in this map, this 
+     * returns <code>null</code>.
+     * @param index Index into this map.
+     * @return The node at the <code>index</code>th position in the map, or 
+     *   <code>null</code> if that is not a valid index.
+     */
+    public Node item(int index);
+
+    /**
+     * The number of nodes in this map. The range of valid child node indices 
+     * is <code>0</code> to <code>length-1</code> inclusive.
+     * 
+     * @return the length of the map.
+     */
+    public int getLength();
+
+    /**
+     * Retrieves a node specified by local name and namespace URI. HTML-only 
+     * DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the node to retrieve.
+     * @param localName The local name of the node to retrieve.
+     * @return A <code>Node</code> (of any type) with the specified local 
+     *   name and namespace URI, or <code>null</code> if they do not 
+     *   identify any node in this map.
+     * @since DOM Level 2
+     */
+    public Node getNamedItemNS(String namespaceURI, 
+                               String localName);
+
+    /**
+     * Adds a node using its <code>namespaceURI</code> and 
+     * <code>localName</code>. If a node with that namespace URI and that 
+     * local name is already present in this map, it is replaced by the new 
+     * one.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param arg A node to store in this map. The node will later be 
+     *   accessible using the value of its <code>namespaceURI</code> and 
+     *   <code>localName</code> attributes.
+     * @return If the new <code>Node</code> replaces an existing node the 
+     *   replaced <code>Node</code> is returned, otherwise <code>null</code> 
+     *   is returned.
+     * @exception DOMException
+     *   WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a 
+     *   different document than the one that created this map.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+     *   <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an 
+     *   <code>Attr</code> that is already an attribute of another 
+     *   <code>Element</code> object. The DOM user must explicitly clone 
+     *   <code>Attr</code> nodes to re-use them in other elements.
+     * @since DOM Level 2
+     */
+    public Node setNamedItemNS(Node arg)
+                               throws DOMException;
+
+    /**
+     * Removes a node specified by local name and namespace URI. A removed 
+     * attribute may be known to have a default value when this map contains 
+     * the attributes attached to an element, as returned by the attributes 
+     * attribute of the <code>Node</code> interface. If so, an attribute 
+     * immediately appears containing the default value as well as the 
+     * corresponding namespace URI, local name, and prefix when applicable.
+     * <br>HTML-only DOM implementations do not need to implement this method.
+     * @param namespaceURI The namespace URI of the node to remove.
+     * @param localName The local name of the node to remove.
+     * @return The node removed from this map if a node with such a local 
+     *   name and namespace URI exists.
+     * @exception DOMException
+     *   NOT_FOUND_ERR: Raised if there is no node with the specified 
+     *   <code>namespaceURI</code> and <code>localName</code> in this map.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+     * @since DOM Level 2
+     */
+    public Node removeNamedItemNS(String namespaceURI, 
+                                  String localName)
+                                  throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Node.java b/xml/src/main/java/org/w3c/dom/Node.java
new file mode 100644
index 0000000..c91c46d
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Node.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Node</code> interface is the primary datatype for the entire 
+ * Document Object Model. It represents a single node in the document tree. 
+ * While all objects implementing the <code>Node</code> interface expose 
+ * methods for dealing with children, not all objects implementing the 
+ * <code>Node</code> interface may have children. For example, 
+ * <code>Text</code> nodes may not have children, and adding children to 
+ * such nodes results in a <code>DOMException</code> being raised.
+ * <p>The attributes <code>nodeName</code>, <code>nodeValue</code> and 
+ * <code>attributes</code> are included as a mechanism to get at node 
+ * information without casting down to the specific derived interface. In 
+ * cases where there is no obvious mapping of these attributes for a 
+ * specific <code>nodeType</code> (e.g., <code>nodeValue</code> for an 
+ * <code>Element</code> or <code>attributes</code> for a <code>Comment</code>
+ * ), this returns <code>null</code>. Note that the specialized interfaces 
+ * may contain additional and more convenient mechanisms to get and set the 
+ * relevant information.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Node {
+    // NodeType
+    /**
+     * The node is an <code>Element</code>.
+     */
+    public static final short ELEMENT_NODE              = 1;
+    /**
+     * The node is an <code>Attr</code>.
+     */
+    public static final short ATTRIBUTE_NODE            = 2;
+    /**
+     * The node is a <code>Text</code> node.
+     */
+    public static final short TEXT_NODE                 = 3;
+    /**
+     * The node is a <code>CDATASection</code>.
+     */
+    public static final short CDATA_SECTION_NODE        = 4;
+    /**
+     * The node is an <code>EntityReference</code>.
+     */
+    public static final short ENTITY_REFERENCE_NODE     = 5;
+    /**
+     * The node is an <code>Entity</code>.
+     */
+    public static final short ENTITY_NODE               = 6;
+    /**
+     * The node is a <code>ProcessingInstruction</code>.
+     */
+    public static final short PROCESSING_INSTRUCTION_NODE = 7;
+    /**
+     * The node is a <code>Comment</code>.
+     */
+    public static final short COMMENT_NODE              = 8;
+    /**
+     * The node is a <code>Document</code>.
+     */
+    public static final short DOCUMENT_NODE             = 9;
+    /**
+     * The node is a <code>DocumentType</code>.
+     */
+    public static final short DOCUMENT_TYPE_NODE        = 10;
+    /**
+     * The node is a <code>DocumentFragment</code>.
+     */
+    public static final short DOCUMENT_FRAGMENT_NODE    = 11;
+    /**
+     * The node is a <code>Notation</code>.
+     */
+    public static final short NOTATION_NODE             = 12;
+
+    /**
+     * The name of this node, depending on its type; see the table above. 
+     * 
+     * @return the name of the node.
+     */
+    public String getNodeName();
+
+    /**
+     * Returns the value of this node, depending on its type; see the table
+     * above.
+     * 
+     * @return the value of the node.
+     * 
+     * @exception DOMException
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than 
+     *   fit in a <code>DOMString</code> variable on the implementation 
+     *   platform.
+     */
+    public String getNodeValue()
+                                 throws DOMException;
+    /**
+     * Sets the value of this node, depending on its type; see the table above. 
+     * When it is defined to be <code>null</code>, setting it has no effect.
+     * 
+     * @param nodeValue the new value of the node.
+     * 
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     */
+    public void setNodeValue(String nodeValue)
+                                 throws DOMException;
+
+    /**
+     * A code representing the type of the underlying object, as defined above.
+     * 
+     * @return the type of the node.
+     */
+    public short getNodeType();
+
+    /**
+     * The parent of this node. All nodes, except <code>Attr</code>, 
+     * <code>Document</code>, <code>DocumentFragment</code>, 
+     * <code>Entity</code>, and <code>Notation</code> may have a parent. 
+     * However, if a node has just been created and not yet added to the 
+     * tree, or if it has been removed from the tree, this is 
+     * <code>null</code>.
+     * 
+     * @return the parent node, if any.
+     */
+    public Node getParentNode();
+
+    /**
+     * A <code>NodeList</code> that contains all children of this node. If 
+     * there are no children, this is a <code>NodeList</code> containing no 
+     * nodes.
+     * 
+     * @return the list of children, which may be empty.
+     */
+    public NodeList getChildNodes();
+
+    /**
+     * The first child of this node. If there is no such node, this returns 
+     * <code>null</code>.
+     * 
+     * @return the first child of the node, if any.
+     */
+    public Node getFirstChild();
+
+    /**
+     * The last child of this node. If there is no such node, this returns 
+     * <code>null</code>.
+     * 
+     * @return the last child of the node, if any.
+     */
+    public Node getLastChild();
+
+    /**
+     * The node immediately preceding this node. If there is no such node, 
+     * this returns <code>null</code>.
+     * 
+     * @return the preceding node, if any.
+     */
+    public Node getPreviousSibling();
+
+    /**
+     * The node immediately following this node. If there is no such node, 
+     * this returns <code>null</code>.
+     * 
+     * @return the following node, if any.
+     */
+    public Node getNextSibling();
+
+    /**
+     * A <code>NamedNodeMap</code> containing the attributes of this node (if 
+     * it is an <code>Element</code>) or <code>null</code> otherwise. 
+     * 
+     * @return the attributes of the node, which may be an empty map, or
+     * <code>null</code>, if this the node cannot have any attributes.
+     */
+    public NamedNodeMap getAttributes();
+
+    /**
+     * The <code>Document</code> object associated with this node. This is 
+     * also the <code>Document</code> object used to create new nodes. When 
+     * this node is a <code>Document</code> or a <code>DocumentType</code> 
+     * which is not used with any <code>Document</code> yet, this is 
+     * <code>null</code>.
+     * 
+     * @return the document this node belongs to, if any.
+     * 
+     * @version DOM Level 2
+     */
+    public Document getOwnerDocument();
+
+    /**
+     * Inserts the node <code>newChild</code> before the existing child node 
+     * <code>refChild</code>. If <code>refChild</code> is <code>null</code>, 
+     * insert <code>newChild</code> at the end of the list of children.
+     * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object, 
+     * all of its children are inserted, in the same order, before 
+     * <code>refChild</code>. If the <code>newChild</code> is already in the 
+     * tree, it is first removed.
+     * @param newChild The node to insert.
+     * @param refChild The reference node, i.e., the node before which the new 
+     *   node must be inserted.
+     * @return The node being inserted.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not 
+     *   allow children of the type of the <code>newChild</code> node, or if 
+     *   the node to insert is one of this node's ancestors.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or 
+     *   if the parent of the node being inserted is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of 
+     *   this node.
+     */
+    public Node insertBefore(Node newChild, 
+                             Node refChild)
+                             throws DOMException;
+
+    /**
+     * Replaces the child node <code>oldChild</code> with <code>newChild</code>
+     *  in the list of children, and returns the <code>oldChild</code> node.
+     * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object, 
+     * <code>oldChild</code> is replaced by all of the 
+     * <code>DocumentFragment</code> children, which are inserted in the 
+     * same order. If the <code>newChild</code> is already in the tree, it 
+     * is first removed.
+     * @param newChild The new node to put in the child list.
+     * @param oldChild The node being replaced in the list.
+     * @return The node replaced.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not 
+     *   allow children of the type of the <code>newChild</code> node, or if 
+     *   the node to put in is one of this node's ancestors.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of 
+     *   the new node is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of 
+     *   this node.
+     */
+    public Node replaceChild(Node newChild, 
+                             Node oldChild)
+                             throws DOMException;
+
+    /**
+     * Removes the child node indicated by <code>oldChild</code> from the list 
+     * of children, and returns it.
+     * @param oldChild The node being removed.
+     * @return The node removed.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of 
+     *   this node.
+     */
+    public Node removeChild(Node oldChild)
+                            throws DOMException;
+
+    /**
+     * Adds the node <code>newChild</code> to the end of the list of children 
+     * of this node. If the <code>newChild</code> is already in the tree, it 
+     * is first removed.
+     * @param newChild The node to add.If it is a <code>DocumentFragment</code>
+     *    object, the entire contents of the document fragment are moved 
+     *   into the child list of this node
+     * @return The node added.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not 
+     *   allow children of the type of the <code>newChild</code> node, or if 
+     *   the node to append is one of this node's ancestors.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created 
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public Node appendChild(Node newChild)
+                            throws DOMException;
+
+    /**
+     * Returns whether this node has any children.
+     * @return  <code>true</code> if this node has any children, 
+     *   <code>false</code> otherwise.
+     */
+    public boolean hasChildNodes();
+
+    /**
+     * Returns a duplicate of this node, i.e., serves as a generic copy 
+     * constructor for nodes. The duplicate node has no parent; (
+     * <code>parentNode</code> is <code>null</code>.).
+     * <br>Cloning an <code>Element</code> copies all attributes and their 
+     * values, including those generated by the XML processor to represent 
+     * defaulted attributes, but this method does not copy any text it 
+     * contains unless it is a deep clone, since the text is contained in a 
+     * child <code>Text</code> node. Cloning an <code>Attribute</code> 
+     * directly, as opposed to be cloned as part of an <code>Element</code> 
+     * cloning operation, returns a specified attribute (
+     * <code>specified</code> is <code>true</code>). Cloning any other type 
+     * of node simply returns a copy of this node.
+     * <br>Note that cloning an immutable subtree results in a mutable copy, 
+     * but the children of an <code>EntityReference</code> clone are readonly
+     * . In addition, clones of unspecified <code>Attr</code> nodes are 
+     * specified. And, cloning <code>Document</code>, 
+     * <code>DocumentType</code>, <code>Entity</code>, and 
+     * <code>Notation</code> nodes is implementation dependent.
+     * @param deep If <code>true</code>, recursively clone the subtree under 
+     *   the specified node; if <code>false</code>, clone only the node 
+     *   itself (and its attributes, if it is an <code>Element</code>). 
+     * @return The duplicate node.
+     */
+    public Node cloneNode(boolean deep);
+
+    /**
+     * Puts all <code>Text</code> nodes in the full depth of the sub-tree 
+     * underneath this <code>Node</code>, including attribute nodes, into a 
+     * "normal" form where only structure (e.g., elements, comments, 
+     * processing instructions, CDATA sections, and entity references) 
+     * separates <code>Text</code> nodes, i.e., there are neither adjacent 
+     * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can 
+     * be used to ensure that the DOM view of a document is the same as if 
+     * it were saved and re-loaded, and is useful when operations (such as 
+     * XPointer  lookups) that depend on a particular document tree 
+     * structure are to be used.In cases where the document contains 
+     * <code>CDATASections</code>, the normalize operation alone may not be 
+     * sufficient, since XPointers do not differentiate between 
+     * <code>Text</code> nodes and <code>CDATASection</code> nodes.
+     * @version DOM Level 2
+     */
+    public void normalize();
+
+    /**
+     * Tests whether the DOM implementation implements a specific feature and 
+     * that feature is supported by this node.
+     * @param feature The name of the feature to test. This is the same name 
+     *   which can be passed to the method <code>hasFeature</code> on 
+     *   <code>DOMImplementation</code>.
+     * @param version This is the version number of the feature to test. In 
+     *   Level 2, version 1, this is the string "2.0". If the version is not 
+     *   specified, supporting any version of the feature will cause the 
+     *   method to return <code>true</code>.
+     * @return Returns <code>true</code> if the specified feature is 
+     *   supported on this node, <code>false</code> otherwise.
+     * @since DOM Level 2
+     */
+    public boolean isSupported(String feature, 
+                               String version);
+
+    /**
+     * The namespace URI of this node, or <code>null</code> if it is 
+     * unspecified.
+     * <br>This is not a computed value that is the result of a namespace 
+     * lookup based on an examination of the namespace declarations in 
+     * scope. It is merely the namespace URI given at creation time.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and 
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 
+     * method, such as <code>createElement</code> from the 
+     * <code>Document</code> interface, this is always <code>null</code>.Per 
+     * the Namespaces in XML Specification  an attribute does not inherit 
+     * its namespace from the element it is attached to. If an attribute is 
+     * not explicitly given a namespace, it simply has no namespace.
+     * 
+     * @return the namespace URI, if any.
+     * 
+     * @since DOM Level 2
+     */
+    public String getNamespaceURI();
+
+    /**
+     * Returns the namespace prefix of this node, or <code>null</code> if it is 
+     * unspecified.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and 
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 
+     * method, such as <code>createElement</code> from the 
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * 
+     * @return the namespace prefix, if any.
+     * 
+     * @exception DOMException
+     * @since DOM Level 2
+     */
+    public String getPrefix();
+    
+    /**
+     * Sets the namespace prefix of this node.
+     * <br>Note that setting this attribute, when permitted, changes the 
+     * <code>nodeName</code> attribute, which holds the qualified name, as 
+     * well as the <code>tagName</code> and <code>name</code> attributes of 
+     * the <code>Element</code> and <code>Attr</code> interfaces, when 
+     * applicable.
+     * <br>Note also that changing the prefix of an attribute that is known to 
+     * have a default value, does not make a new attribute with the default 
+     * value and the original prefix appear, since the 
+     * <code>namespaceURI</code> and <code>localName</code> do not change.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and 
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 
+     * method, such as <code>createElement</code> from the 
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified prefix contains an 
+     *   illegal character.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is 
+     *   malformed, if the <code>namespaceURI</code> of this node is 
+     *   <code>null</code>, if the specified prefix is "xml" and the 
+     *   <code>namespaceURI</code> of this node is different from "
+     *   http://www.w3.org/XML/1998/namespace", if this node is an attribute 
+     *   and the specified prefix is "xmlns" and the 
+     *   <code>namespaceURI</code> of this node is different from "
+     *   http://www.w3.org/2000/xmlns/", or if this node is an attribute and 
+     *   the <code>qualifiedName</code> of this node is "xmlns" .
+     *   
+     * @param prefix the new namespace prefix.
+     * 
+     * @since DOM Level 2
+     */
+    public void setPrefix(String prefix)
+                               throws DOMException;
+
+    /**
+     * Returns the local part of the qualified name of this node.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and 
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1 
+     * method, such as <code>createElement</code> from the 
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * 
+     * @return the local name, if any.
+     * 
+     * @since DOM Level 2
+     */
+    public String getLocalName();
+
+    /**
+     * Returns whether this node (if it is an element) has any attributes.
+     * @return <code>true</code> if this node has any attributes, 
+     *   <code>false</code> otherwise.
+     * @since DOM Level 2
+     */
+    public boolean hasAttributes();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/NodeList.java b/xml/src/main/java/org/w3c/dom/NodeList.java
new file mode 100644
index 0000000..0dbadda
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/NodeList.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>NodeList</code> interface provides the abstraction of an ordered 
+ * collection of nodes, without defining or constraining how this collection 
+ * is implemented. <code>NodeList</code> objects in the DOM are live.
+ * <p>The items in the <code>NodeList</code> are accessible via an integral 
+ * index, starting from 0.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface NodeList {
+    /**
+     * Returns the <code>index</code>th item in the collection. If 
+     * <code>index</code> is greater than or equal to the number of nodes in 
+     * the list, this returns <code>null</code>.
+     * @param index Index into the collection.
+     * @return The node at the <code>index</code>th position in the 
+     *   <code>NodeList</code>, or <code>null</code> if that is not a valid 
+     *   index.
+     */
+    public Node item(int index);
+
+    /**
+     * The number of nodes in the list. The range of valid child node indices 
+     * is 0 to <code>length-1</code> inclusive.
+     * 
+     * @return the length of the list. 
+     */
+    public int getLength();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Notation.java b/xml/src/main/java/org/w3c/dom/Notation.java
new file mode 100644
index 0000000..00c702f
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Notation.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * This interface represents a notation declared in the DTD. A notation either 
+ * declares, by name, the format of an unparsed entity (see section 4.7 of 
+ * the XML 1.0 specification ), or is used for formal declaration of 
+ * processing instruction targets (see section 2.6 of the XML 1.0 
+ * specification ). The <code>nodeName</code> attribute inherited from 
+ * <code>Node</code> is set to the declared name of the notation.
+ * <p>The DOM Level 1 does not support editing <code>Notation</code> nodes; 
+ * they are therefore readonly.
+ * <p>A <code>Notation</code> node does not have any parent.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Notation extends Node {
+    /**
+     * The public identifier of this notation. If the public identifier was 
+     * not specified, this is <code>null</code>.
+     * 
+     * @return the public identifier of this notation, if any.
+     */
+    public String getPublicId();
+
+    /**
+     * The system identifier of this notation. If the system identifier was 
+     * not specified, this is <code>null</code>.
+     * 
+     * @return the system identifier of this notation, if any.
+     */
+    public String getSystemId();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java b/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java
new file mode 100644
index 0000000..a702aa6
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>ProcessingInstruction</code> interface represents a "processing 
+ * instruction", used in XML as a way to keep processor-specific information 
+ * in the text of the document.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface ProcessingInstruction extends Node {
+    /**
+     * The target of this processing instruction. XML defines this as being 
+     * the first token following the markup that begins the processing 
+     * instruction.
+     * 
+     * @return the target of this processing instruction.
+     */
+    public String getTarget();
+
+    /**
+     * Returns the content of this processing instruction. This is from the
+     * first non white space character after the target to the character
+     * immediately preceding the <code>?&gt;</code>.
+     * 
+     * @return the data of this processing instruction.
+     */
+    public String getData();
+
+    /**
+     * Sets the content of this processing instruction. This is from the first
+     * non white space character after the target to the character immediately 
+     * preceding the <code>?&gt;</code>.
+     * 
+     * @param data the new data of the processing instruction.
+     * 
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     */
+    public void setData(String data)
+                          throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Text.java b/xml/src/main/java/org/w3c/dom/Text.java
new file mode 100644
index 0000000..4d1746b
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Text.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+/**
+ * The <code>Text</code> interface inherits from <code>CharacterData</code> 
+ * and represents the textual content (termed character data in XML) of an 
+ * <code>Element</code> or <code>Attr</code>. If there is no markup inside 
+ * an element's content, the text is contained in a single object 
+ * implementing the <code>Text</code> interface that is the only child of 
+ * the element. If there is markup, it is parsed into the information items 
+ * (elements, comments, etc.) and <code>Text</code> nodes that form the list 
+ * of children of the element.
+ * <p>When a document is first made available via the DOM, there is only one 
+ * <code>Text</code> node for each block of text. Users may create adjacent 
+ * <code>Text</code> nodes that represent the contents of a given element 
+ * without any intervening markup, but should be aware that there is no way 
+ * to represent the separations between these nodes in XML or HTML, so they 
+ * will not (in general) persist between DOM editing sessions. The 
+ * <code>normalize()</code> method on <code>Node</code> merges any such 
+ * adjacent <code>Text</code> objects into a single node for each block of 
+ * text.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Text extends CharacterData {
+    /**
+     * Breaks this node into two nodes at the specified <code>offset</code>, 
+     * keeping both in the tree as siblings. After being split, this node 
+     * will contain all the content up to the <code>offset</code> point. A 
+     * new node of the same type, which contains all the content at and 
+     * after the <code>offset</code> point, is returned. If the original 
+     * node had a parent node, the new node is inserted as the next sibling 
+     * of the original node. When the <code>offset</code> is equal to the 
+     * length of this node, the new node has no data.
+     * @param offset The 16-bit unit offset at which to split, starting from 
+     *   <code>0</code>.
+     * @return The new node, of the same type as this node.
+     * @exception DOMException
+     *   INDEX_SIZE_ERR: Raised if the specified offset is negative or greater 
+     *   than the number of 16-bit units in <code>data</code>.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     */
+    public Text splitText(int offset)
+                          throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/package.html b/xml/src/main/java/org/w3c/dom/package.html
new file mode 100644
index 0000000..8189944
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/package.html
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <p>
+      Provides the official W3C Java bindings for the Document Object Model,
+      level 2 core. XML documents returned by
+      {@link javax.xml.parsers.DocumentBuilder} are accessed and manipulated
+      through these interfaces.
+    </p>
+    
+  @since Android 1.0
+  </body>
+</html>
\ No newline at end of file
diff --git a/xml/src/main/java/org/xml/sax/AttributeList.java b/xml/src/main/java/org/xml/sax/AttributeList.java
new file mode 100644
index 0000000..9285eac
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/AttributeList.java
@@ -0,0 +1,193 @@
+// SAX Attribute List Interface.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: AttributeList.java,v 1.7 2004/04/26 17:34:34 dmegginson Exp $
+
+package org.xml.sax;
+
+/**
+ * Interface for an element's attribute specifications.
+ *
+ * <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 original SAX1 interface for reporting an element's
+ * attributes.  Unlike the new {@link org.xml.sax.Attributes Attributes}
+ * interface, it does not support Namespace-related information.</p>
+ *
+ * <p>When an attribute list is supplied as part of a
+ * {@link org.xml.sax.DocumentHandler#startElement startElement}
+ * event, the list will return valid results only during the
+ * scope of the event; once the event handler returns control
+ * to the parser, the attribute list is invalid.  To save a
+ * persistent copy of the attribute list, use the SAX1
+ * {@link org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
+ * helper class.</p>
+ *
+ * <p>An attribute list includes only attributes that have been
+ * specified or defaulted: #IMPLIED attributes will not be included.</p>
+ *
+ * <p>There are two ways for the SAX application to obtain information
+ * from the AttributeList.  First, it can iterate through the entire
+ * list:</p>
+ *
+ * <pre>
+ * public void startElement (String name, AttributeList atts) {
+ *   for (int i = 0; i < atts.getLength(); i++) {
+ *     String name = atts.getName(i);
+ *     String type = atts.getType(i);
+ *     String value = atts.getValue(i);
+ *     [...]
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>(Note that the result of getLength() will be zero if there
+ * are no attributes.)
+ *
+ * <p>As an alternative, the application can request the value or
+ * type of specific attributes:</p>
+ *
+ * <pre>
+ * public void startElement (String name, AttributeList atts) {
+ *   String identifier = atts.getValue("id");
+ *   String label = atts.getValue("label");
+ *   [...]
+ * }
+ * </pre>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ *             {@link org.xml.sax.Attributes Attributes}
+ *             interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.DocumentHandler#startElement startElement
+ * @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
+ */
+public interface AttributeList {
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Iteration methods.
+    ////////////////////////////////////////////////////////////////////
+    
+
+    /**
+     * Return the number of attributes in this list.
+     *
+     * <p>The SAX parser may provide attributes in any
+     * arbitrary order, regardless of the order in which they were
+     * declared or specified.  The number of attributes may be
+     * zero.</p>
+     *
+     * @return The number of attributes in the list.  
+     */
+    public abstract int getLength ();
+    
+    
+    /**
+     * Return the name of an attribute in this list (by position).
+     *
+     * <p>The names must be unique: the SAX parser shall not include the
+     * same attribute twice.  Attributes without values (those declared
+     * #IMPLIED without a value specified in the start tag) will be
+     * omitted from the list.</p>
+     *
+     * <p>If the attribute name has a namespace prefix, the prefix
+     * will still be attached.</p>
+     *
+     * @param i The index of the attribute in the list (starting at 0).
+     * @return The name of the indexed attribute, or null
+     *         if the index is out of range.
+     * @see #getLength 
+     */
+    public abstract String getName (int i);
+    
+    
+    /**
+     * Return the type of an attribute in the list (by position).
+     *
+     * <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 i The index of the attribute in the list (starting at 0).
+     * @return The attribute type as a string, or
+     *         null if the index is out of range.
+     * @see #getLength 
+     * @see #getType(java.lang.String)
+     */
+    public abstract String getType (int i);
+    
+    
+    /**
+     * Return the value of an attribute in the list (by position).
+     *
+     * <p>If the attribute value is a list of tokens (IDREFS,
+     * ENTITIES, or NMTOKENS), the tokens will be concatenated
+     * into a single string separated by whitespace.</p>
+     *
+     * @param i The index of the attribute in the list (starting at 0).
+     * @return The attribute value as a string, or
+     *         null if the index is out of range.
+     * @see #getLength
+     * @see #getValue(java.lang.String)
+     */
+    public abstract String getValue (int i);
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Lookup methods.
+    ////////////////////////////////////////////////////////////////////
+    
+    
+    /**
+     * Return the type of an attribute in the list (by name).
+     *
+     * <p>The return value is the same as the return value for
+     * getType(int).</p>
+     *
+     * <p>If the attribute name has a namespace prefix in the document,
+     * the application must include the prefix here.</p>
+     *
+     * @param name The name of the attribute.
+     * @return The attribute type as a string, or null if no
+     *         such attribute exists.
+     * @see #getType(int)
+     */
+    public abstract String getType (String name);
+    
+    
+    /**
+     * Return the value of an attribute in the list (by name).
+     *
+     * <p>The return value is the same as the return value for
+     * getValue(int).</p>
+     *
+     * <p>If the attribute name has a namespace prefix in the document,
+     * the application must include the prefix here.</p>
+     *
+     * @param name the name of the attribute to return
+     * @return The attribute value as a string, or null if
+     *         no such attribute exists.
+     * @see #getValue(int)
+     */
+    public abstract String getValue (String name);
+    
+}
+
+// end of AttributeList.java
diff --git a/xml/src/main/java/org/xml/sax/Attributes.java b/xml/src/main/java/org/xml/sax/Attributes.java
new file mode 100644
index 0000000..b25432d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Attributes.java
@@ -0,0 +1,257 @@
+// 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.13 2004/03/18 12:28:05 dmegginson Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/ContentHandler.java b/xml/src/main/java/org/xml/sax/ContentHandler.java
new file mode 100644
index 0000000..db66c0d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ContentHandler.java
@@ -0,0 +1,419 @@
+// 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.13 2004/04/26 17:50:49 dmegginson Exp $
+
+package 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
+ * @version 2.0.1+ (sax2r3pre1)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/DTDHandler.java b/xml/src/main/java/org/xml/sax/DTDHandler.java
new file mode 100644
index 0000000..13d5eee
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/DTDHandler.java
@@ -0,0 +1,117 @@
+// SAX DTD handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DTDHandler.java,v 1.8 2002/01/30 21:13:43 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/DocumentHandler.java b/xml/src/main/java/org/xml/sax/DocumentHandler.java
new file mode 100644
index 0000000..500fe4c
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/DocumentHandler.java
@@ -0,0 +1,232 @@
+// SAX document handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DocumentHandler.java,v 1.6 2002/01/30 21:13:43 dbrownell Exp $
+
+package org.xml.sax;
+
+/**
+ * Receive notification of general document 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>This was the main event-handling interface for SAX1; in
+ * SAX2, it has been replaced by {@link org.xml.sax.ContentHandler
+ * ContentHandler}, which provides Namespace support and reporting
+ * of skipped entities.  This interface is included in SAX2 only
+ * to support legacy SAX1 applications.</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>Application writers who do not want to implement the entire
+ * interface can derive a class from HandlerBase, which implements
+ * the default functionality; parser writers can instantiate
+ * HandlerBase to obtain a default handler.  The application can find
+ * the location of any document event using the Locator interface
+ * supplied by the Parser through the setDocumentLocator method.</p>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ *             {@link org.xml.sax.ContentHandler ContentHandler}
+ *             interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Parser#setDocumentHandler
+ * @see org.xml.sax.Locator
+ * @see org.xml.sax.HandlerBase
+ */
+public interface DocumentHandler {
+    
+    
+    /**
+     * 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 DocumentHandler
+     * 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 of the events in this interface.  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 abstract 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 methods in this interface or in DTDHandler (except for
+     * setDocumentLocator).</p>
+     *
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public abstract void startDocument ()
+    throws SAXException;
+    
+    
+    /**
+     * Receive notification of the end of a document.
+     *
+     * <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>
+     *
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public abstract void endDocument ()
+    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
+     * 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>If the element name has a namespace prefix, the prefix will
+     * still be attached.  Note that the attribute list provided will
+     * contain only attributes with explicit values (specified or
+     * defaulted): #IMPLIED attributes will be omitted.</p>
+     *
+     * @param name The element type name.
+     * @param atts The attributes attached to the element, if any.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement
+     * @see org.xml.sax.AttributeList 
+     */
+    public abstract void startElement (String name, AttributeList 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
+     * startElement() event for every endElement() event (even when the
+     * element is empty).</p>
+     *
+     * <p>If the element name has a namespace prefix, the prefix will
+     * still be attached to the name.</p>
+     *
+     * @param name The element type name
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public abstract void endElement (String name)
+    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>Note that some parsers will report whitespace using the
+     * ignorableWhitespace() method rather than this one (validating
+     * parsers must 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.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #ignorableWhitespace 
+     * @see org.xml.sax.Locator
+     */
+    public abstract 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 ignorable whitespace (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.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #characters
+     */
+    public abstract 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 should 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>
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if
+     *        none was supplied.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public abstract void processingInstruction (String target, String data)
+    throws SAXException;
+    
+}
+
+// end of DocumentHandler.java
diff --git a/xml/src/main/java/org/xml/sax/EntityResolver.java b/xml/src/main/java/org/xml/sax/EntityResolver.java
new file mode 100644
index 0000000..06ac725
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/EntityResolver.java
@@ -0,0 +1,119 @@
+// SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver.java,v 1.10 2002/01/30 21:13:44 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/ErrorHandler.java b/xml/src/main/java/org/xml/sax/ErrorHandler.java
new file mode 100644
index 0000000..e4e4206
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ErrorHandler.java
@@ -0,0 +1,139 @@
+// SAX error handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ErrorHandler.java,v 1.10 2004/03/08 13:01:00 dmegginson Exp $
+
+package 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
+ * @version 2.0.1+ (sax2r3pre1)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/HandlerBase.java b/xml/src/main/java/org/xml/sax/HandlerBase.java
new file mode 100644
index 0000000..15ea2d4
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/HandlerBase.java
@@ -0,0 +1,369 @@
+// SAX default handler base class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: HandlerBase.java,v 1.7 2004/04/26 17:34:34 dmegginson Exp $
+
+package org.xml.sax;
+
+/**
+ * Default base class for 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 implements the default behaviour for four SAX1
+ * interfaces: EntityResolver, DTDHandler, DocumentHandler,
+ * and ErrorHandler.  It is now obsolete, but is included in SAX2 to
+ * support legacy SAX1 applications.  SAX2 applications should use
+ * the {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
+ * class instead.</p>
+ *
+ * <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>Note that the use of this class is optional.</p>
+ *
+ * @deprecated This class works with the deprecated
+ *             {@link org.xml.sax.DocumentHandler DocumentHandler}
+ *             interface.  It has been replaced by the SAX2
+ *             {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
+ *             class.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.DocumentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class HandlerBase
+    implements EntityResolver, DTDHandler, DocumentHandler, 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 identifer, 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 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 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.
+     * @see org.xml.sax.DTDHandler#notationDecl
+     */
+    public void notationDecl (String name, String publicId, String systemId)
+    {
+    // 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.
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public void unparsedEntityDecl (String name, String publicId,
+                    String systemId, String notationName)
+    {
+    // no op
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Default implementation of DocumentHandler 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.DocumentHandler#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.DocumentHandler#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 beginning
+     * 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.DocumentHandler#endDocument
+     */
+    public void endDocument ()
+    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 name The element type name.
+     * @param attributes The specified or defaulted attributes.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.DocumentHandler#startElement
+     */
+    public void startElement (String name, AttributeList 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 name the element name
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see org.xml.sax.DocumentHandler#endElement
+     */
+    public void endElement (String name)
+    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.DocumentHandler#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.DocumentHandler#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.DocumentHandler#processingInstruction
+     */
+    public void processingInstruction (String target, String data)
+    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 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 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 HandlerBase.java
diff --git a/xml/src/main/java/org/xml/sax/InputSource.java b/xml/src/main/java/org/xml/sax/InputSource.java
new file mode 100644
index 0000000..b1342ee
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/InputSource.java
@@ -0,0 +1,337 @@
+// SAX input source.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: InputSource.java,v 1.9 2002/01/30 21:13:45 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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>
+     *
+     * @param characterStream The raw character stream containing the document.
+     * @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
diff --git a/xml/src/main/java/org/xml/sax/Locator.java b/xml/src/main/java/org/xml/sax/Locator.java
new file mode 100644
index 0000000..f8f3484
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Locator.java
@@ -0,0 +1,136 @@
+// SAX locator interface for document events.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Locator.java,v 1.8 2002/01/30 21:13:47 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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
diff --git a/xml/src/main/java/org/xml/sax/Parser.java b/xml/src/main/java/org/xml/sax/Parser.java
new file mode 100644
index 0000000..67a5512
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Parser.java
@@ -0,0 +1,209 @@
+// SAX parser interface.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Parser.java,v 1.6 2002/01/30 21:13:47 dbrownell Exp $
+
+package org.xml.sax;
+
+import java.io.IOException;
+import java.util.Locale;
+
+
+/**
+ * Basic interface for SAX (Simple API for XML) parsers.
+ *
+ * <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 was the main event supplier interface for SAX1; it has
+ * been replaced in SAX2 by {@link org.xml.sax.XMLReader XMLReader},
+ * which includes Namespace support and sophisticated configurability
+ * and extensibility.</p>
+ *
+ * <p>All SAX1 parsers must implement this basic interface: it allows
+ * applications to register handlers for different types of events
+ * and to initiate a parse from a URI, or a character stream.</p>
+ *
+ * <p>All SAX1 parsers must also implement a zero-argument constructor
+ * (though other constructors are also allowed).</p>
+ *
+ * <p>SAX1 parsers are reusable but not re-entrant: the application
+ * may reuse a parser object (possibly with a different input source)
+ * once the first parse has completed successfully, but it may not
+ * invoke the parse() methods recursively within a parse.</p>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ *             {@link org.xml.sax.XMLReader XMLReader}
+ *             interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.DocumentHandler
+ * @see org.xml.sax.ErrorHandler
+ * @see org.xml.sax.HandlerBase
+ * @see org.xml.sax.InputSource
+ */
+public interface Parser 
+{
+    
+    /**
+     * Allow an application to request a locale for errors and warnings.
+     *
+     * <p>SAX parsers are not required to provide localisation for errors
+     * and warnings; if they cannot support the requested locale,
+     * however, they must throw a SAX exception.  Applications may
+     * not request a locale change in the middle of a parse.</p>
+     *
+     * @param locale A Java Locale object.
+     * @exception org.xml.sax.SAXException Throws an exception
+     *            (using the previous or default locale) if the 
+     *            requested locale is not supported.
+     * @see org.xml.sax.SAXException
+     * @see org.xml.sax.SAXParseException
+     */
+    public abstract void setLocale (Locale locale)
+    throws SAXException;
+    
+    
+    /**
+     * Allow an application to register a custom entity resolver.
+     *
+     * <p>If the application does not register an entity resolver, the
+     * SAX parser will resolve system identifiers and open connections
+     * to entities itself (this is the default behaviour implemented in
+     * HandlerBase).</p>
+     *
+     * <p>Applications may register a new or different entity resolver
+     * in the middle of a parse, and the SAX parser must begin using
+     * the new resolver immediately.</p>
+     *
+     * @param resolver The object for resolving entities.
+     * @see EntityResolver
+     * @see HandlerBase
+     */
+    public abstract void setEntityResolver (EntityResolver resolver);
+    
+    
+    /**
+     * 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 (this is the default behaviour implemented by
+     * HandlerBase).</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 DTDHandler
+     * @see HandlerBase
+     */
+    public abstract void setDTDHandler (DTDHandler handler);
+    
+    
+    /**
+     * Allow an application to register a document event handler.
+     *
+     * <p>If the application does not register a document handler, all
+     * document events reported by the SAX parser will be silently
+     * ignored (this is the default behaviour implemented by
+     * HandlerBase).</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 document handler.
+     * @see DocumentHandler
+     * @see HandlerBase
+     */
+    public abstract void setDocumentHandler (DocumentHandler handler);
+    
+    
+    /**
+     * Allow an application to register an error event handler.
+     *
+     * <p>If the application does not register an error event handler,
+     * all error events reported by the SAX parser will be silently
+     * ignored, except for fatalError, which will throw a SAXException
+     * (this is the default behaviour implemented by HandlerBase).</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 ErrorHandler
+     * @see SAXException
+     * @see HandlerBase
+     */
+    public abstract void setErrorHandler (ErrorHandler handler);
+    
+    
+    /**
+     * Parse an XML document.
+     *
+     * <p>The application can use this method to instruct the SAX parser
+     * 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 Parser instead for each
+     * additional XML document).  Once a parse is complete, an
+     * application may reuse the same Parser object, possibly with a
+     * different input source.</p>
+     *
+     * @param source 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 #setDocumentHandler
+     * @see #setErrorHandler
+     */
+    public abstract void parse (InputSource source)
+    throws SAXException, IOException;
+    
+    
+    /**
+     * 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 abstract void parse (String systemId)
+    throws SAXException, IOException;
+    
+}
+
+// end of Parser.java
diff --git a/xml/src/main/java/org/xml/sax/SAXException.java b/xml/src/main/java/org/xml/sax/SAXException.java
new file mode 100644
index 0000000..2e5b4cd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXException.java
@@ -0,0 +1,153 @@
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXException.java,v 1.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package 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;
+    }
+
+
+    /**
+     * Override toString to pick up any embedded exception.
+     *
+     * @return A string representation of this exception.
+     */
+    public String toString ()
+    {
+    if (exception != null) {
+        return exception.toString();
+    } else {
+        return super.toString();
+    }
+    }
+    
+    
+    
+    //////////////////////////////////////////////////////////////////////
+    // Internal state.
+    //////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * @serial The embedded exception if tunnelling, or null.
+     */    
+    private Exception exception;
+    
+}
+
+// end of SAXException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java b/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java
new file mode 100644
index 0000000..69ba807
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java
@@ -0,0 +1,53 @@
+// 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.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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);
+    }
+
+}
+
+// end of SAXNotRecognizedException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java b/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java
new file mode 100644
index 0000000..bd5b239
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java
@@ -0,0 +1,53 @@
+// 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.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package 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
+ * @version 2.0.1 (sax2r2)
+ * @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);
+    }
+
+}
+
+// end of SAXNotSupportedException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXParseException.java b/xml/src/main/java/org/xml/sax/SAXParseException.java
new file mode 100644
index 0000000..a6a93e9
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXParseException.java
@@ -0,0 +1,269 @@
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXParseException.java,v 1.11 2004/04/21 13:05:02 dmegginson Exp $
+
+package 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;
+    }
+    
+    
+    //////////////////////////////////////////////////////////////////////
+    // 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;
+    
+}
+
+// end of SAXParseException.java
diff --git a/xml/src/main/java/org/xml/sax/XMLFilter.java b/xml/src/main/java/org/xml/sax/XMLFilter.java
new file mode 100644
index 0000000..5a399fa
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/XMLFilter.java
@@ -0,0 +1,65 @@
+// XMLFilter.java - filter SAX2 events.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: XMLFilter.java,v 1.6 2002/01/30 21:13:48 dbrownell Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Interface for an XML filter.
+ *
+ * <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 XML filter is like an XML reader, except that it obtains its
+ * events from another XML reader rather than a primary source like
+ * an XML document or database.  Filters can modify a stream of
+ * events as they pass on to the final application.</p>
+ *
+ * <p>The XMLFilterImpl helper class provides a convenient base
+ * for creating SAX2 filters, by passing on all {@link org.xml.sax.EntityResolver
+ * EntityResolver}, {@link org.xml.sax.DTDHandler DTDHandler},
+ * {@link org.xml.sax.ContentHandler ContentHandler} and {@link org.xml.sax.ErrorHandler
+ * ErrorHandler} events automatically.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.helpers.XMLFilterImpl
+ */
+public interface XMLFilter extends XMLReader
+{
+
+    /**
+     * Set the parent reader.
+     *
+     * <p>This method allows the application to link the filter to
+     * a parent reader (which may be another filter).  The argument
+     * may not be null.</p>
+     *
+     * @param parent The parent reader.
+     */
+    public abstract void setParent (XMLReader parent);
+
+
+    /**
+     * Get the parent reader.
+     *
+     * <p>This method allows the application to query the parent
+     * reader (which may be another filter).  It is generally a
+     * bad idea to perform any operations on the parent reader
+     * directly: they should all pass through this filter.</p>
+     *
+     * @return The parent filter, or null if none has been set.
+     */
+    public abstract XMLReader getParent ();
+
+}
+
+// end of XMLFilter.java
diff --git a/xml/src/main/java/org/xml/sax/XMLReader.java b/xml/src/main/java/org/xml/sax/XMLReader.java
new file mode 100644
index 0000000..d58a4bd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/XMLReader.java
@@ -0,0 +1,404 @@
+// 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.9 2004/04/26 17:34:34 dmegginson Exp $
+
+package 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
+ * @version 2.0.1+ (sax2r3pre1)
+ * @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;
+
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Attributes2.java b/xml/src/main/java/org/xml/sax/ext/Attributes2.java
new file mode 100644
index 0000000..45cd551
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Attributes2.java
@@ -0,0 +1,132 @@
+// Attributes2.java - extended Attributes
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Attributes2.java,v 1.6 2004/03/08 13:01:00 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Attributes;
+
+
+/**
+ * SAX2 extension to augment the per-attribute information
+ * provided though {@link Attributes}.
+ * If an implementation supports this extension, the attributes
+ * provided in {@link org.xml.sax.ContentHandler#startElement
+ * ContentHandler.startElement() } will implement this interface,
+ * and the <em>http://xml.org/sax/features/use-attributes2</em>
+ * feature flag will have the value <em>true</em>.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> XMLReader implementations are not required to support this
+ * information, and it is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>Note that if an attribute was defaulted (<em>!isSpecified()</em>)
+ * it will of necessity also have been declared (<em>isDeclared()</em>)
+ * in the DTD.
+ * Similarly if an attribute's type is anything except CDATA, then it
+ * must have been declared.
+ * </p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public interface Attributes2 extends Attributes
+{
+    /**
+     * 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);
+
+    /**
+     * 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);
+
+    /**
+     * 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);
+
+    /**
+     * 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);
+
+    /**
+     * 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);
+
+    /**
+     * 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);
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java b/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java
new file mode 100644
index 0000000..fc36805
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java
@@ -0,0 +1,320 @@
+// Attributes2Impl.java - extended AttributesImpl
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Attributes2Impl.java,v 1.5 2004/03/08 13:01:01 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+
+/**
+ * SAX2 extension helper for additional Attributes information,
+ * implementing the {@link Attributes2} interface.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p>This is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>The <em>specified</em> flag for each attribute will always
+ * be true, unless it has been set to false in the copy constructor
+ * or using {@link #setSpecified}.
+ * Similarly, the <em>declared</em> flag for each attribute will
+ * always be false, except for defaulted attributes (<em>specified</em>
+ * is false), non-CDATA attributes, or when it is set to true using
+ * {@link #setDeclared}.
+ * If you change an attribute's type by hand, you may need to modify
+ * its <em>declared</em> flag to match. 
+ * </p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public class Attributes2Impl extends AttributesImpl implements Attributes2
+{
+    private boolean    declared [];
+    private boolean    specified [];
+
+
+    /**
+     * Construct a new, empty Attributes2Impl object.
+     */
+    public Attributes2Impl () {
+        // BEGIN android-added
+        declared = new boolean[0];
+        specified = new boolean[0];
+        // END android-added
+    }
+
+
+    /**
+     * Copy an existing Attributes or Attributes2 object.
+     * If the object implements Attributes2, values of the
+     * <em>specified</em> and <em>declared</em> flags for each
+     * attribute are copied.
+     * Otherwise the flag values are defaulted to assume no DTD was used,
+     * unless there is evidence to the contrary (such as attributes with
+     * type other than CDATA, which must have been <em>declared</em>).
+     *
+     * <p>This constructor is especially useful inside a
+     * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
+     *
+     * @param atts The existing Attributes object.
+     */
+    public Attributes2Impl (Attributes atts)
+    {
+    super (atts);
+    }
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of Attributes2
+    ////////////////////////////////////////////////////////////////////
+
+
+    /*
+     * Returns the current value of the attribute's "declared" flag.
+     */
+    // javadoc mostly from interface
+    public boolean isDeclared (int index)
+    {
+    if (index < 0 || index >= getLength ())
+        throw new ArrayIndexOutOfBoundsException (
+        "No attribute at index: " + index);
+    return declared [index];
+    }
+
+
+    /*
+     * Returns the current value of the attribute's "declared" flag.
+     */
+    // javadoc mostly from interface
+    public boolean isDeclared (String uri, String localName)
+    {
+    int index = getIndex (uri, localName);
+
+    if (index < 0)
+        throw new IllegalArgumentException (
+        "No such attribute: local=" + localName
+        + ", namespace=" + uri);
+    return declared [index];
+    }
+
+
+    /*
+     * Returns the current value of the attribute's "declared" flag.
+     */
+    // javadoc mostly from interface
+    public boolean isDeclared (String qName)
+    {
+    int index = getIndex (qName);
+
+    if (index < 0)
+        throw new IllegalArgumentException (
+        "No such attribute: " + qName);
+    return declared [index];
+    }
+
+
+    /**
+     * Returns the current value of an attribute's "specified" flag.
+     *
+     * @param index The attribute index (zero-based).
+     * @return current flag value
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not identify an attribute.
+     */
+    public boolean isSpecified (int index)
+    {
+    if (index < 0 || index >= getLength ())
+        throw new ArrayIndexOutOfBoundsException (
+        "No attribute at index: " + index);
+    return specified [index];
+    }
+
+
+    /**
+     * Returns the current value of an attribute's "specified" flag.
+     *
+     * @param uri The Namespace URI, or the empty string if
+     *        the name has no Namespace URI.
+     * @param localName The attribute's local name.
+     * @return current flag value
+     * @exception java.lang.IllegalArgumentException When the
+     *            supplied names do not identify an attribute.
+     */
+    public boolean isSpecified (String uri, String localName)
+    {
+    int index = getIndex (uri, localName);
+
+    if (index < 0)
+        throw new IllegalArgumentException (
+        "No such attribute: local=" + localName
+        + ", namespace=" + uri);
+    return specified [index];
+    }
+
+
+    /**
+     * Returns the current value of an attribute's "specified" flag.
+     *
+     * @param qName The XML qualified (prefixed) name.
+     * @return current flag value
+     * @exception java.lang.IllegalArgumentException When the
+     *            supplied name does not identify an attribute.
+     */
+    public boolean isSpecified (String qName)
+    {
+    int index = getIndex (qName);
+
+    if (index < 0)
+        throw new IllegalArgumentException (
+        "No such attribute: " + qName);
+    return specified [index];
+    }
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Manipulators
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Copy an entire Attributes object.  The "specified" flags are
+     * assigned as true, and "declared" flags as false (except when
+     * an attribute's type is not CDATA),
+     * unless the object is an Attributes2 object.
+     * In that case those flag values are all copied.
+     *
+     * @param atts The attributes to copy.
+     * 
+     * @see AttributesImpl#setAttributes
+     */
+    public void setAttributes (Attributes atts)
+    {
+    int length = atts.getLength ();
+
+    super.setAttributes (atts);
+    declared = new boolean [length];
+    specified = new boolean [length];
+
+    if (atts instanceof Attributes2) {
+        Attributes2    a2 = (Attributes2) atts;
+        for (int i = 0; i < length; i++) {
+        declared [i] = a2.isDeclared (i);
+        specified [i] = a2.isSpecified (i);
+        }
+    } else {
+        for (int i = 0; i < length; i++) {
+        declared [i] = !"CDATA".equals (atts.getType (i));
+        specified [i] = true;
+        }
+    }
+    }
+
+
+    /**
+     * Add an attribute to the end of the list, setting its
+     * "specified" flag to true.  To set that flag's value
+     * to false, use {@link #setSpecified}.
+     *
+     * <p>Unless the attribute <em>type</em> is CDATA, this attribute
+     * is marked as being declared in the DTD.  To set that flag's value
+     * to true for CDATA attributes, use {@link #setDeclared}.
+     *
+     * @param uri The Namespace URI, or the empty string if
+     *        none is available or Namespace processing is not
+     *        being performed.
+     * @param localName The local name, or the empty string if
+     *        Namespace processing is not being performed.
+     * @param qName The qualified (prefixed) name, or the empty string
+     *        if qualified names are not available.
+     * @param type The attribute type as a string.
+     * @param value The attribute value.
+     * 
+     * @see AttributesImpl#addAttribute
+     */
+    public void addAttribute (String uri, String localName, String qName,
+                  String type, String value)
+    {
+    super.addAttribute (uri, localName, qName, type, value);
+
+    int length = getLength ();
+
+    // BEGIN android-changed
+    if (length > specified.length) {
+    // END android-changed
+        boolean    newFlags [];
+
+        newFlags = new boolean [length];
+        System.arraycopy (declared, 0, newFlags, 0, declared.length);
+        declared = newFlags;
+
+        newFlags = new boolean [length];
+        System.arraycopy (specified, 0, newFlags, 0, specified.length);
+        specified = newFlags;
+    }
+
+    specified [length - 1] = true;
+    declared [length - 1] = !"CDATA".equals (type);
+    }
+
+
+    // javadoc entirely from superclass
+    public void removeAttribute (int index)
+    {
+    int origMax = getLength () - 1;
+
+    super.removeAttribute (index);
+    if (index != origMax) {
+        System.arraycopy (declared, index + 1, declared, index,
+            origMax - index);
+        System.arraycopy (specified, index + 1, specified, index,
+            origMax - index);
+    }
+    }
+
+
+    /**
+     * Assign a value to the "declared" flag of a specific attribute.
+     * This is normally needed only for attributes of type CDATA,
+     * including attributes whose type is changed to or from CDATA.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param value The desired flag value.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not identify an attribute.
+     * @see #setType
+     */
+    public void setDeclared (int index, boolean value)
+    {
+    if (index < 0 || index >= getLength ())
+        throw new ArrayIndexOutOfBoundsException (
+        "No attribute at index: " + index);
+    declared [index] = value;
+    }
+
+
+    /**
+     * Assign a value to the "specified" flag of a specific attribute.
+     * This is the only way this flag can be cleared, except clearing
+     * by initialization with the copy constructor.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param value The desired flag value.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not identify an attribute.
+     */
+    public void setSpecified (int index, boolean value)
+    {
+    if (index < 0 || index >= getLength ())
+        throw new ArrayIndexOutOfBoundsException (
+        "No attribute at index: " + index);
+    specified [index] = value;
+    }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/DeclHandler.java b/xml/src/main/java/org/xml/sax/ext/DeclHandler.java
new file mode 100644
index 0000000..26471f3
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/DeclHandler.java
@@ -0,0 +1,146 @@
+// DeclHandler.java - Optional handler for DTD declaration events.
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: DeclHandler.java,v 1.6 2004/04/22 13:28:49 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.SAXException;
+
+
+/**
+ * SAX2 extension handler for DTD declaration 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>This is an optional extension handler for SAX2 to provide more
+ * complete information about DTD declarations in an XML document.
+ * XML readers are not required to recognize this handler, and it
+ * is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>Note that data-related DTD declarations (unparsed entities and
+ * notations) are already reported through the {@link
+ * org.xml.sax.DTDHandler DTDHandler} interface.</p>
+ *
+ * <p>If you are using the declaration handler together with a lexical
+ * handler, all of the events will occur between the
+ * {@link org.xml.sax.ext.LexicalHandler#startDTD startDTD} and the
+ * {@link org.xml.sax.ext.LexicalHandler#endDTD endDTD} events.</p>
+ *
+ * <p>To set the DeclHandler for an XML reader, use the
+ * {@link org.xml.sax.XMLReader#setProperty setProperty} method
+ * with the property name
+ * <code>http://xml.org/sax/properties/declaration-handler</code>
+ * and an object implementing this interface (or null) as the value.
+ * If the reader does not report declaration events, it will throw a
+ * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
+ * when you attempt to register the handler.</p>
+ *
+ * @since SAX 2.0 (extensions 1.0)
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public interface DeclHandler
+{
+
+    /**
+     * Report an element type declaration.
+     *
+     * <p>The content model will consist of the string "EMPTY", the
+     * string "ANY", or a parenthesised group, optionally followed
+     * by an occurrence indicator.  The model will be normalized so
+     * that all parameter entities are fully resolved and all whitespace 
+     * is removed,and will include the enclosing parentheses.  Other
+     * normalization (such as removing redundant parentheses or 
+     * simplifying occurrence indicators) is at the discretion of the
+     * parser.</p>
+     *
+     * @param name The element type name.
+     * @param model The content model as a normalized string.
+     * @exception SAXException The application may raise an exception.
+     */
+    public abstract void elementDecl (String name, String model)
+    throws SAXException;
+
+
+    /**
+     * Report an attribute type declaration.
+     *
+     * <p>Only the effective (first) declaration for an attribute will
+     * be reported.  The type will be one of the strings "CDATA",
+     * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+     * "ENTITIES", a parenthesized token group with 
+     * the separator "|" and all whitespace removed, or the word
+     * "NOTATION" followed by a space followed by a parenthesized
+     * token group with all whitespace removed.</p>
+     *
+     * <p>The value will be the value as reported to applications,
+     * appropriately normalized and with entity and character
+     * references expanded.  </p>
+     *
+     * @param eName The name of the associated element.
+     * @param aName The name of the attribute.
+     * @param type A string representing the attribute type.
+     * @param mode A string representing the attribute defaulting mode
+     *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+     *        none of these applies.
+     * @param value A string representing the attribute's default value,
+     *        or null if there is none.
+     * @exception SAXException The application may raise an exception.
+     */
+    public abstract void attributeDecl (String eName,
+                    String aName,
+                    String type,
+                    String mode,
+                    String value)
+    throws SAXException;
+
+
+    /**
+     * Report an internal entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.  All parameter entities in the value
+     * will be expanded, but general entities will not.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param value The replacement text of the entity.
+     * @exception SAXException The application may raise an exception.
+     * @see #externalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public abstract void internalEntityDecl (String name, String value)
+    throws SAXException;
+
+
+    /**
+     * Report a parsed external entity declaration.
+     *
+     * <p>Only the effective (first) declaration for each entity
+     * will be reported.</p>
+     *
+     * <p>If the system identifier is a URL, the parser must resolve it
+     * fully before passing it to the application.</p>
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%'.
+     * @param publicId The entity's public identifier, or null if none
+     *        was given.
+     * @param systemId The entity's system identifier.
+     * @exception SAXException The application may raise an exception.
+     * @see #internalEntityDecl
+     * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+     */
+    public abstract void externalEntityDecl (String name, String publicId,
+                         String systemId)
+    throws SAXException;
+
+}
+
+// end of DeclHandler.java
diff --git a/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java b/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java
new file mode 100644
index 0000000..f26564f
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java
@@ -0,0 +1,185 @@
+// DefaultHandler2.java - extended DefaultHandler
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: DefaultHandler2.java,v 1.3 2002/01/12 19:04:19 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import java.io.IOException;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * This class extends the SAX2 base handler class to support the
+ * SAX2 {@link LexicalHandler}, {@link DeclHandler}, and
+ * {@link EntityResolver2} extensions.  Except for overriding the
+ * original SAX1 {@link DefaultHandler#resolveEntity resolveEntity()}
+ * method the added handler methods just return.  Subclassers may
+ * override everything on a method-by-method basis.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> <em>Note:</em> this class might yet learn that the
+ * <em>ContentHandler.setDocumentLocator()</em> call might be passed a
+ * {@link Locator2} object, and that the
+ * <em>ContentHandler.startElement()</em> call might be passed a
+ * {@link Attributes2} object.
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public class DefaultHandler2 extends DefaultHandler
+    implements LexicalHandler, DeclHandler, EntityResolver2
+{
+    /** Constructs a handler which ignores all parsing events. */
+    public DefaultHandler2 () { }
+
+
+    // SAX2 ext-1.0 LexicalHandler
+
+    public void startCDATA ()
+    throws SAXException
+    {}
+
+    public void endCDATA ()
+    throws SAXException
+    {}
+
+    public void startDTD (String name, String publicId, String systemId)
+    throws SAXException
+    {}
+
+    public void endDTD ()
+    throws SAXException
+    {}
+
+    public void startEntity (String name)
+    throws SAXException
+    {}
+
+    public void endEntity (String name)
+    throws SAXException
+    {}
+
+    public void comment (char ch [], int start, int length)
+    throws SAXException
+    { }
+
+
+    // SAX2 ext-1.0 DeclHandler
+
+    public void attributeDecl (String eName, String aName,
+        String type, String mode, String value)
+    throws SAXException
+    {}
+
+    public void elementDecl (String name, String model)
+    throws SAXException
+    {}
+
+    public void externalEntityDecl (String name,
+        String publicId, String systemId)
+    throws SAXException
+    {}
+
+    public void internalEntityDecl (String name, String value)
+    throws SAXException
+    {}
+
+    // SAX2 ext-1.1 EntityResolver2
+
+    /**
+     * Tells the parser that if no external subset has been declared
+     * in the document text, none should be used.
+     * 
+     * @param name Identifies the document root element.  This name comes
+     *    from a DOCTYPE declaration (where available) or from the actual
+     *    root element. The parameter is ignored.
+     * @param baseURI The document's base URI, serving as an additional
+     *    hint for selecting the external subset.  This is always an absolute
+     *    URI, unless it is null because the XMLReader was given an InputSource
+     *    without one. The parameter is ignored.
+     *    
+     * @return null (always).
+     * 
+     * @exception SAXException Any SAX exception, possibly wrapping
+     *    another exception.
+     * @exception IOException Probably indicating a failure to create
+     *    a new InputStream or Reader, or an illegal URL.
+     */
+    public InputSource getExternalSubset (String name, String baseURI)
+    throws SAXException, IOException
+    { return null; }
+
+    /**
+     * Tells the parser to resolve the systemId against the baseURI
+     * and read the entity text from that resulting absolute URI.
+     * Note that because the older
+     * {@link DefaultHandler#resolveEntity DefaultHandler.resolveEntity()},
+     * method is overridden to call this one, this method may sometimes 
+     * be invoked with null <em>name</em> and <em>baseURI</em>, and
+     * with the <em>systemId</em> already absolutized.
+     * 
+     * @param name Identifies the external entity being resolved.
+     *    Either "[dtd]" for the external subset, or a name starting
+     *    with "%" to indicate a parameter entity, or else the name of
+     *    a general entity.  This is never null when invoked by a SAX2
+     *    parser.
+     * @param publicId The public identifier of the external entity being
+     *    referenced (normalized as required by the XML specification), or
+     *    null if none was supplied.
+     * @param baseURI The URI with respect to which relative systemIDs
+     *    are interpreted.  This is always an absolute URI, unless it is
+     *    null (likely because the XMLReader was given an InputSource without
+     *  one).  This URI is defined by the XML specification to be the one
+     *    associated with the "&lt;" starting the relevant declaration.
+     * @param systemId The system identifier of the external entity
+     *    being referenced; either a relative or absolute URI.
+     *  This is never null when invoked by a SAX2 parser; only declared
+     *    entities, and any external subset, are resolved by such parsers.
+     *
+     * @return An InputSource object describing the new input source.
+     * 
+     * @exception SAXException Any SAX exception, possibly wrapping
+     *    another exception.
+     * @exception IOException Probably indicating a failure to create
+     *    a new InputStream or Reader, or an illegal URL.
+     */
+    public InputSource resolveEntity (String name, String publicId,
+        String baseURI, String systemId)
+    throws SAXException, IOException
+    { return null; }
+    
+    // SAX1 EntityResolver
+
+    /**
+     * Invokes
+     * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()}
+     * with null entity name and base URI.
+     * You only need to override that method to use this class.
+     * 
+     * @param publicId The public identifier of the external entity being
+     *    referenced (normalized as required by the XML specification), or
+     *    null if none was supplied.
+     * @param systemId The system identifier of the external entity
+     *    being referenced; either a relative or absolute URI.
+     *  This is never null when invoked by a SAX2 parser; only declared
+     *    entities, and any external subset, are resolved by such parsers.
+     *
+     * @return An InputSource object describing the new input source.
+     * 
+     * @exception SAXException Any SAX exception, possibly wrapping
+     *    another exception.
+     * @exception IOException Probably indicating a failure to create
+     *    a new InputStream or Reader, or an illegal URL.
+     */
+    public InputSource resolveEntity (String publicId, String systemId)
+    throws SAXException, IOException
+    { return resolveEntity (null, publicId, null, systemId); }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java b/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java
new file mode 100644
index 0000000..5437a9b
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java
@@ -0,0 +1,197 @@
+// EntityResolver2.java - Extended SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver2.java,v 1.2 2002/01/12 19:20:08 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import java.io.IOException;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Extended interface for mapping external entity references to input
+ * sources, or providing a missing external subset.  The
+ * {@link XMLReader#setEntityResolver XMLReader.setEntityResolver()} method
+ * is used to provide implementations of this interface to parsers.
+ * When a parser uses the methods in this interface, the
+ * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()}
+ * method (in this interface) is used <em>instead of</em> the older (SAX 1.0)
+ * {@link EntityResolver#resolveEntity EntityResolver.resolveEntity()} method.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p>If a SAX application requires the customized handling which this
+ * interface defines for external entities, it must ensure that it uses
+ * an XMLReader with the
+ * <em>http://xml.org/sax/features/use-entity-resolver2</em> feature flag
+ * set to <em>true</em> (which is its default value when the feature is
+ * recognized).  If that flag is unrecognized, or its value is false,
+ * or the resolver does not implement this interface, then only the
+ * {@link EntityResolver} method will be used.
+ * </p>
+ *
+ * <p>That supports three categories of application that modify entity
+ * resolution.  <em>Old Style</em> applications won't know about this interface;
+ * they will provide an EntityResolver.
+ * <em>Transitional Mode</em> provide an EntityResolver2 and automatically
+ * get the benefit of its methods in any systems (parsers or other tools)
+ * supporting it, due to polymorphism.
+ * Both <em>Old Style</em> and <em>Transitional Mode</em> applications will
+ * work with any SAX2 parser.
+ * <em>New style</em> applications will fail to run except on SAX2 parsers
+ * that support this particular feature.
+ * They will insist that feature flag have a value of "true", and the
+ * EntityResolver2 implementation they provide  might throw an exception
+ * if the original SAX 1.0 style entity resolution method is invoked.
+ * </p>
+ *
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBD
+ */
+public interface EntityResolver2 extends EntityResolver
+{
+    /**
+     * Allows applications to provide an external subset for documents
+     * that don't explicitly define one.  Documents with DOCTYPE declarations
+     * that omit an external subset can thus augment the declarations
+     * available for validation, entity processing, and attribute processing
+     * (normalization, defaulting, and reporting types including ID).
+     * This augmentation is reported
+     * through the {@link LexicalHandler#startDTD startDTD()} method as if
+     * the document text had originally included the external subset;
+     * this callback is made before any internal subset data or errors
+     * are reported.</p>
+     *
+     * <p>This method can also be used with documents that have no DOCTYPE
+     * declaration.  When the root element is encountered,
+     * but no DOCTYPE declaration has been seen, this method is
+     * invoked.  If it returns a value for the external subset, that root
+     * element is declared to be the root element, giving the effect of
+     * splicing a DOCTYPE declaration at the end the prolog of a document
+     * that could not otherwise be valid.  The sequence of parser callbacks
+     * in that case logically resembles this:</p>
+     *
+     * <pre>
+     * ... comments and PIs from the prolog (as usual)
+     * startDTD ("rootName", source.getPublicId (), source.getSystemId ());
+     * startEntity ("[dtd]");
+     * ... declarations, comments, and PIs from the external subset
+     * endEntity ("[dtd]");
+     * endDTD ();
+     * ... then the rest of the document (as usual)
+     * startElement (..., "rootName", ...);
+     * </pre>
+     *
+     * <p>Note that the InputSource gets no further resolution.
+     * Implementations of this method may wish to invoke
+     * {@link #resolveEntity resolveEntity()} to gain benefits such as use
+     * of local caches of DTD entities.  Also, this method will never be
+     * used by a (non-validating) processor that is not including external
+     * parameter entities. </p>
+     *
+     * <p>Uses for this method include facilitating data validation when
+     * interoperating with XML processors that would always require
+     * undesirable network accesses for external entities, or which for
+     * other reasons adopt a "no DTDs" policy.
+     * Non-validation motives include forcing documents to include DTDs so
+     * that attributes are handled consistently.
+     * For example, an XPath processor needs to know which attibutes have
+     * type "ID" before it can process a widely used type of reference.</p>
+     * 
+     * <p><strong>Warning:</strong> Returning an external subset modifies
+     * the input document.  By providing definitions for general entities,
+     * it can make a malformed document appear to be well formed.
+     * </p>
+     *
+     * @param name Identifies the document root element.  This name comes
+     *    from a DOCTYPE declaration (where available) or from the actual
+     *    root element. 
+     * @param baseURI The document's base URI, serving as an additional
+     *    hint for selecting the external subset.  This is always an absolute
+     *    URI, unless it is null because the XMLReader was given an InputSource
+     *    without one.
+     *
+     * @return An InputSource object describing the new external subset
+     *    to be used by the parser, or null to indicate that no external
+     *    subset is provided.
+     *
+     * @exception SAXException Any SAX exception, possibly wrapping
+     *    another exception.
+     * @exception IOException Probably indicating a failure to create
+     *    a new InputStream or Reader, or an illegal URL.
+     */
+    public InputSource getExternalSubset (String name, String baseURI)
+    throws SAXException, IOException;
+
+    /**
+     * Allows applications to map references to external entities into input
+     * sources, or tell the parser it should use conventional URI resolution.
+     * This method is only called for external entities which have been
+     * properly declared.
+     * This method provides more flexibility than the {@link EntityResolver}
+     * interface, supporting implementations of more complex catalogue
+     * schemes such as the one defined by the <a href=
+    "http://www.oasis-open.org/committees/entity/spec-2001-08-06.html"
+    >OASIS XML Catalogs</a> specification.</p>
+     *
+     * <p>Parsers configured to use this resolver method will call it
+     * to determine the input source to use for any external entity
+     * being included because of a reference in the XML text.
+     * That excludes the document entity, and any external entity returned
+     * by {@link #getExternalSubset getExternalSubset()}.
+     * When a (non-validating) processor is configured not to include
+     * a class of entities (parameter or general) through use of feature
+     * flags, this method is not invoked for such entities.  </p>
+     *
+     * <p>Note that the entity naming scheme used here is the same one
+     * used in the {@link LexicalHandler}, or in the {@link
+    org.xml.sax.ContentHandler#skippedEntity
+    ContentHandler.skippedEntity()}
+     * method. </p>
+     *
+     * @param name Identifies the external entity being resolved.
+     *    Either "[dtd]" for the external subset, or a name starting
+     *    with "%" to indicate a parameter entity, or else the name of
+     *    a general entity.  This is never null when invoked by a SAX2
+     *    parser.
+     * @param publicId The public identifier of the external entity being
+     *    referenced (normalized as required by the XML specification), or
+     *    null if none was supplied.
+     * @param baseURI The URI with respect to which relative systemIDs
+     *    are interpreted.  This is always an absolute URI, unless it is
+     *    null (likely because the XMLReader was given an InputSource without
+     *  one).  This URI is defined by the XML specification to be the one
+     *    associated with the "&lt;" starting the relevant declaration.
+     * @param systemId The system identifier of the external entity
+     *    being referenced; either a relative or absolute URI.
+     *  This is never null when invoked by a SAX2 parser; only declared
+     *    entities, and any external subset, are resolved by such parsers.
+     *
+     * @return An InputSource object describing the new input source to
+     *    be used by the parser.  Returning null directs the parser to
+     *    resolve the system ID against the base URI and open a connection
+     *    to resulting URI.
+     *
+     * @exception SAXException Any SAX exception, possibly wrapping
+     *    another exception.
+     * @exception IOException Probably indicating a failure to create
+     *    a new InputStream or Reader, or an illegal URL.
+     */
+    public InputSource resolveEntity (
+        String name,
+        String publicId,
+        String baseURI,
+        String systemId
+    ) throws SAXException, IOException;
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java b/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java
new file mode 100644
index 0000000..e551b61
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java
@@ -0,0 +1,212 @@
+// LexicalHandler.java - optional handler for lexical parse events.
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: LexicalHandler.java,v 1.5 2002/01/30 21:00:44 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.SAXException;
+
+/**
+ * SAX2 extension handler for lexical 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>This is an optional extension handler for SAX2 to provide
+ * lexical information about an XML document, such as comments
+ * and CDATA section boundaries.
+ * XML readers are not required to recognize this handler, and it
+ * is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>The events in the lexical handler apply to the entire document,
+ * not just to the document element, and all lexical handler events
+ * must appear between the content handler's startDocument and
+ * endDocument events.</p>
+ *
+ * <p>To set the LexicalHandler for an XML reader, use the
+ * {@link org.xml.sax.XMLReader#setProperty setProperty} method
+ * with the property name
+ * <code>http://xml.org/sax/properties/lexical-handler</code>
+ * and an object implementing this interface (or null) as the value.
+ * If the reader does not report lexical events, it will throw a
+ * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
+ * when you attempt to register the handler.</p>
+ *
+ * @since SAX 2.0 (extensions 1.0)
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public interface LexicalHandler
+{
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * <p>This method is intended to report the beginning of the
+     * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+     * this method will not be invoked.</p>
+     *
+     * <p>All declarations reported through 
+     * {@link org.xml.sax.DTDHandler DTDHandler} or
+     * {@link org.xml.sax.ext.DeclHandler DeclHandler} events must appear
+     * between the startDTD and {@link #endDTD endDTD} events.
+     * Declarations are assumed to belong to the internal DTD subset
+     * unless they appear between {@link #startEntity startEntity}
+     * and {@link #endEntity endEntity} events.  Comments and
+     * processing instructions from the DTD should also be reported
+     * between the startDTD and endDTD events, in their original 
+     * order of (logical) occurrence; they are not required to
+     * appear in their correct locations relative to DTDHandler
+     * or DeclHandler events, however.</p>
+     *
+     * <p>Note that the start/endDTD events will appear within
+     * the start/endDocument events from ContentHandler and
+     * before the first 
+     * {@link org.xml.sax.ContentHandler#startElement startElement}
+     * event.</p>
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the
+     *        external DTD subset, or null if none was declared.
+     * @param systemId The declared system identifier for the
+     *        external DTD subset, or null if none was declared.
+     *        (Note that this is not resolved against the document
+     *        base URI.)
+     * @exception SAXException The application may raise an
+     *            exception.
+     * @see #endDTD
+     * @see #startEntity
+     */
+    public abstract void startDTD (String name, String publicId,
+                   String systemId)
+    throws SAXException;
+
+
+    /**
+     * Report the end of DTD declarations.
+     *
+     * <p>This method is intended to report the end of the
+     * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+     * this method will not be invoked.</p>
+     *
+     * @exception SAXException The application may raise an exception.
+     * @see #startDTD
+     */
+    public abstract void endDTD ()
+    throws SAXException;
+
+
+    /**
+     * Report the beginning of some internal and external XML entities.
+     *
+     * <p>The reporting of parameter entities (including
+     * the external DTD subset) is optional, and SAX2 drivers that
+     * report LexicalHandler events may not implement it; you can use the
+     * <code
+     * >http://xml.org/sax/features/lexical-handler/parameter-entities</code>
+     * feature to query or control the reporting of parameter entities.</p>
+     *
+     * <p>General entities are reported with their regular names,
+     * parameter entities have '%' prepended to their names, and 
+     * the external DTD subset has the pseudo-entity name "[dtd]".</p>
+     *
+     * <p>When a SAX2 driver is providing these events, all other 
+     * events must be properly nested within start/end entity 
+     * events.  There is no additional requirement that events from 
+     * {@link org.xml.sax.ext.DeclHandler DeclHandler} or
+     * {@link org.xml.sax.DTDHandler DTDHandler} be properly ordered.</p>
+     *
+     * <p>Note that skipped entities will be reported through the
+     * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+     * event, which is part of the ContentHandler interface.</p>
+     *
+     * <p>Because of the streaming event model that SAX uses, some
+     * entity boundaries cannot be reported under any 
+     * circumstances:</p>
+     *
+     * <ul>
+     * <li>general entities within attribute values</li>
+     * <li>parameter entities within declarations</li>
+     * </ul>
+     *
+     * <p>These will be silently expanded, with no indication of where
+     * the original entity boundaries were.</p>
+     *
+     * <p>Note also that the boundaries of character references (which
+     * are not really entities anyway) are not reported.</p>
+     *
+     * <p>All start/endEntity events must be properly nested.
+     *
+     * @param name The name of the entity.  If it is a parameter
+     *        entity, the name will begin with '%', and if it is the
+     *        external DTD subset, it will be "[dtd]".
+     * @exception SAXException The application may raise an exception.
+     * @see #endEntity
+     * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+     * @see org.xml.sax.ext.DeclHandler#externalEntityDecl 
+     */
+    public abstract void startEntity (String name)
+    throws SAXException;
+
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     * @exception SAXException The application may raise an exception.
+     * @see #startEntity
+     */
+    public abstract void endEntity (String name)
+    throws SAXException;
+
+
+    /**
+     * Report the start of a CDATA section.
+     *
+     * <p>The contents of the CDATA section will be reported through
+     * the regular {@link org.xml.sax.ContentHandler#characters
+     * characters} event; this event is intended only to report
+     * the boundary.</p>
+     *
+     * @exception SAXException The application may raise an exception.
+     * @see #endCDATA
+     */
+    public abstract void startCDATA ()
+    throws SAXException;
+
+
+    /**
+     * Report the end of a CDATA section.
+     *
+     * @exception SAXException The application may raise an exception.
+     * @see #startCDATA
+     */
+    public abstract void endCDATA ()
+    throws SAXException;
+
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * <p>This callback will be used for comments inside or outside the
+     * document element, including comments in the external DTD
+     * subset (if read).  Comments in the DTD must be properly
+     * nested inside start/endDTD and start/endEntity events (if
+     * used).</p>
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use from the array.
+     * @exception SAXException The application may raise an exception.
+     */
+    public abstract void comment (char ch[], int start, int length)
+    throws SAXException;
+
+}
+
+// end of LexicalHandler.java
diff --git a/xml/src/main/java/org/xml/sax/ext/Locator2.java b/xml/src/main/java/org/xml/sax/ext/Locator2.java
new file mode 100644
index 0000000..6de9a16
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Locator2.java
@@ -0,0 +1,75 @@
+// Locator2.java - extended Locator
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Locator2.java,v 1.5 2004/03/17 14:30:10 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Locator;
+
+
+/**
+ * SAX2 extension to augment the entity information provided 
+ * though a {@link Locator}.
+ * If an implementation supports this extension, the Locator
+ * provided in {@link org.xml.sax.ContentHandler#setDocumentLocator
+ * ContentHandler.setDocumentLocator() } will implement this
+ * interface, and the
+ * <em>http://xml.org/sax/features/use-locator2</em> feature
+ * flag will have the value <em>true</em>.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> XMLReader implementations are not required to support this
+ * information, and it is not part of core-only SAX2 distributions.</p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public interface Locator2 extends Locator
+{
+    /**
+     * Returns the version of XML used for the entity.  This will
+     * normally be the identifier from the current entity's
+     * <em>&lt;?xml&nbsp;version='...'&nbsp;...?&gt;</em> declaration,
+     * or be defaulted by the parser.
+     *
+     * @return Identifier for the XML version being used to interpret
+     * the entity's text, or null if that information is not yet
+     * available in the current parsing state.
+     */
+    public String getXMLVersion ();
+
+    /**
+     * Returns the name of the character encoding for the entity.
+     * If the encoding was declared externally (for example, in a MIME
+     * Content-Type header), that will be the name returned.  Else if there
+     * was an <em>&lt;?xml&nbsp;...encoding='...'?&gt;</em> declaration at
+     * the start of the document, that encoding name will be returned.
+     * Otherwise the encoding will been inferred (normally to be UTF-8, or
+     * some UTF-16 variant), and that inferred name will be returned.
+     *
+     * <p>When an {@link org.xml.sax.InputSource InputSource} is used
+     * to provide an entity's character stream, this method returns the
+     * encoding provided in that input stream.
+     *
+     * <p> Note that some recent W3C specifications require that text
+     * in some encodings be normalized, using Unicode Normalization
+     * Form C, before processing.  Such normalization must be performed
+     * by applications, and would normally be triggered based on the
+     * value returned by this method.
+     *
+     * <p> Encoding names may be those used by the underlying JVM,
+     * and comparisons should be case-insensitive.
+     *
+     * @return Name of the character encoding being used to interpret
+     * * the entity's text, or null if this was not provided for a *
+     * character stream passed through an InputSource or is otherwise
+     * not yet available in the current parsing state.
+     */
+    public String getEncoding ();
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java b/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java
new file mode 100644
index 0000000..91f912a
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java
@@ -0,0 +1,105 @@
+// Locator2Impl.java - extended LocatorImpl
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Locator2Impl.java,v 1.3 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.LocatorImpl;
+
+
+/**
+ * SAX2 extension helper for holding additional Entity information,
+ * implementing the {@link Locator2} interface.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> This is not part of core-only SAX2 distributions.</p>
+ *
+ * @since SAX 2.0.2
+ * @author David Brownell
+ * @version TBS
+ */
+public class Locator2Impl extends LocatorImpl implements Locator2
+{
+    private String    encoding;
+    private String    version;
+
+
+    /**
+     * Construct a new, empty Locator2Impl object.
+     * This will not normally be useful, since the main purpose
+     * of this class is to make a snapshot of an existing Locator.
+     */
+    public Locator2Impl () { }
+
+    /**
+     * Copy an existing Locator or Locator2 object.
+     * If the object implements Locator2, values of the
+     * <em>encoding</em> and <em>version</em>strings are copied,
+     * otherwise they set to <em>null</em>. 
+     *
+     * @param locator The existing Locator object.
+     */
+    public Locator2Impl (Locator locator)
+    {
+    super (locator);
+    if (locator instanceof Locator2) {
+        Locator2    l2 = (Locator2) locator;
+
+        version = l2.getXMLVersion ();
+        encoding = l2.getEncoding ();
+    }
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    // Locator2 method implementations
+    ////////////////////////////////////////////////////////////////////
+    
+    /**
+     * Returns the current value of the version property.
+     *
+     * @return the current value of the version property.
+     *
+     * @see #setXMLVersion
+     */
+    public String getXMLVersion ()
+    { return version; }
+
+    /**
+     * Returns the current value of the encoding property.
+     * 
+     * @return the current value of the encoding property.
+     *
+     * @see #setEncoding
+     */
+    public String getEncoding ()
+    { return encoding; }
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Setters 
+    ////////////////////////////////////////////////////////////////////
+    
+    /**
+     * Assigns the current value of the version property.
+     *
+     * @param version the new "version" value
+     * @see #getXMLVersion
+     */
+    public void setXMLVersion (String version)
+    { this.version = version; }
+
+    /**
+     * Assigns the current value of the encoding property.
+     *
+     * @param encoding the new "encoding" value
+     * @see #getEncoding
+     */
+    public void setEncoding (String encoding)
+    { this.encoding = encoding; }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/package.html b/xml/src/main/java/org/xml/sax/ext/package.html
new file mode 100644
index 0000000..9b79d77
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/package.html
@@ -0,0 +1,48 @@
+<HTML><HEAD>
+<!-- $Id: package.html,v 1.8 2002/01/30 21:00:44 dbrownell Exp $ -->
+</HEAD><BODY>
+
+<p>
+This package contains interfaces to SAX2 facilities that
+conformant SAX drivers won't necessarily support.
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+<p> This package is independent of the SAX2 core, though the functionality
+exposed generally needs to be implemented within a parser core.
+That independence has several consequences:</p>
+
+<ul>
+
+<li>SAX2 drivers are <em>not</em> required to recognize these handlers.
+</li>
+
+<li>You cannot assume that the class files will be present in every SAX2
+installation.</li>
+
+<li>This package may be updated independently of SAX2 (i.e. new
+handlers and classes may be added without updating SAX2 itself).</li>
+
+<li>The new handlers are not implemented by the SAX2
+<code>org.xml.sax.helpers.DefaultHandler</code> or
+<code>org.xml.sax.helpers.XMLFilterImpl</code> classes.
+You can subclass these if you need such behavior, or
+use the helper classes found here.</li>
+
+<li>The handlers need to be registered differently than core SAX2
+handlers.</li>
+
+</ul>
+
+<p>This package, SAX2-ext, is a standardized extension to SAX2.  It is
+designed both to allow SAX parsers to pass certain types of information
+to applications, and to serve as a simple model for other SAX2 parser
+extension packages.  Not all such extension packages should need to
+be recognized directly by parsers, however.
+As an example, most validation systems can be cleanly layered on top
+of parsers supporting the standardized SAX2 interfaces.  </p>
+
+@since Android 1.0
+
+</BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java b/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java
new file mode 100644
index 0000000..fb4aee3
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java
@@ -0,0 +1,314 @@
+// SAX default implementation for AttributeList.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: AttributeListImpl.java,v 1.6 2002/01/30 20:52:22 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.AttributeList;
+
+import java.util.Vector;
+
+
+/**
+ * Default implementation for AttributeList.
+ *
+ * <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>AttributeList implements the deprecated SAX1 {@link
+ * org.xml.sax.AttributeList AttributeList} interface, and has been
+ * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl
+ * AttributesImpl} interface.</p>
+ *
+ * <p>This class provides a convenience implementation of the SAX
+ * {@link org.xml.sax.AttributeList AttributeList} interface.  This 
+ * implementation is useful both for SAX parser writers, who can use 
+ * it to provide attributes to the application, and for SAX application 
+ * writers, who can use it to create a persistent copy of an element's 
+ * attribute specifications:</p>
+ *
+ * <pre>
+ * private AttributeList myatts;
+ *
+ * public void startElement (String name, AttributeList atts)
+ * {
+ *              // create a persistent copy of the attribute list
+ *              // for use outside this method
+ *   myatts = new AttributeListImpl(atts);
+ *   [...]
+ * }
+ * </pre>
+ *
+ * <p>Please note that SAX parsers are not required to use this
+ * class to provide an implementation of AttributeList; it is
+ * supplied only as an optional convenience.  In particular, 
+ * parser writers are encouraged to invent more efficient
+ * implementations.</p>
+ *
+ * @deprecated This class implements a deprecated interface,
+ *             {@link org.xml.sax.AttributeList AttributeList};
+ *             that interface has been replaced by
+ *             {@link org.xml.sax.Attributes Attributes},
+ *             which is implemented in the
+ *             {@link org.xml.sax.helpers.AttributesImpl 
+ *            AttributesImpl} helper class.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.AttributeList
+ * @see org.xml.sax.DocumentHandler#startElement 
+ */
+public class AttributeListImpl implements AttributeList
+{
+    
+    /**
+     * Create an empty attribute list.
+     *
+     * <p>This constructor is most useful for parser writers, who
+     * will use it to create a single, reusable attribute list that
+     * can be reset with the clear method between elements.</p>
+     *
+     * @see #addAttribute
+     * @see #clear
+     */
+    public AttributeListImpl ()
+    {
+    }
+    
+    
+    /**
+     * Construct a persistent copy of an existing attribute list.
+     *
+     * <p>This constructor is most useful for application writers,
+     * who will use it to create a persistent copy of an existing
+     * attribute list.</p>
+     *
+     * @param atts The attribute list to copy
+     * @see org.xml.sax.DocumentHandler#startElement
+     */
+    public AttributeListImpl (AttributeList atts)
+    {
+    setAttributeList(atts);
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Methods specific to this class.
+    ////////////////////////////////////////////////////////////////////
+    
+    
+    /**
+     * Set the attribute list, discarding previous contents.
+     *
+     * <p>This method allows an application writer to reuse an
+     * attribute list easily.</p>
+     *
+     * @param atts The attribute list to copy.
+     */
+    public void setAttributeList (AttributeList atts)
+    {
+    int count = atts.getLength();
+    
+    clear();
+    
+    for (int i = 0; i < count; i++) {
+        addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
+    }
+    }
+    
+    
+    /**
+     * Add an attribute to an attribute list.
+     *
+     * <p>This method is provided for SAX parser writers, to allow them
+     * to build up an attribute list incrementally before delivering
+     * it to the application.</p>
+     *
+     * @param name The attribute name.
+     * @param type The attribute type ("NMTOKEN" for an enumeration).
+     * @param value The attribute value (must not be null).
+     * @see #removeAttribute
+     * @see org.xml.sax.DocumentHandler#startElement
+     */
+    public void addAttribute (String name, String type, String value)
+    {
+    names.addElement(name);
+    types.addElement(type);
+    values.addElement(value);
+    }
+    
+    
+    /**
+     * Remove an attribute from the list.
+     *
+     * <p>SAX application writers can use this method to filter an
+     * attribute out of an AttributeList.  Note that invoking this
+     * method will change the length of the attribute list and
+     * some of the attribute's indices.</p>
+     *
+     * <p>If the requested attribute is not in the list, this is
+     * a no-op.</p>
+     *
+     * @param name The attribute name.
+     * @see #addAttribute
+     */
+    public void removeAttribute (String name)
+    {
+    int i = names.indexOf(name);
+    
+    if (i >= 0) {
+        names.removeElementAt(i);
+        types.removeElementAt(i);
+        values.removeElementAt(i);
+    }
+    }
+    
+    
+    /**
+     * Clear the attribute list.
+     *
+     * <p>SAX parser writers can use this method to reset the attribute
+     * list between DocumentHandler.startElement events.  Normally,
+     * it will make sense to reuse the same AttributeListImpl object
+     * rather than allocating a new one each time.</p>
+     *
+     * @see org.xml.sax.DocumentHandler#startElement
+     */
+    public void clear ()
+    {
+    names.removeAllElements();
+    types.removeAllElements();
+    values.removeAllElements();
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.AttributeList
+    ////////////////////////////////////////////////////////////////////
+    
+    
+    /**
+     * Return the number of attributes in the list.
+     *
+     * @return The number of attributes in the list.
+     * @see org.xml.sax.AttributeList#getLength
+     */
+    public int getLength ()
+    {
+    return names.size();
+    }
+    
+    
+    /**
+     * Get the name of an attribute (by position).
+     *
+     * @param i The position of the attribute in the list.
+     * @return The attribute name as a string, or null if there
+     *         is no attribute at that position.
+     * @see org.xml.sax.AttributeList#getName(int)
+     */
+    public String getName (int i)
+    {
+    if (i < 0) {
+        return null;
+    }
+    try {
+        return (String)names.elementAt(i);
+    } catch (ArrayIndexOutOfBoundsException e) {
+        return null;
+    }
+    }
+    
+    
+    /**
+     * Get the type of an attribute (by position).
+     *
+     * @param i The position of the attribute in the list.
+     * @return The attribute type as a string ("NMTOKEN" for an
+     *         enumeration, and "CDATA" if no declaration was
+     *         read), or null if there is no attribute at
+     *         that position.
+     * @see org.xml.sax.AttributeList#getType(int)
+     */
+    public String getType (int i)
+    {
+    if (i < 0) {
+        return null;
+    }
+    try {
+        return (String)types.elementAt(i);
+    } catch (ArrayIndexOutOfBoundsException e) {
+        return null;
+    }
+    }
+    
+    
+    /**
+     * Get the value of an attribute (by position).
+     *
+     * @param i The position of the attribute in the list.
+     * @return The attribute value as a string, or null if
+     *         there is no attribute at that position.
+     * @see org.xml.sax.AttributeList#getValue(int)
+     */
+    public String getValue (int i)
+    {
+    if (i < 0) {
+        return null;
+    }
+    try {
+        return (String)values.elementAt(i);
+    } catch (ArrayIndexOutOfBoundsException e) {
+        return null;
+    }
+    }
+    
+    
+    /**
+     * Get the type of an attribute (by name).
+     *
+     * @param name The attribute name.
+     * @return The attribute type as a string ("NMTOKEN" for an
+     *         enumeration, and "CDATA" if no declaration was
+     *         read).
+     * @see org.xml.sax.AttributeList#getType(java.lang.String)
+     */
+    public String getType (String name)
+    {
+    return getType(names.indexOf(name));
+    }
+    
+    
+    /**
+     * Get the value of an attribute (by name).
+     *
+     * @param name The attribute name.
+     * @return the named attribute's value or null, if the attribute does not
+     *         exist.
+     * @see org.xml.sax.AttributeList#getValue(java.lang.String)
+     */
+    public String getValue (String name)
+    {
+    return getValue(names.indexOf(name));
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    Vector names = new Vector();
+    Vector types = new Vector();
+    Vector values = new Vector();
+
+}
+
+// end of AttributeListImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java b/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java
new file mode 100644
index 0000000..b740e23
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java
@@ -0,0 +1,618 @@
+// AttributesImpl.java - default implementation of Attributes.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: AttributesImpl.java,v 1.9 2002/01/30 20:52:24 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.Attributes;
+
+
+/**
+ * Default implementation of the Attributes interface.
+ *
+ * <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 provides a default implementation of the SAX2
+ * {@link org.xml.sax.Attributes Attributes} interface, with the 
+ * addition of manipulators so that the list can be modified or 
+ * reused.</p>
+ *
+ * <p>There are two typical uses of this class:</p>
+ *
+ * <ol>
+ * <li>to take a persistent snapshot of an Attributes object
+ *  in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>
+ * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li>
+ * </ol>
+ *
+ * <p>This class replaces the now-deprecated SAX1 {@link 
+ * org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
+ * class; in addition to supporting the updated Attributes
+ * interface rather than the deprecated {@link org.xml.sax.AttributeList
+ * AttributeList} interface, it also includes a much more efficient 
+ * implementation using a single array rather than a set of Vectors.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class AttributesImpl implements Attributes
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructors.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct a new, empty AttributesImpl object.
+     */
+    public AttributesImpl ()
+    {
+    length = 0;
+    data = null;
+    }
+
+
+    /**
+     * Copy an existing Attributes object.
+     *
+     * <p>This constructor is especially useful inside a
+     * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
+     *
+     * @param atts The existing Attributes object.
+     */
+    public AttributesImpl (Attributes atts)
+    {
+    setAttributes(atts);
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.Attributes.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Return the number of attributes in the list.
+     *
+     * @return The number of attributes in the list.
+     * @see org.xml.sax.Attributes#getLength
+     */
+    public int getLength ()
+    {
+    return length;
+    }
+
+
+    /**
+     * Return an attribute's Namespace URI.
+     *
+     * @param index The attribute's index (zero-based).
+     * @return The Namespace URI, the empty string if none is
+     *         available, or null if the index is out of range.
+     * @see org.xml.sax.Attributes#getURI
+     */
+    public String getURI (int index)
+    {
+    if (index >= 0 && index < length) {
+        return data[index*5];
+    } else {
+        return null;
+    }
+    }
+
+
+    /**
+     * Return an attribute's local name.
+     *
+     * @param index The attribute's index (zero-based).
+     * @return The attribute's local name, the empty string if 
+     *         none is available, or null if the index if out of range.
+     * @see org.xml.sax.Attributes#getLocalName
+     */
+    public String getLocalName (int index)
+    {
+    if (index >= 0 && index < length) {
+        return data[index*5+1];
+    } else {
+        return null;
+    }
+    }
+
+
+    /**
+     * Return an attribute's qualified (prefixed) name.
+     *
+     * @param index The attribute's index (zero-based).
+     * @return The attribute's qualified name, the empty string if 
+     *         none is available, or null if the index is out of bounds.
+     * @see org.xml.sax.Attributes#getQName
+     */
+    public String getQName (int index)
+    {
+    if (index >= 0 && index < length) {
+        return data[index*5+2];
+    } else {
+        return null;
+    }
+    }
+
+
+    /**
+     * Return an attribute's type by index.
+     *
+     * @param index The attribute's index (zero-based).
+     * @return The attribute's type, "CDATA" if the type is unknown, or null
+     *         if the index is out of bounds.
+     * @see org.xml.sax.Attributes#getType(int)
+     */
+    public String getType (int index)
+    {
+    if (index >= 0 && index < length) {
+        return data[index*5+3];
+    } else {
+        return null;
+    }
+    }
+
+
+    /**
+     * Return an attribute's value by index.
+     *
+     * @param index The attribute's index (zero-based).
+     * @return The attribute's value or null if the index is out of bounds.
+     * @see org.xml.sax.Attributes#getValue(int)
+     */
+    public String getValue (int index)
+    {
+    if (index >= 0 && index < length) {
+        return data[index*5+4];
+    } else {
+        return null;
+    }
+    }
+
+
+    /**
+     * Look up an attribute's index by Namespace name.
+     *
+     * <p>In many cases, it will be more efficient to look up the name once and
+     * use the index query methods rather than using the name query methods
+     * repeatedly.</p>
+     *
+     * @param uri The attribute's Namespace URI, or the empty
+     *        string if none is available.
+     * @param localName The attribute's local name.
+     * @return The attribute's index, or -1 if none matches.
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
+     */
+    public int getIndex (String uri, String localName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i].equals(uri) && data[i+1].equals(localName)) {
+        return i / 5;
+        }
+    } 
+    return -1;
+    }
+
+
+    /**
+     * Look up an attribute's index by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attribute's index, or -1 if none matches.
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String)
+     */
+    public int getIndex (String qName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i+2].equals(qName)) {
+        return i / 5;
+        }
+    } 
+    return -1;
+    }
+
+
+    /**
+     * Look up an attribute's type by Namespace-qualified name.
+     *
+     * @param uri The Namespace URI, or the empty string for a name
+     *        with no explicit Namespace URI.
+     * @param localName The local name.
+     * @return The attribute's type, or null if there is no
+     *         matching attribute.
+     * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String)
+     */
+    public String getType (String uri, String localName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i].equals(uri) && data[i+1].equals(localName)) {
+        return data[i+3];
+        }
+    } 
+    return null;
+    }
+
+
+    /**
+     * Look up an attribute's type by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attribute's type, or null if there is no
+     *         matching attribute.
+     * @see org.xml.sax.Attributes#getType(java.lang.String)
+     */
+    public String getType (String qName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i+2].equals(qName)) {
+        return data[i+3];
+        }
+    }
+    return null;
+    }
+
+
+    /**
+     * Look up an attribute's value by Namespace-qualified name.
+     *
+     * @param uri The Namespace URI, or the empty string for a name
+     *        with no explicit Namespace URI.
+     * @param localName The local name.
+     * @return The attribute's value, or null if there is no
+     *         matching attribute.
+     * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String)
+     */
+    public String getValue (String uri, String localName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i].equals(uri) && data[i+1].equals(localName)) {
+        return data[i+4];
+        }
+    }
+    return null;
+    }
+
+
+    /**
+     * Look up an attribute's value by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attribute's value, or null if there is no
+     *         matching attribute.
+     * @see org.xml.sax.Attributes#getValue(java.lang.String)
+     */
+    public String getValue (String qName)
+    {
+    int max = length * 5;
+    for (int i = 0; i < max; i += 5) {
+        if (data[i+2].equals(qName)) {
+        return data[i+4];
+        }
+    }
+    return null;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Manipulators.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Clear the attribute list for reuse.
+     *
+     * <p>Note that little memory is freed by this call:
+     * the current array is kept so it can be 
+     * reused.</p>
+     */
+    public void clear ()
+    {
+    if (data != null) {
+        for (int i = 0; i < (length * 5); i++)
+        data [i] = null;
+    }
+    length = 0;
+    }
+
+
+    /**
+     * Copy an entire Attributes object.
+     *
+     * <p>It may be more efficient to reuse an existing object
+     * rather than constantly allocating new ones.</p>
+     * 
+     * @param atts The attributes to copy.
+     */
+    public void setAttributes (Attributes atts)
+    {
+        clear();
+        length = atts.getLength();
+        if (length > 0) {
+            data = new String[length*5];
+            for (int i = 0; i < length; i++) {
+                data[i*5] = atts.getURI(i);
+                data[i*5+1] = atts.getLocalName(i);
+                data[i*5+2] = atts.getQName(i);
+                data[i*5+3] = atts.getType(i);
+                data[i*5+4] = atts.getValue(i);
+            }
+    }
+    }
+
+
+    /**
+     * Add an attribute to the end of the list.
+     *
+     * <p>For the sake of speed, this method does no checking
+     * to see if the attribute is already in the list: that is
+     * the responsibility of the application.</p>
+     *
+     * @param uri The Namespace URI, or the empty string if
+     *        none is available or Namespace processing is not
+     *        being performed.
+     * @param localName The local name, or the empty string if
+     *        Namespace processing is not being performed.
+     * @param qName The qualified (prefixed) name, or the empty string
+     *        if qualified names are not available.
+     * @param type The attribute type as a string.
+     * @param value The attribute value.
+     */
+    public void addAttribute (String uri, String localName, String qName,
+                  String type, String value)
+    {
+    ensureCapacity(length+1);
+    data[length*5] = uri;
+    data[length*5+1] = localName;
+    data[length*5+2] = qName;
+    data[length*5+3] = type;
+    data[length*5+4] = value;
+    length++;
+    }
+
+
+    /**
+     * Set an attribute in the list.
+     *
+     * <p>For the sake of speed, this method does no checking
+     * for name conflicts or well-formedness: such checks are the
+     * responsibility of the application.</p>
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param uri The Namespace URI, or the empty string if
+     *        none is available or Namespace processing is not
+     *        being performed.
+     * @param localName The local name, or the empty string if
+     *        Namespace processing is not being performed.
+     * @param qName The qualified name, or the empty string
+     *        if qualified names are not available.
+     * @param type The attribute type as a string.
+     * @param value The attribute value.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setAttribute (int index, String uri, String localName,
+                  String qName, String type, String value)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5] = uri;
+        data[index*5+1] = localName;
+        data[index*5+2] = qName;
+        data[index*5+3] = type;
+        data[index*5+4] = value;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Remove an attribute from the list.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void removeAttribute (int index)
+    {
+    if (index >= 0 && index < length) {
+        if (index < length - 1) {
+        System.arraycopy(data, (index+1)*5, data, index*5,
+                 (length-index-1)*5);
+        }
+        index = (length - 1) * 5;
+        data [index++] = null;
+        data [index++] = null;
+        data [index++] = null;
+        data [index++] = null;
+        data [index] = null;
+        length--;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Set the Namespace URI of a specific attribute.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param uri The attribute's Namespace URI, or the empty
+     *        string for none.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setURI (int index, String uri)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5] = uri;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Set the local name of a specific attribute.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param localName The attribute's local name, or the empty
+     *        string for none.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setLocalName (int index, String localName)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5+1] = localName;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Set the qualified name of a specific attribute.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param qName The attribute's qualified name, or the empty
+     *        string for none.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setQName (int index, String qName)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5+2] = qName;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Set the type of a specific attribute.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param type The attribute's type.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setType (int index, String type)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5+3] = type;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+    /**
+     * Set the value of a specific attribute.
+     *
+     * @param index The index of the attribute (zero-based).
+     * @param value The attribute's value.
+     * @exception java.lang.ArrayIndexOutOfBoundsException When the
+     *            supplied index does not point to an attribute
+     *            in the list.
+     */
+    public void setValue (int index, String value)
+    {
+    if (index >= 0 && index < length) {
+        data[index*5+4] = value;
+    } else {
+        badIndex(index);
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal methods.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Ensure the internal array's capacity.
+     *
+     * @param n The minimum number of attributes that the array must
+     *        be able to hold.
+     */
+    private void ensureCapacity (int n)    {
+        if (n <= 0) {
+            return;
+        }
+        int max;
+        if (data == null || data.length == 0) {
+            max = 25;
+        }
+        else if (data.length >= n * 5) {
+            return;
+        }
+        else {
+            max = data.length;
+        }
+        while (max < n * 5) {
+            max *= 2;
+        }
+
+        String newData[] = new String[max];
+        if (length > 0) {
+            System.arraycopy(data, 0, newData, 0, length*5);
+        }
+        data = newData;
+    }
+
+
+    /**
+     * Report a bad array index in a manipulator.
+     *
+     * @param index The index to report.
+     * @exception java.lang.ArrayIndexOutOfBoundsException Always.
+     */
+    private void badIndex (int index)
+    throws ArrayIndexOutOfBoundsException
+    {
+    String msg =
+        "Attempt to modify attribute at illegal index: " + index;
+    throw new ArrayIndexOutOfBoundsException(msg);
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    int length;
+    String data [];
+
+}
+
+// end of AttributesImpl.java
+
diff --git a/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java b/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java
new file mode 100644
index 0000000..8308be7
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java
@@ -0,0 +1,467 @@
+// 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.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import 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,
+ * @version 2.0.1 (sax2r2)
+ * @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 identifer, 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 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 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
diff --git a/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java b/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java
new file mode 100644
index 0000000..18445bc
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java
@@ -0,0 +1,214 @@
+// SAX default implementation for Locator.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: LocatorImpl.java,v 1.6 2002/01/30 20:52:27 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.Locator;
+
+
+/**
+ * Provide an optional convenience implementation of Locator.
+ *
+ * <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 mainly for application writers, who
+ * can use it to make a persistent snapshot of a locator at any
+ * point during a document parse:</p>
+ *
+ * <pre>
+ * Locator locator;
+ * Locator startloc;
+ *
+ * public void setLocator (Locator locator)
+ * {
+ *         // note the locator
+ *   this.locator = locator;
+ * }
+ *
+ * public void startDocument ()
+ * {
+ *         // save the location of the start of the document
+ *         // for future use.
+ *   Locator startloc = new LocatorImpl(locator);
+ * }
+ *</pre>
+ *
+ * <p>Normally, parser writers will not use this class, since it
+ * is more efficient to provide location information only when
+ * requested, rather than constantly updating a Locator object.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Locator Locator
+ */
+public class LocatorImpl implements Locator
+{
+    
+    
+    /**
+     * Zero-argument constructor.
+     *
+     * <p>This will not normally be useful, since the main purpose
+     * of this class is to make a snapshot of an existing Locator.</p>
+     */
+    public LocatorImpl ()
+    {
+    }
+    
+    
+    /**
+     * Copy constructor.
+     *
+     * <p>Create a persistent copy of the current state of a locator.
+     * When the original locator changes, this copy will still keep
+     * the original values (and it can be used outside the scope of
+     * DocumentHandler methods).</p>
+     *
+     * @param locator The locator to copy.
+     */
+    public LocatorImpl (Locator locator)
+    {
+    setPublicId(locator.getPublicId());
+    setSystemId(locator.getSystemId());
+    setLineNumber(locator.getLineNumber());
+    setColumnNumber(locator.getColumnNumber());
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.Locator
+    ////////////////////////////////////////////////////////////////////
+    
+    
+    /**
+     * Return the saved public identifier.
+     *
+     * @return The public identifier as a string, or null if none
+     *         is available.
+     * @see org.xml.sax.Locator#getPublicId
+     * @see #setPublicId
+     */
+    public String getPublicId ()
+    {
+    return publicId;
+    }
+    
+    
+    /**
+     * Return the saved system identifier.
+     *
+     * @return The system identifier as a string, or null if none
+     *         is available.
+     * @see org.xml.sax.Locator#getSystemId
+     * @see #setSystemId
+     */
+    public String getSystemId ()
+    {
+    return systemId;
+    }
+    
+    
+    /**
+     * Return the saved line number (1-based).
+     *
+     * @return The line number as an integer, or -1 if none is available.
+     * @see org.xml.sax.Locator#getLineNumber
+     * @see #setLineNumber
+     */
+    public int getLineNumber ()
+    {
+    return lineNumber;
+    }
+    
+    
+    /**
+     * Return the saved column number (1-based).
+     *
+     * @return The column number as an integer, or -1 if none is available.
+     * @see org.xml.sax.Locator#getColumnNumber
+     * @see #setColumnNumber
+     */
+    public int getColumnNumber ()
+    {
+    return columnNumber;
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Setters for the properties (not in org.xml.sax.Locator)
+    ////////////////////////////////////////////////////////////////////
+    
+    
+    /**
+     * Set the public identifier for this locator.
+     *
+     * @param publicId The new public identifier, or null 
+     *        if none is available.
+     * @see #getPublicId
+     */
+    public void setPublicId (String publicId)
+    {
+    this.publicId = publicId;
+    }
+    
+    
+    /**
+     * Set the system identifier for this locator.
+     *
+     * @param systemId The new system identifier, or null 
+     *        if none is available.
+     * @see #getSystemId
+     */
+    public void setSystemId (String systemId)
+    {
+    this.systemId = systemId;
+    }
+    
+    
+    /**
+     * Set the line number for this locator (1-based).
+     *
+     * @param lineNumber The line number, or -1 if none is available.
+     * @see #getLineNumber
+     */
+    public void setLineNumber (int lineNumber)
+    {
+    this.lineNumber = lineNumber;
+    }
+    
+    
+    /**
+     * Set the column number for this locator (1-based).
+     *
+     * @param columnNumber The column number, or -1 if none is available.
+     * @see #getColumnNumber
+     */
+    public void setColumnNumber (int columnNumber)
+    {
+    this.columnNumber = columnNumber;
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+    
+    private String publicId;
+    private String systemId;
+    private int lineNumber;
+    private int columnNumber;
+    
+}
+
+// end of LocatorImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java b/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
new file mode 100644
index 0000000..a737d1d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
@@ -0,0 +1,840 @@
+// NamespaceSupport.java - generic Namespace support for SAX.
+// http://www.saxproject.org
+// Written by David Megginson
+// This class is in the Public Domain.  NO WARRANTY!
+// $Id: NamespaceSupport.java,v 1.15 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.util.EmptyStackException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+
+/**
+ * Encapsulate Namespace logic for use by applications using SAX,
+ * or internally by SAX drivers.
+ *
+ * <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 encapsulates the logic of Namespace processing: it
+ * tracks the declarations currently in force for each context and
+ * automatically processes qualified XML names into their Namespace
+ * parts; it can also be used in reverse for generating XML qnames
+ * from Namespaces.</p>
+ *
+ * <p>Namespace support objects are reusable, but the reset method
+ * must be invoked between each session.</p>
+ *
+ * <p>Here is a simple session:</p>
+ *
+ * <pre>
+ * String parts[] = new String[3];
+ * NamespaceSupport support = new NamespaceSupport();
+ *
+ * support.pushContext();
+ * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
+ * support.declarePrefix("dc", "http://www.purl.org/dc#");
+ *
+ * parts = support.processName("p", parts, false);
+ * System.out.println("Namespace URI: " + parts[0]);
+ * System.out.println("Local name: " + parts[1]);
+ * System.out.println("Raw name: " + parts[2]);
+ *
+ * parts = support.processName("dc:title", parts, false);
+ * System.out.println("Namespace URI: " + parts[0]);
+ * System.out.println("Local name: " + parts[1]);
+ * System.out.println("Raw name: " + parts[2]);
+ *
+ * support.popContext();
+ * </pre>
+ *
+ * <p>Note that this class is optimized for the use case where most
+ * elements do not contain Namespace declarations: if the same
+ * prefix/URI mapping is repeated for each context (for example), this
+ * class will be somewhat less efficient.</p>
+ *
+ * <p>Although SAX drivers (parsers) may choose to use this class to
+ * implement namespace handling, they are not required to do so.
+ * Applications must track namespace information themselves if they
+ * want to use namespace information.
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class NamespaceSupport
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constants.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * The XML Namespace URI as a constant.
+     * The value is <code>http://www.w3.org/XML/1998/namespace</code>
+     * as defined in the "Namespaces in XML" * recommendation.
+     *
+     * <p>This is the Namespace URI that is automatically mapped
+     * to the "xml" prefix.</p>
+     */
+    public final static String XMLNS =
+    "http://www.w3.org/XML/1998/namespace";
+
+
+    /**
+     * The namespace declaration URI as a constant.
+     * The value is <code>http://www.w3.org/xmlns/2000/</code>, as defined
+     * in a backwards-incompatible erratum to the "Namespaces in XML"
+     * recommendation.  Because that erratum postdated SAX2, SAX2 defaults 
+     * to the original recommendation, and does not normally use this URI.
+     * 
+     *
+     * <p>This is the Namespace URI that is optionally applied to
+     * <em>xmlns</em> and <em>xmlns:*</em> attributes, which are used to
+     * declare namespaces.  </p>
+     *
+     * @since SAX 2.1alpha
+     * @see #setNamespaceDeclUris
+     * @see #isNamespaceDeclUris
+     */
+    public final static String NSDECL =
+    "http://www.w3.org/xmlns/2000/";
+
+
+    /**
+     * An empty enumeration.
+     */
+    private final static Enumeration EMPTY_ENUMERATION =
+    new Vector().elements();
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructor.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new Namespace support object.
+     */
+    public NamespaceSupport ()
+    {
+    reset();
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Context management.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Reset this Namespace support object for reuse.
+     *
+     * <p>It is necessary to invoke this method before reusing the
+     * Namespace support object for a new session.  If namespace
+     * declaration URIs are to be supported, that flag must also
+     * be set to a non-default value.
+     * </p>
+     *
+     * @see #setNamespaceDeclUris
+     */
+    public void reset ()
+    {
+    contexts = new Context[32];
+    namespaceDeclUris = false;
+    contextPos = 0;
+    contexts[contextPos] = currentContext = new Context();
+    currentContext.declarePrefix("xml", XMLNS);
+    }
+
+
+    /**
+     * Start a new Namespace context.
+     * The new context will automatically inherit
+     * the declarations of its parent context, but it will also keep
+     * track of which declarations were made within this context.
+     *
+     * <p>Event callback code should start a new context once per element.
+     * This means being ready to call this in either of two places.
+     * For elements that don't include namespace declarations, the
+     * <em>ContentHandler.startElement()</em> callback is the right place.
+     * For elements with such a declaration, it'd done in the first
+     * <em>ContentHandler.startPrefixMapping()</em> callback.
+     * A boolean flag can be used to
+     * track whether a context has been started yet.  When either of
+     * those methods is called, it checks the flag to see if a new context
+     * needs to be started.  If so, it starts the context and sets the
+     * flag.  After <em>ContentHandler.startElement()</em>
+     * does that, it always clears the flag.
+     *
+     * <p>Normally, SAX drivers would push a new context at the beginning
+     * of each XML element.  Then they perform a first pass over the
+     * attributes to process all namespace declarations, making
+     * <em>ContentHandler.startPrefixMapping()</em> callbacks.
+     * Then a second pass is made, to determine the namespace-qualified
+     * names for all attributes and for the element name.
+     * Finally all the information for the
+     * <em>ContentHandler.startElement()</em> callback is available,
+     * so it can then be made.
+     *
+     * <p>The Namespace support object always starts with a base context
+     * already in force: in this context, only the "xml" prefix is
+     * declared.</p>
+     *
+     * @see org.xml.sax.ContentHandler
+     * @see #popContext
+     */
+    public void pushContext ()
+    {
+    int max = contexts.length;
+
+    contexts [contextPos].declsOK = false;
+    contextPos++;
+
+                // Extend the array if necessary
+    if (contextPos >= max) {
+        Context newContexts[] = new Context[max*2];
+        System.arraycopy(contexts, 0, newContexts, 0, max);
+        max *= 2;
+        contexts = newContexts;
+    }
+
+                // Allocate the context if necessary.
+    currentContext = contexts[contextPos];
+    if (currentContext == null) {
+        contexts[contextPos] = currentContext = new Context();
+    }
+
+                // Set the parent, if any.
+    if (contextPos > 0) {
+        currentContext.setParent(contexts[contextPos - 1]);
+    }
+    }
+
+
+    /**
+     * Revert to the previous Namespace context.
+     *
+     * <p>Normally, you should pop the context at the end of each
+     * XML element.  After popping the context, all Namespace prefix
+     * mappings that were previously in force are restored.</p>
+     *
+     * <p>You must not attempt to declare additional Namespace
+     * prefixes after popping a context, unless you push another
+     * context first.</p>
+     *
+     * @see #pushContext
+     */
+    public void popContext ()
+    {
+    contexts[contextPos].clear();
+    contextPos--;
+    if (contextPos < 0) {
+        throw new EmptyStackException();
+    }
+    currentContext = contexts[contextPos];
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Operations within a context.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Declare a Namespace prefix.  All prefixes must be declared
+     * before they are referenced.  For example, a SAX driver (parser)
+     * would scan an element's attributes
+     * in two passes:  first for namespace declarations,
+     * then a second pass using {@link #processName processName()} to
+     * interpret prefixes against (potentially redefined) prefixes.
+     *
+     * <p>This method declares a prefix in the current Namespace
+     * context; the prefix will remain in force until this context
+     * is popped, unless it is shadowed in a descendant context.</p>
+     *
+     * <p>To declare the default element Namespace, use the empty string as
+     * the prefix.</p>
+     *
+     * <p>Note that you must <em>not</em> declare a prefix after
+     * you've pushed and popped another Namespace context, or
+     * treated the declarations phase as complete by processing
+     * a prefixed name.</p>
+     *
+     * <p>Note that there is an asymmetry in this library: {@link
+     * #getPrefix getPrefix} will not return the "" prefix,
+     * even if you have declared a default element namespace.
+     * To check for a default namespace,
+     * you have to look it up explicitly using {@link #getURI getURI}.
+     * This asymmetry exists to make it easier to look up prefixes
+     * for attribute names, where the default prefix is not allowed.</p>
+     *
+     * @param prefix The prefix to declare, or the empty string to
+     *    indicate the default element namespace.  This may never have
+     *    the value "xml" or "xmlns".
+     * @param uri The Namespace URI to associate with the prefix.
+     * @return true if the prefix was legal, false otherwise
+     *
+     * @see #processName
+     * @see #getURI
+     * @see #getPrefix
+     */
+    public boolean declarePrefix (String prefix, String uri)
+    {
+    if (prefix.equals("xml") || prefix.equals("xmlns")) {
+        return false;
+    } else {
+        currentContext.declarePrefix(prefix, uri);
+        return true;
+    }
+    }
+
+
+    /**
+     * Process a raw XML qualified name, after all declarations in the
+     * current context have been handled by {@link #declarePrefix
+     * declarePrefix()}.
+     *
+     * <p>This method processes a raw XML qualified name in the
+     * current context by removing the prefix and looking it up among
+     * the prefixes currently declared.  The return value will be the
+     * array supplied by the caller, filled in as follows:</p>
+     *
+     * <dl>
+     * <dt>parts[0]</dt>
+     * <dd>The Namespace URI, or an empty string if none is
+     *  in use.</dd>
+     * <dt>parts[1]</dt>
+     * <dd>The local name (without prefix).</dd>
+     * <dt>parts[2]</dt>
+     * <dd>The original raw name.</dd>
+     * </dl>
+     *
+     * <p>All of the strings in the array will be internalized.  If
+     * the raw name has a prefix that has not been declared, then
+     * the return value will be null.</p>
+     *
+     * <p>Note that attribute names are processed differently than
+     * element names: an unprefixed element name will receive the
+     * default Namespace (if any), while an unprefixed attribute name
+     * will not.</p>
+     *
+     * @param qName The XML qualified name to be processed.
+     * @param parts An array supplied by the caller, capable of
+     *        holding at least three members.
+     * @param isAttribute A flag indicating whether this is an
+     *        attribute name (true) or an element name (false).
+     * @return The supplied array holding three internalized strings 
+     *        representing the Namespace URI (or empty string), the
+     *        local name, and the XML qualified name; or null if there
+     *        is an undeclared prefix.
+     * @see #declarePrefix
+     * @see java.lang.String#intern */
+    public String [] processName (String qName, String parts[],
+                  boolean isAttribute)
+    {
+    String myParts[] = currentContext.processName(qName, isAttribute);
+    if (myParts == null) {
+        return null;
+    } else {
+        parts[0] = myParts[0];
+        parts[1] = myParts[1];
+        parts[2] = myParts[2];
+        return parts;
+    }
+    }
+
+
+    /**
+     * Look up a prefix and get the currently-mapped Namespace URI.
+     *
+     * <p>This method looks up the prefix in the current context.
+     * Use the empty string ("") for the default Namespace.</p>
+     *
+     * @param prefix The prefix to look up.
+     * @return The associated Namespace URI, or null if the prefix
+     *         is undeclared in this context.
+     * @see #getPrefix
+     * @see #getPrefixes
+     */
+    public String getURI (String prefix)
+    {
+    return currentContext.getURI(prefix);
+    }
+
+
+    /**
+     * Return an enumeration of all prefixes whose declarations are
+     * active in the current context.
+     * This includes declarations from parent contexts that have
+     * not been overridden.
+     *
+     * <p><strong>Note:</strong> if there is a default prefix, it will not be
+     * returned in this enumeration; check for the default prefix
+     * using the {@link #getURI getURI} with an argument of "".</p>
+     *
+     * @return An enumeration of prefixes (never empty).
+     * @see #getDeclaredPrefixes
+     * @see #getURI
+     */
+    public Enumeration getPrefixes ()
+    {
+    return currentContext.getPrefixes();
+    }
+
+
+    /**
+     * Return one of the prefixes mapped to a Namespace URI.
+     *
+     * <p>If more than one prefix is currently mapped to the same
+     * URI, this method will make an arbitrary selection; if you
+     * want all of the prefixes, use the {@link #getPrefixes}
+     * method instead.</p>
+     *
+     * <p><strong>Note:</strong> this will never return the empty (default) prefix;
+     * to check for a default prefix, use the {@link #getURI getURI}
+     * method with an argument of "".</p>
+     *
+     * @param uri the namespace URI
+     * @return one of the prefixes currently mapped to the URI supplied,
+     *         or null if none is mapped or if the URI is assigned to
+     *         the default namespace
+     * @see #getPrefixes(java.lang.String)
+     * @see #getURI
+     */
+    public String getPrefix (String uri)
+    {
+    return currentContext.getPrefix(uri);
+    }
+
+
+    /**
+     * Return an enumeration of all prefixes for a given URI whose
+     * declarations are active in the current context.
+     * This includes declarations from parent contexts that have
+     * not been overridden.
+     *
+     * <p>This method returns prefixes mapped to a specific Namespace
+     * URI.  The xml: prefix will be included.  If you want only one
+     * prefix that's mapped to the Namespace URI, and you don't care 
+     * which one you get, use the {@link #getPrefix getPrefix}
+     *  method instead.</p>
+     *
+     * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
+     * in this enumeration; to check for the presence of a default
+     * Namespace, use the {@link #getURI getURI} method with an
+     * argument of "".</p>
+     *
+     * @param uri The Namespace URI.
+     * @return An enumeration of prefixes (never empty).
+     * @see #getPrefix
+     * @see #getDeclaredPrefixes
+     * @see #getURI
+     */
+    public Enumeration getPrefixes (String uri)
+    {
+    Vector prefixes = new Vector();
+    Enumeration allPrefixes = getPrefixes();
+    while (allPrefixes.hasMoreElements()) {
+        String prefix = (String)allPrefixes.nextElement();
+        if (uri.equals(getURI(prefix))) {
+        prefixes.addElement(prefix);
+        }
+    }
+    return prefixes.elements();
+    }
+
+
+    /**
+     * Return an enumeration of all prefixes declared in this context.
+     *
+     * <p>The empty (default) prefix will be included in this 
+     * enumeration; note that this behaviour differs from that of
+     * {@link #getPrefix} and {@link #getPrefixes}.</p>
+     *
+     * @return An enumeration of all prefixes declared in this
+     *         context.
+     * @see #getPrefixes
+     * @see #getURI
+     */
+    public Enumeration getDeclaredPrefixes ()
+    {
+    return currentContext.getDeclaredPrefixes();
+    }
+
+    /**
+     * Controls whether namespace declaration attributes are placed
+     * into the {@link #NSDECL NSDECL} namespace
+     * by {@link #processName processName()}.  This may only be
+     * changed before any contexts have been pushed.
+     * 
+     * @param value the namespace declaration attribute state. A value of true
+     *              enables this feature, a value of false disables it.
+     *
+     * @since SAX 2.1alpha
+     *
+     * @exception IllegalStateException when attempting to set this
+     *    after any context has been pushed.
+     */
+    public void setNamespaceDeclUris (boolean value)
+    {
+    if (contextPos != 0)
+        throw new IllegalStateException ();
+    if (value == namespaceDeclUris)
+        return;
+    namespaceDeclUris = value;
+    if (value)
+        currentContext.declarePrefix ("xmlns", NSDECL);
+    else {
+        contexts[contextPos] = currentContext = new Context();
+        currentContext.declarePrefix("xml", XMLNS);
+    }
+    }
+
+    /**
+     * Returns true if namespace declaration attributes are placed into
+     * a namespace.  This behavior is not the default.
+     *
+     * @return true if namespace declaration attributes are enabled, false
+     *         otherwise.
+     * @since SAX 2.1alpha
+     */
+    public boolean isNamespaceDeclUris ()
+    { return namespaceDeclUris; }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private Context contexts[];
+    private Context currentContext;
+    private int contextPos;
+    private boolean namespaceDeclUris;
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal classes.
+    ////////////////////////////////////////////////////////////////////
+
+    /**
+     * Internal class for a single Namespace context.
+     *
+     * <p>This module caches and reuses Namespace contexts,
+     * so the number allocated
+     * will be equal to the element depth of the document, not to the total
+     * number of elements (i.e. 5-10 rather than tens of thousands).
+     * Also, data structures used to represent contexts are shared when
+     * possible (child contexts without declarations) to further reduce
+     * the amount of memory that's consumed.
+     * </p>
+     */
+    final class Context {
+
+    /**
+     * Create the root-level Namespace context.
+     */
+    Context ()
+    {
+        copyTables();
+    }
+    
+    
+    /**
+     * (Re)set the parent of this Namespace context.
+     * The context must either have been freshly constructed,
+     * or must have been cleared.
+     *
+     * @param context The parent Namespace context object.
+     */
+    void setParent (Context parent)
+    {
+        this.parent = parent;
+        declarations = null;
+        prefixTable = parent.prefixTable;
+        uriTable = parent.uriTable;
+        elementNameTable = parent.elementNameTable;
+        attributeNameTable = parent.attributeNameTable;
+        defaultNS = parent.defaultNS;
+        declSeen = false;
+        declsOK = true;
+    }
+
+    /**
+     * Makes associated state become collectible,
+     * invalidating this context.
+     * {@link #setParent} must be called before
+     * this context may be used again.
+     */
+    void clear ()
+    {
+        parent = null;
+        prefixTable = null;
+        uriTable = null;
+        elementNameTable = null;
+        attributeNameTable = null;
+        defaultNS = null;
+    }
+    
+    
+    /**
+     * Declare a Namespace prefix for this context.
+     *
+     * @param prefix The prefix to declare.
+     * @param uri The associated Namespace URI.
+     * @see org.xml.sax.helpers.NamespaceSupport#declarePrefix
+     */
+    void declarePrefix (String prefix, String uri)
+    {
+                // Lazy processing...
+        if (!declsOK)
+        throw new IllegalStateException (
+            "can't declare any more prefixes in this context");
+        if (!declSeen) {
+        copyTables();
+        }
+        if (declarations == null) {
+        declarations = new Vector();
+        }
+        
+        prefix = prefix.intern();
+        uri = uri.intern();
+        if ("".equals(prefix)) {
+        if ("".equals(uri)) {
+            defaultNS = null;
+        } else {
+            defaultNS = uri;
+        }
+        } else {
+        prefixTable.put(prefix, uri);
+        uriTable.put(uri, prefix); // may wipe out another prefix
+        }
+        declarations.addElement(prefix);
+    }
+
+
+    /**
+     * Process an XML qualified name in this context.
+     *
+     * @param qName The XML qualified name.
+     * @param isAttribute true if this is an attribute name.
+     * @return An array of three strings containing the
+     *         URI part (or empty string), the local part,
+     *         and the raw name, all internalized, or null
+     *         if there is an undeclared prefix.
+     * @see org.xml.sax.helpers.NamespaceSupport#processName
+     */
+    String [] processName (String qName, boolean isAttribute)
+    {
+        String name[];
+        Hashtable table;
+        
+                    // detect errors in call sequence
+        declsOK = false;
+
+                // Select the appropriate table.
+        if (isAttribute) {
+        table = attributeNameTable;
+        } else {
+        table = elementNameTable;
+        }
+        
+                // Start by looking in the cache, and
+                // return immediately if the name
+                // is already known in this content
+        name = (String[])table.get(qName);
+        if (name != null) {
+        return name;
+        }
+        
+                // We haven't seen this name in this
+                // context before.  Maybe in the parent
+                // context, but we can't assume prefix
+                // bindings are the same.
+        name = new String[3];
+        name[2] = qName.intern();
+        int index = qName.indexOf(':');
+        
+        
+                // No prefix.
+        if (index == -1) {
+        if (isAttribute) {
+            if (qName == "xmlns" && namespaceDeclUris)
+            name[0] = NSDECL;
+            else
+            name[0] = "";
+        } else if (defaultNS == null) {
+            name[0] = "";
+        } else {
+            name[0] = defaultNS;
+        }
+        name[1] = name[2];
+        }
+        
+                // Prefix
+        else {
+        String prefix = qName.substring(0, index);
+        String local = qName.substring(index+1);
+        String uri;
+        if ("".equals(prefix)) {
+            uri = defaultNS;
+        } else {
+            uri = (String)prefixTable.get(prefix);
+        }
+        if (uri == null
+            || (!isAttribute && "xmlns".equals (prefix))) {
+            return null;
+        }
+        name[0] = uri;
+        name[1] = local.intern();
+        }
+        
+                // Save in the cache for future use.
+                // (Could be shared with parent context...)
+        table.put(name[2], name);
+        return name;
+    }
+    
+
+    /**
+     * Look up the URI associated with a prefix in this context.
+     *
+     * @param prefix The prefix to look up.
+     * @return The associated Namespace URI, or null if none is
+     *         declared.    
+     * @see org.xml.sax.helpers.NamespaceSupport#getURI
+     */
+    String getURI (String prefix)
+    {
+        if ("".equals(prefix)) {
+        return defaultNS;
+        } else if (prefixTable == null) {
+        return null;
+        } else {
+        return (String)prefixTable.get(prefix);
+        }
+    }
+
+
+    /**
+     * Look up one of the prefixes associated with a URI in this context.
+     *
+     * <p>Since many prefixes may be mapped to the same URI,
+     * the return value may be unreliable.</p>
+     *
+     * @param uri The URI to look up.
+     * @return The associated prefix, or null if none is declared.
+     * @see org.xml.sax.helpers.NamespaceSupport#getPrefix
+     */
+    String getPrefix (String uri)
+    {
+        if (uriTable == null) {
+        return null;
+        } else {
+        return (String)uriTable.get(uri);
+        }
+    }
+    
+    
+    /**
+     * Return an enumeration of prefixes declared in this context.
+     *
+     * @return An enumeration of prefixes (possibly empty).
+     * @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes
+     */
+    Enumeration getDeclaredPrefixes ()
+    {
+        if (declarations == null) {
+        return EMPTY_ENUMERATION;
+        } else {
+        return declarations.elements();
+        }
+    }
+    
+    
+    /**
+     * Return an enumeration of all prefixes currently in force.
+     *
+     * <p>The default prefix, if in force, is <em>not</em>
+     * returned, and will have to be checked for separately.</p>
+     *
+     * @return An enumeration of prefixes (never empty).
+     * @see org.xml.sax.helpers.NamespaceSupport#getPrefixes
+     */
+    Enumeration getPrefixes ()
+    {
+        if (prefixTable == null) {
+        return EMPTY_ENUMERATION;
+        } else {
+        return prefixTable.keys();
+        }
+    }
+    
+    
+
+    ////////////////////////////////////////////////////////////////
+    // Internal methods.
+    ////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Copy on write for the internal tables in this context.
+     *
+     * <p>This class is optimized for the normal case where most
+     * elements do not contain Namespace declarations.</p>
+     */    
+    private void copyTables ()
+    {
+        if (prefixTable != null) {
+        prefixTable = (Hashtable)prefixTable.clone();
+        } else {
+        prefixTable = new Hashtable();
+        }
+        if (uriTable != null) {
+        uriTable = (Hashtable)uriTable.clone();
+        } else {
+        uriTable = new Hashtable();
+        }
+        elementNameTable = new Hashtable();
+        attributeNameTable = new Hashtable();
+        declSeen = true;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////
+    // Protected state.
+    ////////////////////////////////////////////////////////////////
+    
+    Hashtable prefixTable;
+    Hashtable uriTable;
+    Hashtable elementNameTable;
+    Hashtable attributeNameTable;
+    String defaultNS = null;
+    boolean declsOK = true;
+    
+
+
+    ////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////
+    
+    private Vector declarations = null;
+    private boolean declSeen = false;
+    private Context parent = null;
+    }
+}
+
+// end of NamespaceSupport.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/NewInstance.java b/xml/src/main/java/org/xml/sax/helpers/NewInstance.java
new file mode 100644
index 0000000..e590192
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/NewInstance.java
@@ -0,0 +1,79 @@
+// NewInstance.java - create a new instance of a class by name.
+// http://www.saxproject.org
+// Written by Edwin Goei, edwingo@apache.org
+// and by David Brownell, dbrownell@users.sourceforge.net
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: NewInstance.java,v 1.4 2002/01/30 20:52:27 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Create a new instance of a class by name.
+ *
+ * <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 contains a static method for creating an instance of a
+ * class from an explicit class name.  It tries to use the thread's context
+ * ClassLoader if possible and falls back to using
+ * Class.forName(String).</p>
+ *
+ * <p>This code is designed to compile and run on JDK version 1.1 and later
+ * including versions of Java 2.</p>
+ *
+ * @author Edwin Goei, David Brownell
+ * @version 2.0.1 (sax2r2)
+ */
+class NewInstance {
+
+    /**
+     * Creates a new instance of the specified class name
+     *
+     * Package private so this code is not exposed at the API level.
+     */
+    static Object newInstance (ClassLoader classLoader, String className)
+        throws ClassNotFoundException, IllegalAccessException,
+            InstantiationException
+    {
+        Class driverClass;
+        if (classLoader == null) {
+            driverClass = Class.forName(className);
+        } else {
+            driverClass = classLoader.loadClass(className);
+        }
+        return driverClass.newInstance();
+    }
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */           
+    static ClassLoader getClassLoader ()
+    {
+        Method m = null;
+
+        try {
+            m = Thread.class.getMethod("getContextClassLoader");
+        } catch (NoSuchMethodException e) {
+            // Assume that we are running JDK 1.1, use the current ClassLoader
+            return NewInstance.class.getClassLoader();
+        }
+
+        try {
+            return (ClassLoader) m.invoke(Thread.currentThread());
+        } catch (IllegalAccessException e) {
+            // assert(false)
+            throw new UnknownError(e.getMessage());
+        } catch (InvocationTargetException e) {
+            // assert(e.getTargetException() instanceof SecurityException)
+            throw new UnknownError(e.getMessage());
+        }
+    }
+}
diff --git a/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java b/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java
new file mode 100644
index 0000000..7fc3813
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java
@@ -0,0 +1,1046 @@
+// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: ParserAdapter.java,v 1.16 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.xml.sax.Parser;    // deprecated
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.AttributeList; // deprecated
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler; // deprecated
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+
+/**
+ * Adapt a SAX1 Parser as a SAX2 XMLReader.
+ *
+ * <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 wraps a SAX1 {@link org.xml.sax.Parser Parser}
+ * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
+ * with feature, property, and Namespace support.  Note
+ * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
+ * skippedEntity} events, since SAX1 does not make that information available.</p>
+ *
+ * <p>This adapter does not test for duplicate Namespace-qualified
+ * attribute names.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.helpers.XMLReaderAdapter
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.Parser
+ */
+public class ParserAdapter implements XMLReader, DocumentHandler
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructors.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct a new parser adapter.
+     *
+     * <p>Use the "org.xml.sax.parser" property to locate the
+     * embedded SAX1 driver.</p>
+     *
+     * @exception SAXException If the embedded driver
+     *            cannot be instantiated or if the
+     *            org.xml.sax.parser property is not specified.
+     */
+    public ParserAdapter ()
+      throws SAXException
+    {
+    super();
+
+    String driver = System.getProperty("org.xml.sax.parser");
+
+    try {
+        setup(ParserFactory.makeParser());
+    } catch (ClassNotFoundException e1) {
+        throw new
+        SAXException("Cannot find SAX1 driver class " +
+                 driver, e1);
+    } catch (IllegalAccessException e2) {
+        throw new
+        SAXException("SAX1 driver class " +
+                 driver +
+                 " found but cannot be loaded", e2);
+    } catch (InstantiationException e3) {
+        throw new
+        SAXException("SAX1 driver class " +
+                 driver +
+                 " loaded but cannot be instantiated", e3);
+    } catch (ClassCastException e4) {
+        throw new
+        SAXException("SAX1 driver class " +
+                 driver +
+                 " does not implement org.xml.sax.Parser");
+    } catch (NullPointerException e5) {
+        throw new 
+        SAXException("System property org.xml.sax.parser not specified");
+    }
+    }
+
+
+    /**
+     * Construct a new parser adapter.
+     *
+     * <p>Note that the embedded parser cannot be changed once the
+     * adapter is created; to embed a different parser, allocate
+     * a new ParserAdapter.</p>
+     *
+     * @param parser The SAX1 parser to embed.
+     * @exception java.lang.NullPointerException If the parser parameter
+     *            is null.
+     */
+    public ParserAdapter (Parser parser)
+    {
+    super();
+    setup(parser);
+    }
+
+
+    /**
+     * Internal setup method.
+     *
+     * @param parser The embedded parser.
+     * @exception java.lang.NullPointerException If the parser parameter
+     *            is null.
+     */
+    private void setup (Parser parser)
+    {
+    if (parser == null) {
+        throw new
+        NullPointerException("Parser argument must not be null");
+    }
+    this.parser = parser;
+    atts = new AttributesImpl();
+    nsSupport = new NamespaceSupport();
+    attAdapter = new AttributeListAdapter();
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.XMLReader.
+    ////////////////////////////////////////////////////////////////////
+
+
+    //
+    // Internal constants for the sake of convenience.
+    //
+    private final static String FEATURES = "http://xml.org/sax/features/";
+    private final static String NAMESPACES = FEATURES + "namespaces";
+    private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
+    private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
+
+
+    /**
+     * Set a feature flag for the parser.
+     *
+     * <p>The only features recognized are namespaces and 
+     * namespace-prefixes.</p>
+     *
+     * @param name The feature name, as a complete URI.
+     * @param value The requested feature value.
+     * @exception SAXNotRecognizedException If the feature
+     *            can't be assigned or retrieved.
+     * @exception SAXNotSupportedException If the feature
+     *            can't be assigned that value.
+     * @see org.xml.sax.XMLReader#setFeature
+     */
+    public void setFeature (String name, boolean value)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (name.equals(NAMESPACES)) {
+        checkNotParsing("feature", name);
+        namespaces = value;
+        if (!namespaces && !prefixes) {
+        prefixes = true;
+        }
+    } else if (name.equals(NAMESPACE_PREFIXES)) {
+        checkNotParsing("feature", name);
+        prefixes = value;
+        if (!prefixes && !namespaces) {
+        namespaces = true;
+        }
+    } else if (name.equals(XMLNS_URIs)) {
+        checkNotParsing("feature", name);
+        uris = value;
+    } else {
+        throw new SAXNotRecognizedException("Feature: " + name);
+    }
+    }
+
+
+    /**
+     * Check a parser feature flag.
+     *
+     * <p>The only features recognized are namespaces and 
+     * namespace-prefixes.</p>
+     *
+     * @param name The feature name, as a complete URI.
+     * @return The current feature value.
+     * @exception SAXNotRecognizedException If the feature
+     *            value can't be assigned or retrieved.
+     * @exception SAXNotSupportedException If the
+     *            feature is not currently readable.
+     * @see org.xml.sax.XMLReader#setFeature
+     */
+    public boolean getFeature (String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (name.equals(NAMESPACES)) {
+        return namespaces;
+    } else if (name.equals(NAMESPACE_PREFIXES)) {
+        return prefixes;
+    } else if (name.equals(XMLNS_URIs)) {
+        return uris;
+    } else {
+        throw new SAXNotRecognizedException("Feature: " + name);
+    }
+    }
+
+
+    /**
+     * Set a parser property.
+     *
+     * <p>No properties are currently recognized.</p>
+     *
+     * @param name The property name.
+     * @param value The property value.
+     * @exception SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved.
+     * @exception SAXNotSupportedException If the property
+     *            can't be assigned that value.
+     * @see org.xml.sax.XMLReader#setProperty
+     */
+    public void setProperty (String name, Object value)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    throw new SAXNotRecognizedException("Property: " + name);
+    }
+
+
+    /**
+     * Get a parser property.
+     *
+     * <p>No properties are currently recognized.</p>
+     *
+     * @param name The property name.
+     * @return The property value.
+     * @exception SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved.
+     * @exception SAXNotSupportedException If the property
+     *            value is not currently readable.
+     * @see org.xml.sax.XMLReader#getProperty
+     */
+    public Object getProperty (String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    throw new SAXNotRecognizedException("Property: " + name);
+    }
+
+
+    /**
+     * Set the entity resolver.
+     *
+     * @param resolver The new entity resolver.
+     * @see org.xml.sax.XMLReader#setEntityResolver
+     */
+    public void setEntityResolver (EntityResolver resolver)
+    {
+    entityResolver = resolver;
+    }
+
+
+    /**
+     * Return the current entity resolver.
+     *
+     * @return The current entity resolver, or null if none was supplied.
+     * @see org.xml.sax.XMLReader#getEntityResolver
+     */
+    public EntityResolver getEntityResolver ()
+    {
+    return entityResolver;
+    }
+
+
+    /**
+     * Set the DTD handler.
+     *
+     * @param handler the new DTD handler
+     * @see org.xml.sax.XMLReader#setEntityResolver
+     */
+    public void setDTDHandler (DTDHandler handler)
+    {
+    dtdHandler = handler;
+    }
+
+
+    /**
+     * Return the current DTD handler.
+     *
+     * @return the current DTD handler, or null if none was supplied
+     * @see org.xml.sax.XMLReader#getEntityResolver
+     */
+    public DTDHandler getDTDHandler ()
+    {
+    return dtdHandler;
+    }
+
+
+    /**
+     * Set the content handler.
+     *
+     * @param handler the new content handler
+     * @see org.xml.sax.XMLReader#setEntityResolver
+     */
+    public void setContentHandler (ContentHandler handler)
+    {
+    contentHandler = handler;
+    }
+
+
+    /**
+     * Return the current content handler.
+     *
+     * @return The current content handler, or null if none was supplied.
+     * @see org.xml.sax.XMLReader#getEntityResolver
+     */
+    public ContentHandler getContentHandler ()
+    {
+    return contentHandler;
+    }
+
+
+    /**
+     * Set the error handler.
+     *
+     * @param handler The new error handler.
+     * @see org.xml.sax.XMLReader#setEntityResolver
+     */
+    public void setErrorHandler (ErrorHandler handler)
+    {
+    errorHandler = handler;
+    }
+
+
+    /**
+     * Return the current error handler.
+     *
+     * @return The current error handler, or null if none was supplied.
+     * @see org.xml.sax.XMLReader#getEntityResolver
+     */
+    public ErrorHandler getErrorHandler ()
+    {
+    return errorHandler;
+    }
+
+
+    /**
+     * Parse an XML document.
+     *
+     * @param systemId The absolute URL of the document.
+     * @exception java.io.IOException If there is a problem reading
+     *            the raw content of the document.
+     * @exception SAXException If there is a problem
+     *            processing the document.
+     * @see #parse(org.xml.sax.InputSource)
+     * @see org.xml.sax.Parser#parse(java.lang.String)
+     */
+    public void parse (String systemId)
+    throws IOException, SAXException
+    {
+    parse(new InputSource(systemId));
+    }
+
+
+    /**
+     * Parse an XML document.
+     *
+     * @param input An input source for the document.
+     * @exception java.io.IOException If there is a problem reading
+     *            the raw content of the document.
+     * @exception SAXException If there is a problem
+     *            processing the document.
+     * @see #parse(java.lang.String)
+     * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
+     */
+    public void parse (InputSource input)
+    throws IOException, SAXException
+    {
+    if (parsing) {
+        throw new SAXException("Parser is already in use");
+    }
+    setupParser();
+    parsing = true;
+    try {
+        parser.parse(input);
+    } finally {
+        parsing = false;
+    }
+    parsing = false;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.DocumentHandler.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 document locator event.
+     *
+     * @param locator A document locator.
+     * @see org.xml.sax.ContentHandler#setDocumentLocator
+     */
+    public void setDocumentLocator (Locator locator)
+    {
+    this.locator = locator;
+    if (contentHandler != null) {
+        contentHandler.setDocumentLocator(locator);
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 start document event.
+     *
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#startDocument
+     */
+    public void startDocument ()
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.startDocument();
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 end document event.
+     *
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#endDocument
+     */
+    public void endDocument ()
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.endDocument();
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 startElement event.
+     *
+     * <p>If necessary, perform Namespace processing.</p>
+     *
+     * @param qName The qualified (prefixed) name.
+     * @param qAtts The XML attribute list (with qnames).
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     */
+    public void startElement (String qName, AttributeList qAtts)
+    throws SAXException
+    {
+                // These are exceptions from the
+                // first pass; they should be
+                // ignored if there's a second pass,
+                // but reported otherwise.
+    Vector exceptions = null;
+
+                // If we're not doing Namespace
+                // processing, dispatch this quickly.
+    if (!namespaces) {
+        if (contentHandler != null) {
+        attAdapter.setAttributeList(qAtts);
+        contentHandler.startElement("", "", qName.intern(),
+                        attAdapter);
+        }
+        return;
+    }
+
+
+                // OK, we're doing Namespace processing.
+    nsSupport.pushContext();
+    int length = qAtts.getLength();
+    
+                // First pass:  handle NS decls
+    for (int i = 0; i < length; i++) {
+        String attQName = qAtts.getName(i);
+
+        if (!attQName.startsWith("xmlns"))
+        continue;
+                // Could be a declaration...
+        String prefix;
+        int n = attQName.indexOf(':');
+
+                    // xmlns=...
+        if (n == -1 && attQName.length () == 5) {
+        prefix = "";
+        } else if (n != 5) {
+        // XML namespaces spec doesn't discuss "xmlnsf:oo"
+        // (and similarly named) attributes ... at most, warn
+        continue;
+        } else         // xmlns:foo=...
+        prefix = attQName.substring(n+1);
+
+        String value = qAtts.getValue(i);
+        if (!nsSupport.declarePrefix(prefix, value)) {
+        reportError("Illegal Namespace prefix: " + prefix);
+        continue;
+        }
+        if (contentHandler != null)
+        contentHandler.startPrefixMapping(prefix, value);
+    }
+    
+                // Second pass: copy all relevant
+                // attributes into the SAX2 AttributeList
+                // using updated prefix bindings
+    atts.clear();
+    for (int i = 0; i < length; i++) {
+        String attQName = qAtts.getName(i);
+        String type = qAtts.getType(i);
+        String value = qAtts.getValue(i);
+
+                // Declaration?
+        if (attQName.startsWith("xmlns")) {
+        String prefix;
+        int n = attQName.indexOf(':');
+
+        if (n == -1 && attQName.length () == 5) {
+            prefix = "";
+        } else if (n != 5) {
+            // XML namespaces spec doesn't discuss "xmlnsf:oo"
+            // (and similarly named) attributes ... ignore
+            prefix = null;
+        } else {
+            prefix = attQName.substring(6);
+        }
+                // Yes, decl:  report or prune
+        if (prefix != null) {
+            if (prefixes) {
+            if (uris)
+                // note funky case:  localname can be null
+                // when declaring the default prefix, and
+                // yet the uri isn't null.
+                atts.addAttribute (nsSupport.XMLNS, prefix,
+                    attQName.intern(), type, value);
+            else
+                atts.addAttribute ("", "",
+                    attQName.intern(), type, value);
+            }
+            continue;
+        }
+        } 
+
+                // Not a declaration -- report
+        try {
+        String attName[] = processName(attQName, true, true);
+        atts.addAttribute(attName[0], attName[1], attName[2],
+                  type, value);
+        } catch (SAXException e) {
+        if (exceptions == null)
+            exceptions = new Vector();
+        exceptions.addElement(e);
+        atts.addAttribute("", attQName, attQName, type, value);
+        }
+    }
+    
+    // now handle the deferred exception reports
+    if (exceptions != null && errorHandler != null) {
+        for (int i = 0; i < exceptions.size(); i++)
+        errorHandler.error((SAXParseException)
+                (exceptions.elementAt(i)));
+    }
+
+                // OK, finally report the event.
+    if (contentHandler != null) {
+        String name[] = processName(qName, false, false);
+        contentHandler.startElement(name[0], name[1], name[2], atts);
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 end element event.
+     *
+     * @param qName The qualified (prefixed) name.
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#endElement
+     */
+    public void endElement (String qName)
+    throws SAXException
+    {
+                // If we're not doing Namespace
+                // processing, dispatch this quickly.
+    if (!namespaces) {
+        if (contentHandler != null) {
+        contentHandler.endElement("", "", qName.intern());
+        }
+        return;
+    }
+
+                // Split the name.
+    String names[] = processName(qName, false, false);
+    if (contentHandler != null) {
+        contentHandler.endElement(names[0], names[1], names[2]);
+        Enumeration prefixes = nsSupport.getDeclaredPrefixes();
+        while (prefixes.hasMoreElements()) {
+        String prefix = (String)prefixes.nextElement();
+        contentHandler.endPrefixMapping(prefix);
+        }
+    }
+    nsSupport.popContext();
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 characters event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use.
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#characters
+     */
+    public void characters (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.characters(ch, start, length);
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 ignorable whitespace event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use.
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#ignorableWhitespace
+     */
+    public void ignorableWhitespace (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.ignorableWhitespace(ch, start, length);
+    }
+    }
+
+
+    /**
+     * Adapter implementation method; do not call.
+     * Adapt a SAX1 processing instruction event.
+     *
+     * @param target The processing instruction target.
+     * @param data The remainder of the processing instruction
+     * @exception SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.DocumentHandler#processingInstruction
+     */
+    public void processingInstruction (String target, String data)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.processingInstruction(target, data);
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal utility methods.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Initialize the parser before each run.
+     */
+    private void setupParser ()
+    {
+    // catch an illegal "nonsense" state.
+    if (!prefixes && !namespaces)
+        throw new IllegalStateException ();
+
+    nsSupport.reset();
+    if (uris)
+        nsSupport.setNamespaceDeclUris (true);
+
+    if (entityResolver != null) {
+        parser.setEntityResolver(entityResolver);
+    }
+    if (dtdHandler != null) {
+        parser.setDTDHandler(dtdHandler);
+    }
+    if (errorHandler != null) {
+        parser.setErrorHandler(errorHandler);
+    }
+    parser.setDocumentHandler(this);
+    locator = null;
+    }
+
+
+    /**
+     * Process a qualified (prefixed) name.
+     *
+     * <p>If the name has an undeclared prefix, use only the qname
+     * and make an ErrorHandler.error callback in case the app is
+     * interested.</p>
+     *
+     * @param qName The qualified (prefixed) name.
+     * @param isAttribute true if this is an attribute name.
+     * @return The name split into three parts.
+     * @exception SAXException The client may throw
+     *            an exception if there is an error callback.
+     */
+    private String [] processName (String qName, boolean isAttribute,
+                   boolean useException)
+    throws SAXException
+    {
+    String parts[] = nsSupport.processName(qName, nameParts,
+                           isAttribute);
+    if (parts == null) {
+        if (useException)
+        throw makeException("Undeclared prefix: " + qName);
+        reportError("Undeclared prefix: " + qName);
+        parts = new String[3];
+        parts[0] = parts[1] = "";
+        parts[2] = qName.intern();
+    }
+    return parts;
+    }
+
+
+    /**
+     * Report a non-fatal error.
+     *
+     * @param message The error message.
+     * @exception SAXException The client may throw
+     *            an exception.
+     */
+    void reportError (String message)
+    throws SAXException
+    {
+    if (errorHandler != null)
+        errorHandler.error(makeException(message));
+    }
+
+    
+    /**
+     * Construct an exception for the current context.
+     *
+     * @param message The error message.
+     */
+    private SAXParseException makeException (String message)
+    {
+    if (locator != null) {
+        return new SAXParseException(message, locator);
+    } else {
+        return new SAXParseException(message, null, null, -1, -1);
+    }
+    }
+
+
+    /**
+     * Throw an exception if we are parsing.
+     *
+     * <p>Use this method to detect illegal feature or
+     * property changes.</p>
+     *
+     * @param type The type of thing (feature or property).
+     * @param name The feature or property name.
+     * @exception SAXNotSupportedException If a
+     *            document is currently being parsed.
+     */
+    private void checkNotParsing (String type, String name)
+    throws SAXNotSupportedException
+    {
+    if (parsing) {
+        throw new SAXNotSupportedException("Cannot change " +
+                           type + ' ' +
+                           name + " while parsing");
+                           
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private NamespaceSupport nsSupport;
+    private AttributeListAdapter attAdapter;
+
+    private boolean parsing = false;
+    private String nameParts[] = new String[3];
+
+    private Parser parser = null;
+
+    private AttributesImpl atts = null;
+
+                // Features
+    private boolean namespaces = true;
+    private boolean prefixes = false;
+    private boolean uris = false;
+
+                // Properties
+
+                // Handlers
+    Locator locator;
+
+    EntityResolver entityResolver = null;
+    DTDHandler dtdHandler = null;
+    ContentHandler contentHandler = null;
+    ErrorHandler errorHandler = null;
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Inner class to wrap an AttributeList when not doing NS proc.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
+     *
+     * <p>This class is in the Public Domain, and comes with NO
+     * WARRANTY of any kind.</p>
+     *
+     * <p>This wrapper class is used only when Namespace support
+     * is disabled -- it provides pretty much a direct mapping
+     * from SAX1 to SAX2, except that names and types are 
+     * interned whenever requested.</p>
+     */
+    final class AttributeListAdapter implements Attributes
+    {
+
+    /**
+     * Construct a new adapter.
+     */
+    AttributeListAdapter ()
+    {
+    }
+
+
+    /**
+     * Set the embedded AttributeList.
+     *
+     * <p>This method must be invoked before any of the others
+     * can be used.</p>
+     *
+     * @param The SAX1 attribute list (with qnames).
+     */
+    void setAttributeList (AttributeList qAtts)
+    {
+        this.qAtts = qAtts;
+    }
+
+
+    /**
+     * Return the length of the attribute list.
+     *
+     * @return The number of attributes in the list.
+     * @see org.xml.sax.Attributes#getLength
+     */
+    public int getLength ()
+    {
+        return qAtts.getLength();
+    }
+
+
+    /**
+     * Return the Namespace URI of the specified attribute.
+     *
+     * @param The attribute's index.
+     * @return Always the empty string.
+     * @see org.xml.sax.Attributes#getURI
+     */
+    public String getURI (int i)
+    {
+        return "";
+    }
+
+
+    /**
+     * Return the local name of the specified attribute.
+     *
+     * @param The attribute's index.
+     * @return Always the empty string.
+     * @see org.xml.sax.Attributes#getLocalName
+     */
+    public String getLocalName (int i)
+    {
+        return "";
+    }
+
+
+    /**
+     * Return the qualified (prefixed) name of the specified attribute.
+     *
+     * @param The attribute's index.
+     * @return The attribute's qualified name, internalized.
+     */
+    public String getQName (int i)
+    {
+        return qAtts.getName(i).intern();
+    }
+
+
+    /**
+     * Return the type of the specified attribute.
+     *
+     * @param The attribute's index.
+     * @return The attribute's type as an internalized string.
+     */
+    public String getType (int i)
+    {
+        return qAtts.getType(i).intern();
+    }
+
+
+    /**
+     * Return the value of the specified attribute.
+     *
+     * @param The attribute's index.
+     * @return The attribute's value.
+     */
+    public String getValue (int i)
+    {
+        return qAtts.getValue(i);
+    }
+
+
+    /**
+     * Look up an attribute index by Namespace name.
+     *
+     * @param uri The Namespace URI or the empty string.
+     * @param localName The local name.
+     * @return The attributes index, or -1 if none was found.
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
+     */
+    public int getIndex (String uri, String localName)
+    {
+        return -1;
+    }
+
+
+    /**
+     * Look up an attribute index by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attributes index, or -1 if none was found.
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String)
+     */
+    public int getIndex (String qName)
+    {
+        int max = atts.getLength();
+        for (int i = 0; i < max; i++) {
+        if (qAtts.getName(i).equals(qName)) {
+            return i;
+        }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Look up the type of an attribute by Namespace name.
+     *
+     * @param uri The Namespace URI
+     * @param localName The local name.
+     * @return The attribute's type as an internalized string.
+     */
+    public String getType (String uri, String localName)
+    {
+        return null;
+    }
+
+
+    /**
+     * Look up the type of an attribute by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attribute's type as an internalized string.
+     */
+    public String getType (String qName)
+    {
+        return qAtts.getType(qName).intern();
+    }
+
+
+    /**
+     * Look up the value of an attribute by Namespace name.
+     *
+     * @param uri The Namespace URI
+     * @param localName The local name.
+     * @return The attribute's value.
+     */
+    public String getValue (String uri, String localName)
+    {
+        return null;
+    }
+
+
+    /**
+     * Look up the value of an attribute by qualified (prefixed) name.
+     *
+     * @param qName The qualified name.
+     * @return The attribute's value.
+     */
+    public String getValue (String qName)
+    {
+        return qAtts.getValue(qName);
+    }
+
+    private AttributeList qAtts;
+    }
+}
+
+// end of ParserAdapter.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java b/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java
new file mode 100644
index 0000000..ffe2a60
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java
@@ -0,0 +1,133 @@
+// SAX parser factory.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ParserFactory.java,v 1.7 2002/01/30 20:52:36 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import java.lang.ClassNotFoundException;
+import java.lang.IllegalAccessException;
+import java.lang.InstantiationException;
+import java.lang.SecurityException;
+import java.lang.ClassCastException;
+
+import org.xml.sax.Parser;
+
+
+/**
+ * Java-specific class for dynamically loading SAX parsers.
+ *
+ * <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> This class is designed to work with the now-deprecated
+ * SAX1 {@link org.xml.sax.Parser Parser} class.  SAX2 applications should use
+ * {@link org.xml.sax.helpers.XMLReaderFactory XMLReaderFactory} instead.</p>
+ *
+ * <p>ParserFactory is not part of the platform-independent definition
+ * of SAX; it is an additional convenience class designed
+ * specifically for Java XML application writers.  SAX applications
+ * can use the static methods in this class to allocate a SAX parser
+ * dynamically at run-time based either on the value of the
+ * `org.xml.sax.parser' system property or on a string containing the class
+ * name.</p>
+ *
+ * <p>Note that the application still requires an XML parser that
+ * implements SAX1.</p>
+ *
+ * @deprecated This class works with the deprecated
+ *             {@link org.xml.sax.Parser Parser}
+ *             interface.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class ParserFactory {
+    
+    
+    /**
+     * Private null constructor.
+     */
+    private ParserFactory ()
+    {
+    }
+    
+    
+    /**
+     * Create a new SAX parser using the `org.xml.sax.parser' system property.
+     *
+     * <p>The named class must exist and must implement the
+     * {@link org.xml.sax.Parser Parser} interface.</p>
+     * 
+     * @return the newly created parser.
+     *
+     * @exception java.lang.NullPointerException There is no value
+     *            for the `org.xml.sax.parser' system property.
+     * @exception java.lang.ClassNotFoundException The SAX parser
+     *            class was not found (check your CLASSPATH).
+     * @exception IllegalAccessException The SAX parser class was
+     *            found, but you do not have permission to load
+     *            it.
+     * @exception InstantiationException The SAX parser class was
+     *            found but could not be instantiated.
+     * @exception java.lang.ClassCastException The SAX parser class
+     *            was found and instantiated, but does not implement
+     *            org.xml.sax.Parser.
+     * @see #makeParser(java.lang.String)
+     * @see org.xml.sax.Parser
+     */
+    public static Parser makeParser ()
+    throws ClassNotFoundException,
+    IllegalAccessException, 
+    InstantiationException,
+    NullPointerException,
+    ClassCastException
+    {
+    String className = System.getProperty("org.xml.sax.parser");
+    if (className == null) {
+        throw new NullPointerException("No value for sax.parser property");
+    } else {
+        return makeParser(className);
+    }
+    }
+    
+    
+    /**
+     * Create a new SAX parser object using the class name provided.
+     *
+     * <p>The named class must exist and must implement the
+     * {@link org.xml.sax.Parser Parser} interface.</p>
+     *
+     * @return the newly created parser.
+     *
+     * @param className A string containing the name of the
+     *                  SAX parser class.
+     * @exception java.lang.ClassNotFoundException The SAX parser
+     *            class was not found (check your CLASSPATH).
+     * @exception IllegalAccessException The SAX parser class was
+     *            found, but you do not have permission to load
+     *            it.
+     * @exception InstantiationException The SAX parser class was
+     *            found but could not be instantiated.
+     * @exception java.lang.ClassCastException The SAX parser class
+     *            was found and instantiated, but does not implement
+     *            org.xml.sax.Parser.
+     * @see #makeParser()
+     * @see org.xml.sax.Parser
+     */
+    public static Parser makeParser (String className)
+    throws ClassNotFoundException,
+    IllegalAccessException, 
+    InstantiationException,
+    ClassCastException
+    {
+    return (Parser) NewInstance.newInstance (
+        NewInstance.getClassLoader (), className);
+    }
+    
+}
+
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java b/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
new file mode 100644
index 0000000..68e2579
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
@@ -0,0 +1,715 @@
+// XMLFilterImpl.java - base SAX2 filter implementation.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: XMLFilterImpl.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXNotRecognizedException;
+
+
+/**
+ * Base class for deriving an XML filter.
+ *
+ * <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 designed to sit between an {@link org.xml.sax.XMLReader
+ * XMLReader} and the client application's event handlers.  By default, it
+ * does nothing but pass requests up to the reader and events
+ * on to the handlers unmodified, but subclasses can override
+ * specific methods to modify the event stream or the configuration
+ * requests as they pass through.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.XMLFilter
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ContentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class XMLFilterImpl
+    implements XMLFilter, EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructors.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct an empty XML filter, with no parent.
+     *
+     * <p>This filter will have no parent: you must assign a parent
+     * before you start a parse or do any configuration with
+     * setFeature or setProperty, unless you use this as a pure event
+     * consumer rather than as an {@link XMLReader}.</p>
+     *
+     * @see org.xml.sax.XMLReader#setFeature
+     * @see org.xml.sax.XMLReader#setProperty
+     * @see #setParent
+     */
+    public XMLFilterImpl ()
+    {
+    super();
+    }
+
+
+    /**
+     * Construct an XML filter with the specified parent.
+     * 
+     * @param parent the XML reader from which this filter receives its events. 
+     *
+     * @see #setParent
+     * @see #getParent
+     */
+    public XMLFilterImpl (XMLReader parent)
+    {
+        super();
+    setParent(parent);
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.XMLFilter.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Set the parent reader.
+     *
+     * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 
+     * this filter will obtain its events and to which it will pass its 
+     * configuration requests.  The parent may itself be another filter.</p>
+     *
+     * <p>If there is no parent reader set, any attempt to parse
+     * or to set or get a feature or property will fail.</p>
+     *
+     * @param parent The parent XML reader.
+     * @see #getParent
+     */
+    public void setParent (XMLReader parent)
+    {
+    this.parent = parent;
+    }
+
+
+    /**
+     * Get the parent reader.
+     *
+     * @return The parent XML reader, or null if none is set.
+     * @see #setParent
+     */
+    public XMLReader getParent ()
+    {
+    return parent;
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.XMLReader.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Set the value of a feature.
+     *
+     * <p>This will always fail if the parent is null.</p>
+     *
+     * @param name The feature name.
+     * @param value The requested feature value.
+     * @exception org.xml.sax.SAXNotRecognizedException If the feature
+     *            value can't be assigned or retrieved from the parent.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            parent recognizes the feature name but 
+     *            cannot set the requested value.
+     */
+    public void setFeature (String name, boolean value)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (parent != null) {
+        parent.setFeature(name, value);
+    } else {
+        throw new SAXNotRecognizedException("Feature: " + name);
+    }
+    }
+
+
+    /**
+     * Look up the value of a feature.
+     *
+     * <p>This will always fail if the parent is null.</p>
+     *
+     * @param name The feature name.
+     * @return The current value of the feature.
+     * @exception org.xml.sax.SAXNotRecognizedException If the feature
+     *            value can't be assigned or retrieved from the parent.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            parent recognizes the feature name but 
+     *            cannot determine its value at this time.
+     */
+    public boolean getFeature (String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (parent != null) {
+        return parent.getFeature(name);
+    } else {
+        throw new SAXNotRecognizedException("Feature: " + name);
+    }
+    }
+
+
+    /**
+     * Set the value of a property.
+     *
+     * <p>This will always fail if the parent is null.</p>
+     *
+     * @param name The property name.
+     * @param value The requested property value.
+     * @exception org.xml.sax.SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved from the parent.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            parent recognizes the property name but 
+     *            cannot set the requested value.
+     */
+    public void setProperty (String name, Object value)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (parent != null) {
+        parent.setProperty(name, value);
+    } else {
+        throw new SAXNotRecognizedException("Property: " + name);
+    }
+    }
+
+
+    /**
+     * Look up the value of a property.
+     *
+     * @param name The property name.
+     * @return The current value of the property.
+     * @exception org.xml.sax.SAXNotRecognizedException If the property
+     *            value can't be assigned or retrieved from the parent.
+     * @exception org.xml.sax.SAXNotSupportedException When the
+     *            parent recognizes the property name but 
+     *            cannot determine its value at this time.
+     */
+    public Object getProperty (String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+    if (parent != null) {
+        return parent.getProperty(name);
+    } else {
+        throw new SAXNotRecognizedException("Property: " + name);
+    }
+    }
+
+
+    /**
+     * Set the entity resolver.
+     *
+     * @param resolver The new entity resolver.
+     */
+    public void setEntityResolver (EntityResolver resolver)
+    {
+    entityResolver = resolver;
+    }
+
+
+    /**
+     * Get the current entity resolver.
+     *
+     * @return The current entity resolver, or null if none was set.
+     */
+    public EntityResolver getEntityResolver ()
+    {
+    return entityResolver;
+    }
+
+
+    /**
+     * Set the DTD event handler.
+     *
+     * @param handler the new DTD handler
+     */
+    public void setDTDHandler (DTDHandler handler)
+    {
+    dtdHandler = handler;
+    }
+
+
+    /**
+     * Get the current DTD event handler.
+     *
+     * @return The current DTD handler, or null if none was set.
+     */
+    public DTDHandler getDTDHandler ()
+    {
+    return dtdHandler;
+    }
+
+
+    /**
+     * Set the content event handler.
+     *
+     * @param handler the new content handler
+     */
+    public void setContentHandler (ContentHandler handler)
+    {
+    contentHandler = handler;
+    }
+
+
+    /**
+     * Get the content event handler.
+     *
+     * @return The current content handler, or null if none was set.
+     */
+    public ContentHandler getContentHandler ()
+    {
+    return contentHandler;
+    }
+
+
+    /**
+     * Set the error event handler.
+     *
+     * @param handler the new error handler
+     */
+    public void setErrorHandler (ErrorHandler handler)
+    {
+    errorHandler = handler;
+    }
+
+
+    /**
+     * Get the current error event handler.
+     *
+     * @return The current error handler, or null if none was set.
+     */
+    public ErrorHandler getErrorHandler ()
+    {
+    return errorHandler;
+    }
+
+
+    /**
+     * Parse a document.
+     *
+     * @param input The input source for the document entity.
+     * @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.
+     */
+    public void parse (InputSource input)
+    throws SAXException, IOException
+    {
+    setupParse();
+    parent.parse(input);
+    }
+
+
+    /**
+     * Parse a document.
+     *
+     * @param systemId The system identifier as a fully-qualified 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.
+     */
+    public void parse (String systemId)
+    throws SAXException, IOException
+    {
+    parse(new InputSource(systemId));
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.EntityResolver.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Filter an external entity resolution.
+     *
+     * @param publicId The entity's public identifier, or null.
+     * @param systemId The entity's system identifier.
+     * @return A new InputSource or null for the default.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     * @exception java.io.IOException The client may throw an
+     *            I/O-related exception while obtaining the
+     *            new InputSource.
+     */
+    public InputSource resolveEntity (String publicId, String systemId)
+    throws SAXException, IOException
+    {
+    if (entityResolver != null) {
+        return entityResolver.resolveEntity(publicId, systemId);
+    } else {
+        return null;
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.DTDHandler.
+    ////////////////////////////////////////////////////////////////////
+
+    
+    /**
+     * Filter a notation declaration event.
+     *
+     * @param name The notation name.
+     * @param publicId The notation's public identifier, or null.
+     * @param systemId The notation's system identifier, or null.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void notationDecl (String name, String publicId, String systemId)
+    throws SAXException
+    {
+    if (dtdHandler != null) {
+        dtdHandler.notationDecl(name, publicId, systemId);
+    }
+    }
+
+    
+    /**
+     * Filter an unparsed entity declaration event.
+     *
+     * @param name The entity name.
+     * @param publicId The entity's public identifier, or null.
+     * @param systemId The entity's system identifier, or null.
+     * @param notationName The name of the associated notation.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void unparsedEntityDecl (String name, String publicId,
+                    String systemId, String notationName)
+    throws SAXException
+    {
+    if (dtdHandler != null) {
+        dtdHandler.unparsedEntityDecl(name, publicId, systemId,
+                      notationName);
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.ContentHandler.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Filter a new document locator event.
+     *
+     * @param locator The document locator.
+     */
+    public void setDocumentLocator (Locator locator)
+    {
+    this.locator = locator;
+    if (contentHandler != null) {
+        contentHandler.setDocumentLocator(locator);
+    }
+    }
+
+
+    /**
+     * Filter a start document event.
+     *
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void startDocument ()
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.startDocument();
+    }
+    }
+
+
+    /**
+     * Filter an end document event.
+     *
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void endDocument ()
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.endDocument();
+    }
+    }
+
+
+    /**
+     * Filter a start Namespace prefix mapping event.
+     *
+     * @param prefix The Namespace prefix.
+     * @param uri The Namespace URI.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void startPrefixMapping (String prefix, String uri)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.startPrefixMapping(prefix, uri);
+    }
+    }
+
+
+    /**
+     * Filter an end Namespace prefix mapping event.
+     *
+     * @param prefix The Namespace prefix.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void endPrefixMapping (String prefix)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.endPrefixMapping(prefix);
+    }
+    }
+
+
+    /**
+     * Filter a start element event.
+     *
+     * @param uri The element's Namespace URI, or the empty string.
+     * @param localName The element's local name, or the empty string.
+     * @param qName The element's qualified (prefixed) name, or the empty
+     *        string.
+     * @param atts The element's attributes.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void startElement (String uri, String localName, String qName,
+                  Attributes atts)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.startElement(uri, localName, qName, atts);
+    }
+    }
+
+
+    /**
+     * Filter an end element event.
+     *
+     * @param uri The element's Namespace URI, or the empty string.
+     * @param localName The element's local name, or the empty string.
+     * @param qName The element's qualified (prefixed) name, or the empty
+     *        string.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void endElement (String uri, String localName, String qName)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.endElement(uri, localName, qName);
+    }
+    }
+
+
+    /**
+     * Filter a character data event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use from the array.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void characters (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.characters(ch, start, length);
+    }
+    }
+
+
+    /**
+     * Filter an ignorable whitespace event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use from the array.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void ignorableWhitespace (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.ignorableWhitespace(ch, start, length);
+    }
+    }
+
+
+    /**
+     * Filter a processing instruction event.
+     *
+     * @param target The processing instruction target.
+     * @param data The text following the target.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void processingInstruction (String target, String data)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.processingInstruction(target, data);
+    }
+    }
+
+
+    /**
+     * Filter a skipped entity event.
+     *
+     * @param name The name of the skipped entity.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void skippedEntity (String name)
+    throws SAXException
+    {
+    if (contentHandler != null) {
+        contentHandler.skippedEntity(name);
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.ErrorHandler.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Filter a warning event.
+     *
+     * @param e The warning as an exception.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void warning (SAXParseException e)
+    throws SAXException
+    {
+    if (errorHandler != null) {
+        errorHandler.warning(e);
+    }
+    }
+
+
+    /**
+     * Filter an error event.
+     *
+     * @param e The error as an exception.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void error (SAXParseException e)
+    throws SAXException
+    {
+    if (errorHandler != null) {
+        errorHandler.error(e);
+    }
+    }
+
+
+    /**
+     * Filter a fatal error event.
+     *
+     * @param e The error as an exception.
+     * @exception org.xml.sax.SAXException The client may throw
+     *            an exception during processing.
+     */
+    public void fatalError (SAXParseException e)
+    throws SAXException
+    {
+    if (errorHandler != null) {
+        errorHandler.fatalError(e);
+    }
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal methods.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Set up before a parse.
+     *
+     * <p>Before every parse, check whether the parent is
+     * non-null, and re-register the filter for all of the 
+     * events.</p>
+     */
+    private void setupParse ()
+    {
+    if (parent == null) {
+        throw new NullPointerException("No parent for filter");
+    }
+    parent.setEntityResolver(this);
+    parent.setDTDHandler(this);
+    parent.setContentHandler(this);
+    parent.setErrorHandler(this);
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private XMLReader parent = null;
+    private Locator locator = null;
+    private EntityResolver entityResolver = null;
+    private DTDHandler dtdHandler = null;
+    private ContentHandler contentHandler = null;
+    private ErrorHandler errorHandler = null;
+
+}
+
+// end of XMLFilterImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java b/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
new file mode 100644
index 0000000..cc8f431
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
@@ -0,0 +1,538 @@
+// XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY!  This class is in the public domain.
+// $Id: XMLReaderAdapter.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.xml.sax.Parser;    // deprecated
+import org.xml.sax.Locator;
+import org.xml.sax.InputSource;
+import org.xml.sax.AttributeList; // deprecated
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler; // deprecated
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXNotSupportedException;
+
+
+/**
+ * Adapt a SAX2 XMLReader as a SAX1 Parser.
+ *
+ * <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 wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
+ * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}.  The XMLReader 
+ * must support a true value for the 
+ * http://xml.org/sax/features/namespace-prefixes property or parsing will fail
+ * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader 
+ * supports a false value for the http://xml.org/sax/features/namespaces 
+ * property, that will also be used to improve efficiency.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Parser
+ * @see org.xml.sax.XMLReader
+ */
+public class XMLReaderAdapter implements Parser, ContentHandler
+{
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Constructor.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new adapter.
+     *
+     * <p>Use the "org.xml.sax.driver" property to locate the SAX2
+     * driver to embed.</p>
+     *
+     * @exception org.xml.sax.SAXException If the embedded driver
+     *            cannot be instantiated or if the
+     *            org.xml.sax.driver property is not specified.
+     */
+    public XMLReaderAdapter ()
+      throws SAXException
+    {
+    setup(XMLReaderFactory.createXMLReader());
+    }
+
+
+    /**
+     * Create a new adapter.
+     *
+     * <p>Create a new adapter, wrapped around a SAX2 XMLReader.
+     * The adapter will make the XMLReader act like a SAX1
+     * Parser.</p>
+     *
+     * @param xmlReader The SAX2 XMLReader to wrap.
+     * @exception java.lang.NullPointerException If the argument is null.
+     */
+    public XMLReaderAdapter (XMLReader xmlReader)
+    {
+    setup(xmlReader);
+    }
+
+
+
+    /**
+     * Internal setup.
+     *
+     * @param xmlReader The embedded XMLReader.
+     */
+    private void setup (XMLReader xmlReader)
+    {
+    if (xmlReader == null) {
+        throw new NullPointerException("XMLReader must not be null");
+    }
+    this.xmlReader = xmlReader;
+    qAtts = new AttributesAdapter();
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.Parser.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Set the locale for error reporting.
+     *
+     * <p>This is not supported in SAX2, and will always throw
+     * an exception.</p>
+     *
+     * @param locale the locale for error reporting.
+     * @see org.xml.sax.Parser#setLocale
+     * @exception org.xml.sax.SAXException Thrown unless overridden.
+     */
+    public void setLocale (Locale locale)
+    throws SAXException
+    {
+    throw new SAXNotSupportedException("setLocale not supported");
+    }
+
+
+    /**
+     * Register the entity resolver.
+     *
+     * @param resolver The new resolver.
+     * @see org.xml.sax.Parser#setEntityResolver
+     */
+    public void setEntityResolver (EntityResolver resolver)
+    {
+    xmlReader.setEntityResolver(resolver);
+    }
+
+
+    /**
+     * Register the DTD event handler.
+     *
+     * @param handler The new DTD event handler.
+     * @see org.xml.sax.Parser#setDTDHandler
+     */
+    public void setDTDHandler (DTDHandler handler)
+    {
+    xmlReader.setDTDHandler(handler);
+    }
+
+
+    /**
+     * Register the SAX1 document event handler.
+     *
+     * <p>Note that the SAX1 document handler has no Namespace
+     * support.</p>
+     *
+     * @param handler The new SAX1 document event handler.
+     * @see org.xml.sax.Parser#setDocumentHandler
+     */
+    public void setDocumentHandler (DocumentHandler handler)
+    {
+    documentHandler = handler;
+    }
+
+
+    /**
+     * Register the error event handler.
+     *
+     * @param handler The new error event handler.
+     * @see org.xml.sax.Parser#setErrorHandler
+     */
+    public void setErrorHandler (ErrorHandler handler)
+    {
+    xmlReader.setErrorHandler(handler);
+    }
+
+
+    /**
+     * Parse the document.
+     *
+     * <p>This method will throw an exception if the embedded
+     * XMLReader does not support the 
+     * http://xml.org/sax/features/namespace-prefixes property.</p>
+     *
+     * @param systemId The absolute URL of the document.
+     * @exception java.io.IOException If there is a problem reading
+     *            the raw content of the document.
+     * @exception org.xml.sax.SAXException If there is a problem
+     *            processing the document.
+     * @see #parse(org.xml.sax.InputSource)
+     * @see org.xml.sax.Parser#parse(java.lang.String)
+     */
+    public void parse (String systemId)
+    throws IOException, SAXException
+    {
+    parse(new InputSource(systemId));
+    }
+
+
+    /**
+     * Parse the document.
+     *
+     * <p>This method will throw an exception if the embedded
+     * XMLReader does not support the 
+     * http://xml.org/sax/features/namespace-prefixes property.</p>
+     *
+     * @param input An input source for the document.
+     * @exception java.io.IOException If there is a problem reading
+     *            the raw content of the document.
+     * @exception org.xml.sax.SAXException If there is a problem
+     *            processing the document.
+     * @see #parse(java.lang.String)
+     * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
+     */
+    public void parse (InputSource input)
+    throws IOException, SAXException
+    {
+    setupXMLReader();
+    xmlReader.parse(input);
+    }
+
+
+    /**
+     * Set up the XML reader.
+     */
+    private void setupXMLReader ()
+    throws SAXException
+    {
+    xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+    try {
+        xmlReader.setFeature("http://xml.org/sax/features/namespaces",
+                             false);
+    } catch (SAXException e) {
+        // NO OP: it's just extra information, and we can ignore it
+    }
+    xmlReader.setContentHandler(this);
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.xml.sax.ContentHandler.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Set a document locator.
+     *
+     * @param locator The document locator.
+     * @see org.xml.sax.ContentHandler#setDocumentLocator
+     */
+    public void setDocumentLocator (Locator locator)
+    {
+    if (documentHandler != null)
+        documentHandler.setDocumentLocator(locator);
+    }
+
+
+    /**
+     * Start document event.
+     *
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#startDocument
+     */
+    public void startDocument ()
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.startDocument();
+    }
+
+
+    /**
+     * End document event.
+     *
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#endDocument
+     */
+    public void endDocument ()
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.endDocument();
+    }
+
+
+    /**
+     * Adapt a SAX2 start prefix mapping event.
+     *
+     * @param prefix The prefix being mapped.
+     * @param uri The Namespace URI being mapped to.
+     * @see org.xml.sax.ContentHandler#startPrefixMapping
+     */
+    public void startPrefixMapping (String prefix, String uri)
+    {
+    }
+
+
+    /**
+     * Adapt a SAX2 end prefix mapping event.
+     *
+     * @param prefix The prefix being mapped.
+     * @see org.xml.sax.ContentHandler#endPrefixMapping
+     */
+    public void endPrefixMapping (String prefix)
+    {
+    }
+
+
+    /**
+     * Adapt a SAX2 start element event.
+     *
+     * @param uri The Namespace URI.
+     * @param localName The Namespace local name.
+     * @param qName The qualified (prefixed) name.
+     * @param atts The SAX2 attributes.
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#endDocument
+     */
+    public void startElement (String uri, String localName,
+                  String qName, Attributes atts)
+    throws SAXException
+    {
+    if (documentHandler != null) {
+        qAtts.setAttributes(atts);
+        documentHandler.startElement(qName, qAtts);
+    }
+    }
+
+
+    /**
+     * Adapt a SAX2 end element event.
+     *
+     * @param uri The Namespace URI.
+     * @param localName The Namespace local name.
+     * @param qName The qualified (prefixed) name.
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#endElement
+     */
+    public void endElement (String uri, String localName,
+                String qName)
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.endElement(qName);
+    }
+
+
+    /**
+     * Adapt a SAX2 characters event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use.
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#characters
+     */
+    public void characters (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.characters(ch, start, length);
+    }
+
+
+    /**
+     * Adapt a SAX2 ignorable whitespace event.
+     *
+     * @param ch An array of characters.
+     * @param start The starting position in the array.
+     * @param length The number of characters to use.
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace
+     */
+    public void ignorableWhitespace (char ch[], int start, int length)
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.ignorableWhitespace(ch, start, length);
+    }
+
+
+    /**
+     * Adapt a SAX2 processing instruction event.
+     *
+     * @param target The processing instruction target.
+     * @param data The remainder of the processing instruction
+     * @exception org.xml.sax.SAXException The client may raise a
+     *            processing exception.
+     * @see org.xml.sax.ContentHandler#processingInstruction
+     */
+    public void processingInstruction (String target, String data)
+    throws SAXException
+    {
+    if (documentHandler != null)
+        documentHandler.processingInstruction(target, data);
+    }
+
+
+    /**
+     * Adapt a SAX2 skipped entity event.
+     *
+     * @param name The name of the skipped entity.
+     * @see org.xml.sax.ContentHandler#skippedEntity
+     * @exception org.xml.sax.SAXException Throwable by subclasses.
+     */
+    public void skippedEntity (String name)
+    throws SAXException
+    {
+    }
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    XMLReader xmlReader;
+    DocumentHandler documentHandler;
+    AttributesAdapter qAtts;
+
+
+
+    ////////////////////////////////////////////////////////////////////
+    // Internal class.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Internal class to wrap a SAX2 Attributes object for SAX1.
+     */
+    final class AttributesAdapter implements AttributeList
+    {
+    AttributesAdapter ()
+    {
+    }
+
+
+    /**
+     * Set the embedded Attributes object.
+     *
+     * @param The embedded SAX2 Attributes.
+     */ 
+    void setAttributes (Attributes attributes)
+    {
+        this.attributes = attributes;
+    }
+
+
+    /**
+     * Return the number of attributes.
+     *
+     * @return The length of the attribute list.
+     * @see org.xml.sax.AttributeList#getLength
+     */
+    public int getLength ()
+    {
+        return attributes.getLength();
+    }
+
+
+    /**
+     * Return the qualified (prefixed) name of an attribute by position.
+     *
+     * @return The qualified name.
+     * @see org.xml.sax.AttributeList#getName
+     */
+    public String getName (int i)
+    {
+        return attributes.getQName(i);
+    }
+
+
+    /**
+     * Return the type of an attribute by position.
+     *
+     * @return The type.
+     * @see org.xml.sax.AttributeList#getType(int)
+     */
+    public String getType (int i)
+    {
+        return attributes.getType(i);
+    }
+
+
+    /**
+     * Return the value of an attribute by position.
+     *
+     * @return The value.
+     * @see org.xml.sax.AttributeList#getValue(int)
+     */
+    public String getValue (int i)
+    {
+        return attributes.getValue(i);
+    }
+
+
+    /**
+     * Return the type of an attribute by qualified (prefixed) name.
+     *
+     * @return The type.
+     * @see org.xml.sax.AttributeList#getType(java.lang.String)
+     */
+    public String getType (String qName)
+    {
+        return attributes.getType(qName);
+    }
+
+
+    /**
+     * Return the value of an attribute by qualified (prefixed) name.
+     *
+     * @return The value.
+     * @see org.xml.sax.AttributeList#getValue(java.lang.String)
+     */
+    public String getValue (String qName)
+    {
+        return attributes.getValue(qName);
+    }
+
+    private Attributes attributes;
+    }
+
+}
+
+// end of XMLReaderAdapter.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
new file mode 100644
index 0000000..96151a1
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
@@ -0,0 +1,206 @@
+// XMLReaderFactory.java - factory for creating a new reader.
+// http://www.saxproject.org
+// Written by David Megginson
+// and by David Brownell
+// NO WARRANTY!  This class is in the Public Domain.
+// $Id: XMLReaderFactory.java,v 1.10 2002/04/22 01:00:13 dbrownell Exp $
+
+package org.xml.sax.helpers;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Factory for creating an XML reader.
+ *
+ * <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 contains static methods for creating an XML reader
+ * from an explicit class name, or based on runtime defaults:</p>
+ *
+ * <pre>
+ * try {
+ *   XMLReader myReader = XMLReaderFactory.createXMLReader();
+ * } catch (SAXException e) {
+ *   System.err.println(e.getMessage());
+ * }
+ * </pre>
+ *
+ * <p><strong>Note to Distributions bundled with parsers:</strong>
+ * You should modify the implementation of the no-arguments
+ * <em>createXMLReader</em> to handle cases where the external
+ * configuration mechanisms aren't set up.  That method should do its
+ * best to return a parser when one is in the class path, even when
+ * nothing bound its class name to <code>org.xml.sax.driver</code> so
+ * those configuration mechanisms would see it.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson, David Brownell
+ * @version 2.0.1 (sax2r2)
+ */
+final public class XMLReaderFactory
+{
+    /**
+     * Private constructor.
+     *
+     * <p>This constructor prevents the class from being instantiated.</p>
+     */
+    private XMLReaderFactory ()
+    {
+    }
+
+    private static final String property = "org.xml.sax.driver";
+
+    /**
+     * Attempt to create an XMLReader from system defaults.
+     * In environments which can support it, the name of the XMLReader
+     * class is determined by trying each these options in order, and
+     * using the first one which succeeds:</p> <ul>
+     *
+     * <li>If the system property <code>org.xml.sax.driver</code>
+     * has a value, that is used as an XMLReader class name. </li>
+     *
+     * <li>The JAR "Services API" is used to look for a class name
+     * in the <em>META-INF/services/org.xml.sax.driver</em> file in
+     * jarfiles available to the runtime.</li>
+     *
+     * <li> SAX parser distributions are strongly encouraged to provide
+     * a default XMLReader class name that will take effect only when
+     * previous options (on this list) are not successful.</li>
+     *
+     * <li>Finally, if {@link ParserFactory#makeParser()} can
+     * return a system default SAX1 parser, that parser is wrapped in
+     * a {@link ParserAdapter}.  (This is a migration aid for SAX1
+     * environments, where the <code>org.xml.sax.parser</code> system
+     * property will often be usable.) </li>
+     *
+     * </ul>
+     *
+     * <p> In environments such as small embedded systems, which can not
+     * support that flexibility, other mechanisms to determine the default
+     * may be used. </p>
+     *
+     * <p>Note that many Java environments allow system properties to be
+     * initialized on a command line.  This means that <em>in most cases</em>
+     * setting a good value for that property ensures that calls to this
+     * method will succeed, except when security policies intervene.
+     * This will also maximize application portability to older SAX
+     * environments, with less robust implementations of this method.
+     * </p>
+     *
+     * @return A new XMLReader.
+     * @exception org.xml.sax.SAXException If no default XMLReader class
+     *            can be identified and instantiated.
+     * @see #createXMLReader(java.lang.String)
+     */
+    public static XMLReader createXMLReader ()
+    throws SAXException
+    {
+    String        className = null;
+    ClassLoader    loader = NewInstance.getClassLoader ();
+    
+    // 1. try the JVM-instance-wide system property
+    try { className = System.getProperty (property); }
+    catch (RuntimeException e) { /* normally fails for applets */ }
+
+    // 2. if that fails, try META-INF/services/
+    if (className == null) {
+        try {
+        String        service = "META-INF/services/" + property;
+        InputStream    in;
+        BufferedReader    reader;
+
+        if (loader == null)
+            in = ClassLoader.getSystemResourceAsStream (service);
+        else
+            in = loader.getResourceAsStream (service);
+
+        if (in != null) {
+            // BEGIN android-modified
+            reader = new BufferedReader (
+                new InputStreamReader (in, "UTF8"), 8192);
+            // END android-modified
+            className = reader.readLine ();
+            in.close ();
+        }
+        } catch (Exception e) {
+        }
+    }
+
+    // 3. Distro-specific fallback
+    if (className == null) {
+// BEGIN DISTRIBUTION-SPECIFIC
+
+        // EXAMPLE:
+        // className = "com.example.sax.XmlReader";
+        // or a $JAVA_HOME/jre/lib/*properties setting...
+
+// END DISTRIBUTION-SPECIFIC
+    }
+    
+    // do we know the XMLReader implementation class yet?
+    if (className != null)
+        return loadClass (loader, className);
+
+    // 4. panic -- adapt any SAX1 parser
+    try {
+        return new ParserAdapter (ParserFactory.makeParser ());
+    } catch (Exception e) {
+        throw new SAXException ("Can't create default XMLReader; "
+            + "is system property org.xml.sax.driver set?");
+    }
+    }
+
+
+    /**
+     * Attempt to create an XML reader from a class name.
+     *
+     * <p>Given a class name, this method attempts to load
+     * and instantiate the class as an XML reader.</p>
+     * 
+     * @param className the name of the class that should be instantiated.
+     *
+     * <p>Note that this method will not be usable in environments where
+     * the caller (perhaps an applet) is not permitted to load classes
+     * dynamically.</p>
+     *
+     * @return A new XML reader.
+     * @exception org.xml.sax.SAXException If the class cannot be
+     *            loaded, instantiated, and cast to XMLReader.
+     * @see #createXMLReader()
+     */
+    public static XMLReader createXMLReader (String className)
+    throws SAXException
+    {
+    return loadClass (NewInstance.getClassLoader (), className);
+    }
+
+    private static XMLReader loadClass (ClassLoader loader, String className)
+    throws SAXException
+    {
+    try {
+        return (XMLReader) NewInstance.newInstance (loader, className);
+    } catch (ClassNotFoundException e1) {
+        throw new SAXException("SAX2 driver class " + className +
+                   " not found", e1);
+    } catch (IllegalAccessException e2) {
+        throw new SAXException("SAX2 driver class " + className +
+                   " found but cannot be loaded", e2);
+    } catch (InstantiationException e3) {
+        throw new SAXException("SAX2 driver class " + className +
+       " loaded but cannot be instantiated (no empty public constructor?)",
+                   e3);
+    } catch (ClassCastException e4) {
+        throw new SAXException("SAX2 driver class " + className +
+                   " does not implement XMLReader", e4);
+    }
+    }
+}
diff --git a/xml/src/main/java/org/xml/sax/helpers/package.html b/xml/src/main/java/org/xml/sax/helpers/package.html
new file mode 100644
index 0000000..3a265fd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/package.html
@@ -0,0 +1,13 @@
+<HTML><HEAD>
+<!-- $Id: package.html,v 1.6 2002/01/30 20:52:39 dbrownell Exp $ -->
+</HEAD><BODY>
+
+<p>This package contains "helper" classes, including
+support for bootstrapping SAX-based applications.
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+@since Android 1.0
+
+</BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/package.html b/xml/src/main/java/org/xml/sax/package.html
new file mode 100644
index 0000000..fbe7108
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/package.html
@@ -0,0 +1,299 @@
+<html><head>
+<!-- $Id: package.html,v 1.18 2004/04/21 13:06:01 dmegginson Exp $ -->
+</head><body>
+
+<p> This package provides the core SAX APIs.
+Some SAX1 APIs are deprecated to encourage integration of
+namespace-awareness into designs of new applications
+and into maintenance of existing infrastructure. </p>
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+
+<h2> SAX2 Standard Feature Flags </h2>
+
+<p> One of the essential characteristics of SAX2 is that it added
+feature flags which can be used to examine and perhaps modify
+parser modes, in particular modes such as validation.
+Since features are identified by (absolute) URIs, anyone
+can define such features.   
+Currently defined standard feature URIs have the prefix
+<code>http://xml.org/sax/features/</code> before an identifier such as
+<code>validation</code>.  Turn features on or off using
+<em>setFeature</em>.  Those standard identifiers are: </p>
+
+
+<table border="1" cellpadding="3" cellspacing="0" width="100%">
+    <tr align="center" bgcolor="#ccccff">
+	<th>Feature ID</th>
+	<th>Access</th>
+	<th>Default</th>
+	<th>Description</th>
+	</tr>
+
+    <tr>
+	<td>external-general-entities</td>
+	<td><em>read/write</em></td>
+	<td><em>unspecified</em></td>
+	<td> Reports whether this parser processes external
+	    general entities; always true if validating.
+		</td>
+	</tr>
+
+    <tr>
+	<td>external-parameter-entities</td>
+	<td><em>read/write</em></td>
+	<td><em>unspecified</em></td>
+	<td> Reports whether this parser processes external
+	    parameter entities; always true if validating.
+		</td>
+	</tr>
+
+    <tr>
+	<td>is-standalone</td>
+	<td>(parsing) <em>read-only</em>, (not parsing) <em>none</em></td>
+	<td>not applicable</td>
+	<td> May be examined only during a parse, after the
+	    <em>startDocument()</em> callback has been completed; read-only.
+	    The value is true if the document specified standalone="yes" in 
+	    its XML declaration, and otherwise is false.
+		</td>
+	</tr>
+
+    <tr>
+	<td>lexical-handler/parameter-entities</td>
+	<td><em>read/write</em></td>
+	<td><em>unspecified</em></td>
+	<td> A value of "true" indicates that the LexicalHandler will report
+	    the beginning and end of parameter entities.
+		</td>
+	</tr>
+
+    <tr>
+	<td>namespaces</td>
+	<td><em>read/write</em></td>
+	<td>true</td>
+	<td> A value of "true" indicates namespace URIs and unprefixed local names
+	    for element and attribute names will be available.
+		</td>
+	</tr>
+
+    <tr>
+	<td>namespace-prefixes</td>
+	<td><em>read/write</em></td>
+	<td>false</td>
+	<td> A value of "true" indicates that XML qualified names (with prefixes) and
+	    attributes (including <em>xmlns*</em> attributes) will be available.
+		</td>
+	</tr>
+
+    <tr>
+	<td>resolve-dtd-uris</td>
+	<td><em>read/write</em></td>
+	<td><em>true</em></td>
+	<td> A value of "true" indicates that system IDs in declarations will
+	    be absolutized (relative to their base URIs) before reporting.
+	    (That is the default behavior for all SAX2 XML parsers.)
+	    A value of "false" indicates those IDs will not be absolutized;
+	    parsers will provide the base URI from
+	    <em>Locator.getSystemId()</em>.
+	    This applies to system IDs passed in <ul>
+		<li><em>DTDHandler.notationDecl()</em>,
+		<li><em>DTDHandler.unparsedEntityDecl()</em>, and
+		<li><em>DeclHandler.externalEntityDecl()</em>.
+	    </ul>
+	    It does not apply to <em>EntityResolver.resolveEntity()</em>,
+	    which is not used to report declarations, or to
+	    <em>LexicalHandler.startDTD()</em>, which already provides
+	    the non-absolutized URI.
+	    </td>
+	</tr>
+
+    <tr>
+	<td>string-interning</td>
+	<td><em>read/write</em></td>
+	<td><em>unspecified</em></td>
+	<td> Has a value of "true" if all XML names (for elements, prefixes,
+	    attributes, entities, notations, and local names),
+	    as well as Namespace URIs, will have been interned
+	    using <em>java.lang.String.intern</em>. This supports fast
+	    testing of equality/inequality against string constants,
+	    rather than forcing slower calls to <em>String.equals()</em>.
+	    </td>
+	</tr>
+
+    <tr>
+    <td>unicode-normalization-checking</td>
+    <td><em>read/write</em></td>
+    <td><em>false</em></td>
+    <td> Controls whether the parser reports Unicode normalization 
+        errors as described in section 2.13 and Appendix B of the 
+        XML 1.1 Recommendation. If true, Unicode normalization
+        errors are reported using the ErrorHandler.error() callback.
+        Such errors are not fatal in themselves (though, obviously,
+        other Unicode-related encoding errors may be).
+		</td>
+    </tr>
+    
+    <tr>
+	<td>use-attributes2</td>
+	<td><em>read-only</em></td>
+	<td>not applicable</td>
+	<td> Returns "true" if the <em>Attributes</em> objects passed by
+	    this parser in <em>ContentHandler.startElement()</em>
+	    implement the <a href="ext/Attributes2.html"
+	    ><em>org.xml.sax.ext.Attributes2</em></a> interface.
+	    That interface exposes additional DTD-related information,
+	    such as whether the attribute was specified in the
+	    source text rather than defaulted.
+		</td>
+	</tr>
+
+    <tr>
+	<td>use-locator2</td>
+	<td><em>read-only</em></td>
+	<td>not applicable</td>
+	<td> Returns "true" if the <em>Locator</em> objects passed by
+	    this parser in <em>ContentHandler.setDocumentLocator()</em>
+	    implement the <a href="ext/Locator2.html"
+	    ><em>org.xml.sax.ext.Locator2</em></a> interface.
+	    That interface exposes additional entity information,
+	    such as the character encoding and XML version used.
+		</td>
+	</tr>
+
+    <tr>
+	<td>use-entity-resolver2</td>
+	<td><em>read/write</em></td>
+	<td><em>true</em></td>
+	<td> Returns "true" if, when <em>setEntityResolver</em> is given
+	    an object implementing the <a href="ext/EntityResolver2.html"
+	    ><em>org.xml.sax.ext.EntityResolver2</em></a> interface,
+	    those new methods will be used.
+	    Returns "false" to indicate that those methods will not be used.
+		</td>
+	</tr>
+
+    <tr>
+	<td>validation</td>
+	<td><em>read/write</em></td>
+	<td><em>unspecified</em></td>
+	<td> Controls whether the parser is reporting all validity
+	    errors; if true, all external entities will be read.
+		</td>
+	</tr>
+
+    <tr>
+	<td>xmlns-uris</td>
+	<td><em>read/write</em></td>
+	<td><em>false</em></td>
+	<td> Controls whether, when the <em>namespace-prefixes</em> feature
+	    is set, the parser treats namespace declaration attributes as
+	    being in the <em>http://www.w3.org/2000/xmlns/</em> namespace.
+	    By default, SAX2 conforms to the original "Namespaces in XML"
+	    Recommendation, which explicitly states that such attributes are
+	    not in any namespace.
+	    Setting this optional flag to "true" makes the SAX2 events conform to
+	    a later backwards-incompatible revision of that recommendation,
+	    placing those attributes in a namespace.
+		</td>
+	</tr>
+
+    <tr>
+    <td>xml-1.1</td>
+    <td><em>read-only</em></td>
+    <td>not applicable</td>
+    <td> Returns "true" if the parser supports both XML 1.1 and XML 1.0.
+        Returns "false" if the parser supports only XML 1.0.
+		</td>
+    </tr>
+
+</table>
+
+<p> Support for the default values of the
+<em>namespaces</em> and <em>namespace-prefixes</em>
+properties is required.
+Support for any other feature flags is entirely optional.
+</p>
+
+<p> For default values not specified by SAX2,
+each XMLReader implementation specifies its default,
+or may choose not to expose the feature flag.
+Unless otherwise specified here,
+implementations may support changing current values
+of these standard feature flags, but not while parsing.
+</p>
+
+<h2> SAX2 Standard Handler and Property IDs </h2>
+
+<p> For parser interface characteristics that are described
+as objects, a separate namespace is defined.  The
+objects in this namespace are again identified by URI, and
+the standard property URIs have the prefix
+<code>http://xml.org/sax/properties/</code> before an identifier such as
+<code>lexical-handler</code> or
+<code>dom-node</code>.  Manage those properties using
+<em>setProperty()</em>.  Those identifiers are: </p>
+
+<table border="1" cellpadding="3" cellspacing="0" width="100%">
+    <tr align="center" bgcolor="#ccccff">
+	<th>Property ID</th>
+	<th>Description</th>
+	</tr>
+
+    <tr>
+	<td>declaration-handler</td>
+	<td> Used to see most DTD declarations except those treated
+	    as lexical ("document element name is ...") or which are
+	    mandatory for all SAX parsers (<em>DTDHandler</em>).
+	    The Object must implement <a href="ext/DeclHandler.html"
+	    ><em>org.xml.sax.ext.DeclHandler</em></a>.
+	    </td>
+	</tr>
+
+    <tr>
+        <td>document-xml-version</td>
+        <td> May be examined only during a parse, after the startDocument()
+            callback has been completed; read-only. This property is a 
+            literal string describing the actual XML version of the document, 
+            such as "1.0" or "1.1".
+            </td>
+        </tr>
+    
+    <tr>
+	<td>dom-node</td>
+	<td> For "DOM Walker" style parsers, which ignore their
+	    <em>parser.parse()</em> parameters, this is used to
+	    specify the DOM (sub)tree being walked by the parser.
+	    The Object must implement the
+	    <em>org.w3c.dom.Node</em> interface.
+	    </td>
+	</tr>
+
+    <tr>
+	<td>lexical-handler</td>
+	<td> Used to see some syntax events that are essential in some
+	    applications:  comments, CDATA delimiters, selected general
+	    entity inclusions, and the start and end of the DTD
+	    (and declaration of document element name).
+	    The Object must implement <a href="ext/LexicalHandler.html"
+	    ><em>org.xml.sax.ext.LexicalHandler</em></a>.
+	    </td>
+	</tr>
+
+    <tr>
+	<td>xml-string</td>
+	<td> Readable only during a parser callback, this exposes a <b>TBS</b>
+	    chunk of characters responsible for the current event. </td>
+	</tr>
+
+</table>
+
+<p> All of these standard properties are optional;
+XMLReader implementations need not support them.
+</p>
+
+@since Android 1.0
+
+</body></html>
\ No newline at end of file
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
new file mode 100644
index 0000000..2c2946f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
@@ -0,0 +1,1116 @@
+/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * XML Pull Parser is an interface that defines parsing functionlity provided
+ * in <a href="http://www.xmlpull.org/">XMLPULL V1 API</a> (visit this website to
+ * learn more about API and its implementations).
+ *
+ * <p>There are following different
+ * kinds of parser depending on which features are set:<ul>
+ * <li><b>non-validating</b> parser as defined in XML 1.0 spec when
+ *   FEATURE_PROCESS_DOCDECL is set to true
+ * <li><b>validating parser</b> as defined in XML 1.0 spec when
+ *   FEATURE_VALIDATION is true (and that implies that FEATURE_PROCESS_DOCDECL is true)
+ * <li>when FEATURE_PROCESS_DOCDECL is false (this is default and
+ *   if different value is required necessary must be changed before parsing is started)
+ *   then parser behaves like XML 1.0 compliant non-validating parser under condition that
+ *  <em>no DOCDECL is present</em> in XML documents
+ *   (internal entites can still be defined with defineEntityReplacementText()).
+ *   This mode of operation is intened <b>for operation in constrained environments</b> such as J2ME.
+ * </ul>
+ *
+ *
+ * <p>There are two key methods: next() and nextToken(). While next() provides
+ * access to high level parsing events, nextToken() allows access to lower
+ * level tokens.
+ *
+ * <p>The current event state of the parser
+ * can be determined by calling the
+ * <a href="#getEventType()">getEventType()</a> method.
+ * Initially, the parser is in the <a href="#START_DOCUMENT">START_DOCUMENT</a>
+ * state.
+ *
+ * <p>The method <a href="#next()">next()</a> advances the parser to the
+ * next event. The int value returned from next determines the current parser
+ * state and is identical to the value returned from following calls to
+ * getEventType ().
+ *
+ * <p>Th following event types are seen by next()<dl>
+ * <dt><a href="#START_TAG">START_TAG</a><dd> An XML start tag was read.
+ * <dt><a href="#TEXT">TEXT</a><dd> Text content was read;
+ * the text content can be retreived using the getText() method.
+ *  (when in validating mode next() will not report ignorable whitespaces, use nextToken() instead)
+ * <dt><a href="#END_TAG">END_TAG</a><dd> An end tag was read
+ * <dt><a href="#END_DOCUMENT">END_DOCUMENT</a><dd> No more events are available
+ * </dl>
+ *
+ * <p>after first next() or nextToken() (or any other next*() method)
+ * is called user application can obtain
+ * XML version, standalone and encoding from XML declaration
+ * in following ways:<ul>
+ * <li><b>version</b>:
+ *  getProperty(&quot;<a href="http://xmlpull.org/v1/doc/properties.html#xmldecl-version">http://xmlpull.org/v1/doc/properties.html#xmldecl-version</a>&quot;)
+ *       returns String ("1.0") or null if XMLDecl was not read or if property is not supported
+ * <li><b>standalone</b>:
+ *  getProperty(&quot;<a href="http://xmlpull.org/v1/doc/features.html#xmldecl-standalone">http://xmlpull.org/v1/doc/features.html#xmldecl-standalone</a>&quot;)
+ *       returns Boolean: null if there was no standalone declaration
+ *  or if property is not supported
+ *         otherwise returns Boolean(true) if standalon="yes" and Boolean(false) when standalone="no"
+ * <li><b>encoding</b>: obtained from getInputEncoding()
+ *       null if stream had unknown encoding (not set in setInputStream)
+ *           and it was not declared in XMLDecl
+ * </ul>
+ *
+ * A minimal example for using this API may look as follows:
+ * <pre>
+ * import java.io.IOException;
+ * import java.io.StringReader;
+ *
+ * import org.xmlpull.v1.XmlPullParser;
+ * import org.xmlpull.v1.<a href="XmlPullParserException.html">XmlPullParserException.html</a>;
+ * import org.xmlpull.v1.<a href="XmlPullParserFactory.html">XmlPullParserFactory</a>;
+ *
+ * public class SimpleXmlPullApp
+ * {
+ *
+ *     public static void main (String args[])
+ *         throws XmlPullParserException, IOException
+ *     {
+ *         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ *         factory.setNamespaceAware(true);
+ *         XmlPullParser xpp = factory.newPullParser();
+ *
+ *         xpp.<a href="#setInput">setInput</a>( new StringReader ( "&lt;foo>Hello World!&lt;/foo>" ) );
+ *         int eventType = xpp.getEventType();
+ *         while (eventType != XmlPullParser.END_DOCUMENT) {
+ *          if(eventType == XmlPullParser.START_DOCUMENT) {
+ *              System.out.println("Start document");
+ *          } else if(eventType == XmlPullParser.END_DOCUMENT) {
+ *              System.out.println("End document");
+ *          } else if(eventType == XmlPullParser.START_TAG) {
+ *              System.out.println("Start tag "+xpp.<a href="#getName()">getName()</a>);
+ *          } else if(eventType == XmlPullParser.END_TAG) {
+ *              System.out.println("End tag "+xpp.getName());
+ *          } else if(eventType == XmlPullParser.TEXT) {
+ *              System.out.println("Text "+xpp.<a href="#getText()">getText()</a>);
+ *          }
+ *          eventType = xpp.next();
+ *         }
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>The above example will generate the following output:
+ * <pre>
+ * Start document
+ * Start tag foo
+ * Text Hello World!
+ * End tag foo
+ * </pre>
+ *
+ * <p>For more details on API usage, please refer to the
+ * quick Introduction available at <a href="http://www.xmlpull.org">http://www.xmlpull.org</a>
+ *
+ * @see XmlPullParserFactory
+ * @see #defineEntityReplacementText
+ * @see #getName
+ * @see #getNamespace
+ * @see #getText
+ * @see #next
+ * @see #nextToken
+ * @see #setInput
+ * @see #FEATURE_PROCESS_DOCDECL
+ * @see #FEATURE_VALIDATION
+ * @see #START_DOCUMENT
+ * @see #START_TAG
+ * @see #TEXT
+ * @see #END_TAG
+ * @see #END_DOCUMENT
+ *
+ * @author <a href="http://www-ai.cs.uni-dortmund.de/PERSONAL/haustein.html">Stefan Haustein</a>
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+
+public interface XmlPullParser {
+
+    /** This constant represents the default namespace (empty string "") */
+    String NO_NAMESPACE = "";
+
+    // ----------------------------------------------------------------------------
+    // EVENT TYPES as reported by next()
+
+    /**
+     * Signalize that parser is at the very beginning of the document
+     * and nothing was read yet.
+     * This event type can only be observed by calling getEvent()
+     * before the first call to next(), nextToken, or nextTag()</a>).
+     *
+     * @see #next
+     * @see #nextToken
+     */
+    int START_DOCUMENT = 0;
+
+    /**
+     * Logical end of the xml document. Returned from getEventType, next()
+     * and nextToken()
+     * when the end of the input document has been reached.
+     * <p><strong>NOTE:</strong> calling again
+     * <a href="#next()">next()</a> or <a href="#nextToken()">nextToken()</a>
+     * will result in exception being thrown.
+     *
+     * @see #next
+     * @see #nextToken
+     */
+    int END_DOCUMENT = 1;
+
+    /**
+     * Returned from getEventType(),
+     * <a href="#next()">next()</a>, <a href="#nextToken()">nextToken()</a> when
+     * a start tag was read.
+     * The name of start tag is available from getName(), its namespace and prefix are
+     * available from getNamespace() and getPrefix()
+     * if <a href='#FEATURE_PROCESS_NAMESPACES'>namespaces are enabled</a>.
+     * See getAttribute* methods to retrieve element attributes.
+     * See getNamespace* methods to retrieve newly declared namespaces.
+     *
+     * @see #next
+     * @see #nextToken
+     * @see #getName
+     * @see #getPrefix
+     * @see #getNamespace
+     * @see #getAttributeCount
+     * @see #getDepth
+     * @see #getNamespaceCount
+     * @see #getNamespace
+     * @see #FEATURE_PROCESS_NAMESPACES
+     */
+    int START_TAG = 2;
+
+    /**
+     * Returned from getEventType(), <a href="#next()">next()</a>, or
+     * <a href="#nextToken()">nextToken()</a> when an end tag was read.
+     * The name of start tag is available from getName(), its
+     * namespace and prefix are
+     * available from getNamespace() and getPrefix().
+     *
+     * @see #next
+     * @see #nextToken
+     * @see #getName
+     * @see #getPrefix
+     * @see #getNamespace
+     * @see #FEATURE_PROCESS_NAMESPACES
+     */
+    int END_TAG = 3;
+
+
+    /**
+     * Character data was read and will is available by calling getText().
+     * <p><strong>Please note:</strong> <a href="#next()">next()</a> will
+     * accumulate multiple
+     * events into one TEXT event, skipping IGNORABLE_WHITESPACE,
+     * PROCESSING_INSTRUCTION and COMMENT events,
+     * In contrast, <a href="#nextToken()">nextToken()</a> will stop reading
+     * text when any other event is observed.
+     * Also, when the state was reached by calling next(), the text value will
+     * be normalized, whereas getText() will
+     * return unnormalized content in the case of nextToken(). This allows
+     * an exact roundtrip without chnanging line ends when examining low
+     * level events, whereas for high level applications the text is
+     * normalized apropriately.
+     *
+     * @see #next
+     * @see #nextToken
+     * @see #getText
+     */
+    int TEXT = 4;
+
+    // ----------------------------------------------------------------------------
+    // additional events exposed by lower level nextToken()
+
+    /**
+     * A CDATA sections was just read;
+     * this token is available only from calls to <a href="#nextToken()">nextToken()</a>.
+     * A call to next() will accumulate various text events into a single event
+     * of type TEXT. The text contained in the CDATA section is available
+     * by callling getText().
+     *
+     * @see #nextToken
+     * @see #getText
+     */
+    int CDSECT = 5;
+
+    /**
+     * An entity reference was just read;
+     * this token is available from <a href="#nextToken()">nextToken()</a>
+     * only. The entity name is available by calling getName(). If available,
+     * the replacement text can be obtained by calling getTextt(); otherwise,
+     * the user is responsibile for resolving the entity reference.
+     * This event type is never returned from next(); next() will
+     * accumulate the replacement text and other text
+     * events to a single TEXT event.
+     *
+     * @see #nextToken
+     * @see #getText
+     */
+    int ENTITY_REF = 6;
+
+    /**
+     * Ignorable whitespace was just read.
+     * This token is available only from <a href="#nextToken()">nextToken()</a>).
+     * For non-validating
+     * parsers, this event is only reported by nextToken() when outside
+     * the root element.
+     * Validating parsers may be able to detect ignorable whitespace at
+     * other locations.
+     * The ignorable whitespace string is available by calling getText()
+     *
+     * <p><strong>NOTE:</strong> this is different from calling the
+     *  isWhitespace() method, since text content
+     *  may be whitespace but not ignorable.
+     *
+     * Ignorable whitespace is skipped by next() automatically; this event
+     * type is never returned from next().
+     *
+     * @see #nextToken
+     * @see #getText
+     */
+    int IGNORABLE_WHITESPACE = 7;
+
+    /**
+     * An XML processing instruction declaration was just read. This
+     * event type is available only via <a href="#nextToken()">nextToken()</a>.
+     * getText() will return text that is inside the processing instruction.
+     * Calls to next() will skip processing instructions automatically.
+     * @see #nextToken
+     * @see #getText
+     */
+    int PROCESSING_INSTRUCTION = 8;
+
+    /**
+     * An XML comment was just read. This event type is this token is
+     * available via <a href="#nextToken()">nextToken()</a> only;
+     * calls to next() will skip comments automatically.
+     * The content of the comment can be accessed using the getText()
+     * method.
+     *
+     * @see #nextToken
+     * @see #getText
+     */
+    int COMMENT = 9;
+
+    /**
+     * An XML document type declaration was just read. This token is
+     * available from <a href="#nextToken()">nextToken()</a> only.
+     * The unparsed text inside the doctype is available via
+     * the getText() method.
+     *
+     * @see #nextToken
+     * @see #getText
+     */
+    int DOCDECL = 10;
+
+    /**
+     * This array can be used to convert the event type integer constants
+     * such as START_TAG or TEXT to
+     * to a string. For example, the value of TYPES[START_TAG] is
+     * the string "START_TAG".
+     *
+     * This array is intended for diagnostic output only. Relying
+     * on the contents of the array may be dangerous since malicous
+     * applications may alter the array, although it is final, due
+     * to limitations of the Java language.
+     */
+    String [] TYPES = {
+        "START_DOCUMENT",
+            "END_DOCUMENT",
+            "START_TAG",
+            "END_TAG",
+            "TEXT",
+            "CDSECT",
+            "ENTITY_REF",
+            "IGNORABLE_WHITESPACE",
+            "PROCESSING_INSTRUCTION",
+            "COMMENT",
+            "DOCDECL"
+    };
+
+
+    // ----------------------------------------------------------------------------
+    // namespace related features
+
+    /**
+     * This feature determines whether the parser processes
+     * namespaces. As for all features, the default value is false.
+     * <p><strong>NOTE:</strong> The value can not be changed during
+     * parsing an must be set before parsing.
+     *
+     * @see #getFeature
+     * @see #setFeature
+     */
+    String FEATURE_PROCESS_NAMESPACES =
+        "http://xmlpull.org/v1/doc/features.html#process-namespaces";
+
+    /**
+     * This feature determines whether namespace attributes are
+     * exposed via the attribute access methods. Like all features,
+     * the default value is false. This feature cannot be changed
+     * during parsing.
+     *
+     * @see #getFeature
+     * @see #setFeature
+     */
+    String FEATURE_REPORT_NAMESPACE_ATTRIBUTES =
+        "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes";
+
+    /**
+     * This feature determines whether the document declaration
+     * is processed. If set to false,
+     * the DOCDECL event type is reported by nextToken()
+     * and ignored by next().
+     *
+     * If this featue is activated, then the document declaration
+     * must be processed by the parser.
+     *
+     * <p><strong>Please note:</strong> If the document type declaration
+     * was ignored, entity references may cause exceptions
+     * later in the parsing process.
+     * The default value of this feature is false. It cannot be changed
+     * during parsing.
+     *
+     * @see #getFeature
+     * @see #setFeature
+     */
+    String FEATURE_PROCESS_DOCDECL =
+        "http://xmlpull.org/v1/doc/features.html#process-docdecl";
+
+    /**
+     * If this feature is activated, all validation errors as
+     * defined in the XML 1.0 sepcification are reported.
+     * This implies that FEATURE_PROCESS_DOCDECL is true and both, the
+     * internal and external document type declaration will be processed.
+     * <p><strong>Please Note:</strong> This feature can not be changed
+     * during parsing. The default value is false.
+     *
+     * @see #getFeature
+     * @see #setFeature
+     */
+    String FEATURE_VALIDATION =
+        "http://xmlpull.org/v1/doc/features.html#validation";
+
+    /**
+     * Use this call to change the general behaviour of the parser,
+     * such as namespace processing or doctype declaration handling.
+     * This method must be called before the first call to next or
+     * nextToken. Otherwise, an exception is thrown.
+     * <p>Example: call setFeature(FEATURE_PROCESS_NAMESPACES, true) in order
+     * to switch on namespace processing. The initial settings correspond
+     * to the properties requested from the XML Pull Parser factory.
+     * If none were requested, all feautures are deactivated by default.
+     *
+     * @exception XmlPullParserException If the feature is not supported or can not be set
+     * @exception IllegalArgumentException If string with the feature name is null
+     */
+    void setFeature(String name,
+                           boolean state) throws XmlPullParserException;
+
+    /**
+     * Returns the current value of the given feature.
+     * <p><strong>Please note:</strong> unknown features are
+     * <strong>always</strong> returned as false.
+     *
+     * @param name The name of feature to be retrieved.
+     * @return The value of the feature.
+     * @exception IllegalArgumentException if string the feature name is null
+     */
+
+    boolean getFeature(String name);
+
+    /**
+     * Set the value of a property.
+     *
+     * The property name is any fully-qualified URI.
+     *
+     * @exception XmlPullParserException If the property is not supported or can not be set
+     * @exception IllegalArgumentException If string with the property name is null
+     */
+    void setProperty(String name,
+                            Object value) throws XmlPullParserException;
+
+    /**
+     * Look up the value of a property.
+     *
+     * The property name is any fully-qualified URI.
+     * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong>
+     * returned as null.
+     *
+     * @param name The name of property to be retrieved.
+     * @return The value of named property.
+     */
+    Object getProperty(String name);
+
+
+    /**
+     * Set the input source for parser to the given reader and
+     * resets the parser. The event type is set to the initial value
+     * START_DOCUMENT.
+     * Setting the reader to null will just stop parsing and
+     * reset parser state,
+     * allowing the parser to free internal resources
+     * such as parsing buffers.
+     */
+    void setInput(Reader in) throws XmlPullParserException;
+
+
+    /**
+     * Sets the input stream the parser is going to process.
+     * This call resets the parser state and sets the event type
+     * to the initial value START_DOCUMENT.
+     *
+     * <p><strong>NOTE:</strong> If an input encoding string is passed,
+     *  it MUST be used. Otherwise,
+     *  if inputEncoding is null, the parser SHOULD try to determine
+     *  input encoding following XML 1.0 specification (see below).
+     *  If encoding detection is supported then following feature
+     *  <a href="http://xmlpull.org/v1/doc/features.html#detect-encoding">http://xmlpull.org/v1/doc/features.html#detect-encoding</a>
+     *  MUST be true amd otherwise it must be false
+     *
+     * @param inputStream contains a raw byte input stream of possibly
+     *     unknown encoding (when inputEncoding is null).
+     *
+     * @param inputEncoding if not null it MUST be used as encoding for inputStream
+     */
+    void setInput(InputStream inputStream, String inputEncoding)
+        throws XmlPullParserException;
+
+    /**
+     * Returns the input encoding if known, null otherwise.
+     * If setInput(InputStream, inputEncoding) was called with an inputEncoding
+     * value other than null, this value must be returned
+     * from this method. Otherwise, if inputEncoding is null and
+     * the parser suppports the encoding detection feature
+     * (http://xmlpull.org/v1/doc/features.html#detect-encoding),
+     * it must return the detected encoding.
+     * If setInput(Reader) was called, null is returned.
+     * After first call to next if XML declaration was present this method
+     * will return encoding declared.
+     */
+    String getInputEncoding();
+
+    /**
+     * Set new value for entity replacement text as defined in
+     * <a href="http://www.w3.org/TR/REC-xml#intern-replacement">XML 1.0 Section 4.5
+     * Construction of Internal Entity Replacement Text</a>.
+     * If FEATURE_PROCESS_DOCDECL or FEATURE_VALIDATION are set, calling this
+     * function will result in an exception -- when processing of DOCDECL is
+     * enabled, there is no need to the entity replacement text manually.
+     *
+     * <p>The motivation for this function is to allow very small
+     * implementations of XMLPULL that will work in J2ME environments.
+     * Though these implementations may not be able to process the document type
+     * declaration, they still can work with known DTDs by using this function.
+     *
+     * <p><b>Please notes:</b> The given value is used literally as replacement text
+     * and it corresponds to declaring entity in DTD that has all special characters
+     * escaped: left angle bracket is replaced with &amp;lt;, ampersnad with &amp;amp;
+     * and so on.
+     *
+     * <p><b>Note:</b> The given value is the literal replacement text and must not
+     * contain any other entity reference (if it contains any entity reference
+     * there will be no further replacement).
+     *
+     * <p><b>Note:</b> The list of pre-defined entity names will
+     * always contain standard XML entities such as
+     * amp (&amp;amp;), lt (&amp;lt;), gt (&amp;gt;), quot (&amp;quot;), and apos (&amp;apos;).
+     * Those cannot be redefined by this method!
+     *
+     * @see #setInput
+     * @see #FEATURE_PROCESS_DOCDECL
+     * @see #FEATURE_VALIDATION
+     */
+    void defineEntityReplacementText( String entityName,
+                                            String replacementText ) throws XmlPullParserException;
+
+    /**
+     * Returns the numbers of elements in the namespace stack for the given
+     * depth.
+     * If namespaces are not enabled, 0 is returned.
+     *
+     * <p><b>NOTE:</b> when parser is on END_TAG then it is allowed to call
+     *  this function with getDepth()+1 argument to retrieve position of namespace
+     *  prefixes and URIs that were declared on corresponding START_TAG.
+     * <p><b>NOTE:</b> to retrieve lsit of namespaces declared in current element:<pre>
+     *       XmlPullParser pp = ...
+     *       int nsStart = pp.getNamespaceCount(pp.getDepth()-1);
+     *       int nsEnd = pp.getNamespaceCount(pp.getDepth());
+     *       for (int i = nsStart; i < nsEnd; i++) {
+     *          String prefix = pp.getNamespacePrefix(i);
+     *          String ns = pp.getNamespaceUri(i);
+     *           // ...
+     *      }
+     * </pre>
+     *
+     * @see #getNamespacePrefix
+     * @see #getNamespaceUri
+     * @see #getNamespace()
+     * @see #getNamespace(String)
+     */
+    int getNamespaceCount(int depth) throws XmlPullParserException;
+
+    /**
+     * Returns the namespace prefixe for the given position
+     * in the namespace stack.
+     * Default namespace declaration (xmlns='...') will have null as prefix.
+     * If the given index is out of range, an exception is thrown.
+     * <p><b>Please note:</b> when the parser is on an END_TAG,
+     * namespace prefixes that were declared
+     * in the corresponding START_TAG are still accessible
+     * although they are no longer in scope.
+     */
+    String getNamespacePrefix(int pos) throws XmlPullParserException;
+
+    /**
+     * Returns the namespace URI for the given position in the
+     * namespace stack
+     * If the position is out of range, an exception is thrown.
+     * <p><b>NOTE:</b> when parser is on END_TAG then namespace prefixes that were declared
+     *  in corresponding START_TAG are still accessible even though they are not in scope
+     */
+    String getNamespaceUri(int pos) throws XmlPullParserException;
+
+    /**
+     * Returns the URI corresponding to the given prefix,
+     * depending on current state of the parser.
+     *
+     * <p>If the prefix was not declared in the current scope,
+     * null is returned. The default namespace is included
+     * in the namespace table and is available via
+     * getNamespace (null).
+     *
+     * <p>This method is a convenience method for
+     *
+     * <pre>
+     *  for (int i = getNamespaceCount(getDepth ())-1; i >= 0; i--) {
+     *   if (getNamespacePrefix(i).equals( prefix )) {
+     *     return getNamespaceUri(i);
+     *   }
+     *  }
+     *  return null;
+     * </pre>
+     *
+     * <p><strong>Please note:</strong> parser implementations
+     * may provide more efifcient lookup, e.g. using a Hashtable.
+     * The 'xml' prefix is bound to "http://www.w3.org/XML/1998/namespace", as
+     * defined in the
+     * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
+     * specification. Analogous, the 'xmlns' prefix is resolved to
+     * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
+     *
+     * @see #getNamespaceCount
+     * @see #getNamespacePrefix
+     * @see #getNamespaceUri
+     */
+    String getNamespace (String prefix);
+
+
+    // --------------------------------------------------------------------------
+    // miscellaneous reporting methods
+
+    /**
+     * Returns the current depth of the element.
+     * Outside the root element, the depth is 0. The
+     * depth is incremented by 1 when a start tag is reached.
+     * The depth is decremented AFTER the end tag
+     * event was observed.
+     *
+     * <pre>
+     * &lt;!-- outside --&gt;     0
+     * &lt;root>                  1
+     *   sometext                 1
+     *     &lt;foobar&gt;         2
+     *     &lt;/foobar&gt;        2
+     * &lt;/root&gt;              1
+     * &lt;!-- outside --&gt;     0
+     * </pre>
+     */
+    int getDepth();
+
+    /**
+     * Returns a short text describing the current parser state, including
+     * the position, a
+     * description of the current event and the data source if known.
+     * This method is especially useful to provide meaningful
+     * error messages and for debugging purposes.
+     */
+    String getPositionDescription ();
+
+
+    /**
+     * Returns the current line number, starting from 1.
+     * When the parser does not know the current line number
+     * or can not determine it,  -1 is returned (e.g. for WBXML).
+     *
+     * @return current line number or -1 if unknown.
+     */
+    int getLineNumber();
+
+    /**
+     * Returns the current column number, starting from 0.
+     * When the parser does not know the current column number
+     * or can not determine it,  -1 is returned (e.g. for WBXML).
+     *
+     * @return current column number or -1 if unknown.
+     */
+    int getColumnNumber();
+
+
+    // --------------------------------------------------------------------------
+    // TEXT related methods
+
+    /**
+     * Checks whether the current TEXT event contains only whitespace
+     * characters.
+     * For IGNORABLE_WHITESPACE, this is always true.
+     * For TEXT and CDSECT, false is returned when the current event text
+     * contains at least one non-white space character. For any other
+     * event type an exception is thrown.
+     *
+     * <p><b>Please note:</b> non-validating parsers are not
+     * able to distinguish whitespace and ignorable whitespace,
+     * except from whitespace outside the root element. Ignorable
+     * whitespace is reported as separate event, which is exposed
+     * via nextToken only.
+     *
+     */
+    boolean isWhitespace() throws XmlPullParserException;
+
+    /**
+     * Returns the text content of the current event as String.
+     * The value returned depends on current event type,
+     * for example for TEXT event it is element content
+     * (this is typical case when next() is used).
+     *
+     * See description of nextToken() for detailed description of
+     * possible returned values for different types of events.
+     *
+     * <p><strong>NOTE:</strong> in case of ENTITY_REF, this method returns
+     * the entity replacement text (or null if not available). This is
+     * the only case where
+     * getText() and getTextCharacters() return different values.
+     *
+     * @see #getEventType
+     * @see #next
+     * @see #nextToken
+     */
+    String getText ();
+
+
+    /**
+     * Returns the buffer that contains the text of the current event,
+     * as well as the start offset and length relevant for the current
+     * event. See getText(), next() and nextToken() for description of possible returned values.
+     *
+     * <p><strong>Please note:</strong> this buffer must not
+     * be modified and its content MAY change after a call to
+     * next() or nextToken(). This method will always return the
+     * same value as getText(), except for ENTITY_REF. In the case
+     * of ENTITY ref, getText() returns the replacement text and
+     * this method returns the actual input buffer containing the
+     * entity name.
+     * If getText() returns null, this method returns null as well and
+     * the values returned in the holder array MUST be -1 (both start
+     * and length).
+     *
+     * @see #getText
+     * @see #next
+     * @see #nextToken
+     *
+     * @param holderForStartAndLength Must hold an 2-element int array
+     * into which the start offset and length values will be written.
+     * @return char buffer that contains the text of the current event
+     *  (null if the current event has no text associated).
+     */
+    char[] getTextCharacters(int [] holderForStartAndLength);
+
+    // --------------------------------------------------------------------------
+    // START_TAG / END_TAG shared methods
+
+    /**
+     * Returns the namespace URI of the current element.
+     * The default namespace is represented
+     * as empty string.
+     * If namespaces are not enabled, an empty String ("") is always returned.
+     * The current event must be START_TAG or END_TAG; otherwise,
+     * null is returned.
+     */
+    String getNamespace ();
+
+    /**
+     * For START_TAG or END_TAG events, the (local) name of the current
+     * element is returned when namespaces are enabled. When namespace
+     * processing is disabled, the raw name is returned.
+     * For ENTITY_REF events, the entity name is returned.
+     * If the current event is not START_TAG, END_TAG, or ENTITY_REF,
+     * null is returned.
+     * <p><b>Please note:</b> To reconstruct the raw element name
+     *  when namespaces are enabled and the prefix is not null,
+     * you will need to  add the prefix and a colon to localName..
+     *
+     */
+    String getName();
+
+    /**
+     * Returns the prefix of the current element.
+     * If the element is in the default namespace (has no prefix),
+     * null is returned.
+     * If namespaces are not enabled, or the current event
+     * is not  START_TAG or END_TAG, null is returned.
+     */
+    String getPrefix();
+
+    /**
+     * Returns true if the current event is START_TAG and the tag
+     * is degenerated
+     * (e.g. &lt;foobar/&gt;).
+     * <p><b>NOTE:</b> if the parser is not on START_TAG, an exception
+     * will be thrown.
+     */
+    boolean isEmptyElementTag() throws XmlPullParserException;
+
+    // --------------------------------------------------------------------------
+    // START_TAG Attributes retrieval methods
+
+    /**
+     * Returns the number of attributes of the current start tag, or
+     * -1 if the current event type is not START_TAG
+     *
+     * @see #getAttributeNamespace
+     * @see #getAttributeName
+     * @see #getAttributePrefix
+     * @see #getAttributeValue
+     */
+    int getAttributeCount();
+
+    /**
+     * Returns the namespace URI of the attribute
+     * with the given index (starts from 0).
+     * Returns an empty string ("") if namespaces are not enabled
+     * or the attribute has no namespace.
+     * Throws an IndexOutOfBoundsException if the index is out of range
+     * or the current event type is not START_TAG.
+     *
+     * <p><strong>NOTE:</strong> if FEATURE_REPORT_NAMESPACE_ATTRIBUTES is set
+     * then namespace attributes (xmlns:ns='...') must be reported
+     * with namespace
+     * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
+     * (visit this URL for description!).
+     * The default namespace attribute (xmlns="...") will be reported with empty namespace.
+     * <p><strong>NOTE:</strong>The xml prefix is bound as defined in
+     * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
+     * specification to "http://www.w3.org/XML/1998/namespace".
+     *
+     * @param index zero-based index of attribute
+     * @return attribute namespace,
+     *   empty string ("") is returned  if namesapces processing is not enabled or
+     *   namespaces processing is enabled but attribute has no namespace (it has no prefix).
+     */
+    String getAttributeNamespace (int index);
+
+    /**
+     * Returns the local name of the specified attribute
+     * if namespaces are enabled or just attribute name if namespaces are disabled.
+     * Throws an IndexOutOfBoundsException if the index is out of range
+     * or current event type is not START_TAG.
+     *
+     * @param index zero-based index of attribute
+     * @return attribute name (null is never returned)
+     */
+    String getAttributeName (int index);
+
+    /**
+     * Returns the prefix of the specified attribute
+     * Returns null if the element has no prefix.
+     * If namespaces are disabled it will always return null.
+     * Throws an IndexOutOfBoundsException if the index is out of range
+     * or current event type is not START_TAG.
+     *
+     * @param index zero-based index of attribute
+     * @return attribute prefix or null if namespaces processing is not enabled.
+     */
+    String getAttributePrefix(int index);
+
+    /**
+     * Returns the type of the specified attribute
+     * If parser is non-validating it MUST return CDATA.
+     *
+     * @param index zero-based index of attribute
+     * @return attribute type (null is never returned)
+     */
+    String getAttributeType(int index);
+
+    /**
+     * Returns if the specified attribute was not in input was declared in XML.
+     * If parser is non-validating it MUST always return false.
+     * This information is part of XML infoset:
+     *
+     * @param index zero-based index of attribute
+     * @return false if attribute was in input
+     */
+    boolean isAttributeDefault(int index);
+
+    /**
+     * Returns the given attributes value.
+     * Throws an IndexOutOfBoundsException if the index is out of range
+     * or current event type is not START_TAG.
+     *
+     * <p><strong>NOTE:</strong> attribute value must be normalized
+     * (including entity replacement text if PROCESS_DOCDECL is false) as described in
+     * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
+     * 3.3.3 Attribute-Value Normalization</a>
+     *
+     * @see #defineEntityReplacementText
+     *
+     * @param index zero-based index of attribute
+     * @return value of attribute (null is never returned)
+     */
+    String getAttributeValue(int index);
+
+    /**
+     * Returns the attributes value identified by namespace URI and namespace localName.
+     * If namespaces are disabled namespace must be null.
+     * If current event type is not START_TAG then IndexOutOfBoundsException will be thrown.
+     *
+     * <p><strong>NOTE:</strong> attribute value must be normalized
+     * (including entity replacement text if PROCESS_DOCDECL is false) as described in
+     * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
+     * 3.3.3 Attribute-Value Normalization</a>
+     *
+     * @see #defineEntityReplacementText
+     *
+     * @param namespace Namespace of the attribute if namespaces are enabled otherwise must be null
+     * @param name If namespaces enabled local name of attribute otherwise just attribute name
+     * @return value of attribute or null if attribute with given name does not exist
+     */
+    String getAttributeValue(String namespace,
+                                    String name);
+
+    // --------------------------------------------------------------------------
+    // actual parsing methods
+
+    /**
+     * Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.)
+     *
+     * @see #next()
+     * @see #nextToken()
+     */
+    int getEventType()
+        throws XmlPullParserException;
+
+    /**
+     * Get next parsing event - element content wil be coalesced and only one
+     * TEXT event must be returned for whole element content
+     * (comments and processing instructions will be ignored and emtity references
+     * must be expanded or exception mus be thrown if entity reerence can not be exapnded).
+     * If element content is empty (content is "") then no TEXT event will be reported.
+     *
+     * <p><b>NOTE:</b> empty element (such as &lt;tag/>) will be reported
+     *  with  two separate events: START_TAG, END_TAG - it must be so to preserve
+     *   parsing equivalency of empty element to &lt;tag>&lt;/tag>.
+     *  (see isEmptyElementTag ())
+     *
+     * @see #isEmptyElementTag
+     * @see #START_TAG
+     * @see #TEXT
+     * @see #END_TAG
+     * @see #END_DOCUMENT
+     */
+
+    int next()
+        throws XmlPullParserException, IOException;
+
+
+    /**
+     * This method works similarly to next() but will expose
+     * additional event types (COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or
+     * IGNORABLE_WHITESPACE) if they are available in input.
+     *
+     * <p>If special feature
+     * <a href="http://xmlpull.org/v1/doc/features.html#xml-roundtrip">FEATURE_XML_ROUNDTRIP</a>
+     * (identified by URI: http://xmlpull.org/v1/doc/features.html#xml-roundtrip)
+     * is enabled it is possible to do XML document round trip ie. reproduce
+     * exectly on output the XML input using getText():
+     * returned content is always unnormalized (exactly as in input).
+     * Otherwise returned content is end-of-line normalized as described
+     * <a href="http://www.w3.org/TR/REC-xml#sec-line-ends">XML 1.0 End-of-Line Handling</a>
+     * and. Also when this feature is enabled exact content of START_TAG, END_TAG,
+     * DOCDECL and PROCESSING_INSTRUCTION is available.
+     *
+     * <p>Here is the list of tokens that can be  returned from nextToken()
+     * and what getText() and getTextCharacters() returns:<dl>
+     * <dt>START_DOCUMENT<dd>null
+     * <dt>END_DOCUMENT<dd>null
+     * <dt>START_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
+     *   enabled and then returns XML tag, ex: &lt;tag attr='val'>
+     * <dt>END_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
+     *  id enabled and then returns XML tag, ex: &lt;/tag>
+     * <dt>TEXT<dd>return element content.
+     *  <br>Note: that element content may be delivered in multiple consecutive TEXT events.
+     * <dt>IGNORABLE_WHITESPACE<dd>return characters that are determined to be ignorable white
+     * space. If the FEATURE_XML_ROUNDTRIP is enabled all whitespace content outside root
+     * element will always reported as IGNORABLE_WHITESPACE otherise rteporting is optional.
+     *  <br>Note: that element content may be delevered in multiple consecutive IGNORABLE_WHITESPACE events.
+     * <dt>CDSECT<dd>
+     * return text <em>inside</em> CDATA
+     *  (ex. 'fo&lt;o' from &lt;!CDATA[fo&lt;o]]>)
+     * <dt>PROCESSING_INSTRUCTION<dd>
+     *  if FEATURE_XML_ROUNDTRIP is true
+     *  return exact PI content ex: 'pi foo' from &lt;?pi foo?>
+     *  otherwise it may be exact PI content or concatenation of PI target,
+     * space and data so for example for
+     *   &lt;?target    data?> string &quot;target data&quot; may
+     *       be returned if FEATURE_XML_ROUNDTRIP is false.
+     * <dt>COMMENT<dd>return comment content ex. 'foo bar' from &lt;!--foo bar-->
+     * <dt>ENTITY_REF<dd>getText() MUST return entity replacement text if PROCESS_DOCDECL is false
+     * otherwise getText() MAY return null,
+     * additionally getTextCharacters() MUST return entity name
+     * (for example 'entity_name' for &amp;entity_name;).
+     * <br><b>NOTE:</b> this is the only place where value returned from getText() and
+     *   getTextCharacters() <b>are different</b>
+     * <br><b>NOTE:</b> it is user responsibility to resolve entity reference
+     *    if PROCESS_DOCDECL is false and there is no entity replacement text set in
+     *    defineEntityReplacementText() method (getText() will be null)
+     * <br><b>NOTE:</b> character entities (ex. &amp;#32;) and standard entities such as
+     *  &amp;amp; &amp;lt; &amp;gt; &amp;quot; &amp;apos; are reported as well
+     *  and are <b>not</b> reported as TEXT tokens but as ENTITY_REF tokens!
+     *  This requirement is added to allow to do roundtrip of XML documents!
+     * <dt>DOCDECL<dd>
+     * if FEATURE_XML_ROUNDTRIP is true or PROCESS_DOCDECL is false
+     * then return what is inside of DOCDECL for example it returns:<pre>
+     * &quot; titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
+     * [&lt;!ENTITY % active.links "INCLUDE">]&quot;</pre>
+     * <p>for input document that contained:<pre>
+     * &lt;!DOCTYPE titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
+     * [&lt;!ENTITY % active.links "INCLUDE">]></pre>
+     * otherwise if FEATURE_XML_ROUNDTRIP is false and PROCESS_DOCDECL is true
+     *    then what is returned is undefined (it may be even null)
+     * </dd>
+     * </dl>
+     *
+     * <p><strong>NOTE:</strong> there is no gurantee that there will only one TEXT or
+     * IGNORABLE_WHITESPACE event from nextToken() as parser may chose to deliver element content in
+     * multiple tokens (dividing element content into chunks)
+     *
+     * <p><strong>NOTE:</strong> whether returned text of token is end-of-line normalized
+     *  is depending on FEATURE_XML_ROUNDTRIP.
+     *
+     * <p><strong>NOTE:</strong> XMLDecl (&lt;?xml ...?&gt;) is not reported but its content
+     * is available through optional properties (see class description above).
+     *
+     * @see #next
+     * @see #START_TAG
+     * @see #TEXT
+     * @see #END_TAG
+     * @see #END_DOCUMENT
+     * @see #COMMENT
+     * @see #DOCDECL
+     * @see #PROCESSING_INSTRUCTION
+     * @see #ENTITY_REF
+     * @see #IGNORABLE_WHITESPACE
+     */
+    int nextToken()
+        throws XmlPullParserException, IOException;
+
+    //-----------------------------------------------------------------------------
+    // utility methods to mak XML parsing easier ...
+
+    /**
+     * Test if the current event is of the given type and if the
+     * namespace and name do match. null will match any namespace
+     * and any name. If the test is not passed, an exception is
+     * thrown. The exception text indicates the parser position,
+     * the expected event and the current event that is not meeting the
+     * requirement.
+     *
+     * <p>Essentially it does this
+     * <pre>
+     *  if (type != getEventType()
+     *  || (namespace != null &amp;&amp;  !namespace.equals( getNamespace () ) )
+     *  || (name != null &amp;&amp;  !name.equals( getName() ) ) )
+     *     throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
+     * </pre>
+     */
+    void require(int type, String namespace, String name)
+        throws XmlPullParserException, IOException;
+
+    /**
+     * If current event is START_TAG then if next element is TEXT then element content is returned
+     * or if next event is END_TAG then empty string is returned, otherwise exception is thrown.
+     * After calling this function successfully parser will be positioned on END_TAG.
+     *
+     * <p>The motivation for this function is to allow to parse consistently both
+     * empty elements and elements that has non empty content, for example for input: <ol>
+     * <li>&lt;tag&gt;foo&lt;/tag&gt;
+     * <li>&lt;tag&gt;&lt;/tag&gt; (which is equivalent to &lt;tag/&gt;
+     * both input can be parsed with the same code:
+     * <pre>
+     *   p.nextTag()
+     *   p.requireEvent(p.START_TAG, "", "tag");
+     *   String content = p.nextText();
+     *   p.requireEvent(p.END_TAG, "", "tag");
+     * </pre>
+     * This function together with nextTag make it very easy to parse XML that has
+     * no mixed content.
+     *
+     *
+     * <p>Essentially it does this
+     * <pre>
+     *  if(getEventType() != START_TAG) {
+     *     throw new XmlPullParserException(
+     *       "parser must be on START_TAG to read next text", this, null);
+     *  }
+     *  int eventType = next();
+     *  if(eventType == TEXT) {
+     *     String result = getText();
+     *     eventType = next();
+     *     if(eventType != END_TAG) {
+     *       throw new XmlPullParserException(
+     *          "event TEXT it must be immediately followed by END_TAG", this, null);
+     *      }
+     *      return result;
+     *  } else if(eventType == END_TAG) {
+     *     return "";
+     *  } else {
+     *     throw new XmlPullParserException(
+     *       "parser must be on START_TAG or TEXT to read text", this, null);
+     *  }
+     * </pre>
+     */
+    String nextText() throws XmlPullParserException, IOException;
+
+    /**
+     * Call next() and return event if it is START_TAG or END_TAG
+     * otherwise throw an exception.
+     * It will skip whitespace TEXT before actual tag if any.
+     *
+     * <p>essentially it does this
+     * <pre>
+     *   int eventType = next();
+     *   if(eventType == TEXT &amp;&amp;  isWhitespace()) {   // skip whitespace
+     *      eventType = next();
+     *   }
+     *   if (eventType != START_TAG &amp;&amp;  eventType != END_TAG) {
+     *      throw new XmlPullParserException("expected start or end tag", this, null);
+     *   }
+     *   return eventType;
+     * </pre>
+     */
+    int nextTag() throws XmlPullParserException, IOException;
+
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java
new file mode 100644
index 0000000..b4b4b71
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java
@@ -0,0 +1,76 @@
+/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+/**
+ * This exception is thrown to signal XML Pull Parser related faults.
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+public class XmlPullParserException extends Exception {
+    protected Throwable detail;
+    protected int row = -1;
+    protected int column = -1;
+
+    /*    public XmlPullParserException() {
+          }*/
+
+    public XmlPullParserException(String s) {
+        super(s);
+    }
+
+    /*
+    public XmlPullParserException(String s, Throwable thrwble) {
+        super(s);
+        this.detail = thrwble;
+        }
+
+    public XmlPullParserException(String s, int row, int column) {
+        super(s);
+        this.row = row;
+        this.column = column;
+    }
+    */
+
+    public XmlPullParserException(String msg, XmlPullParser parser, Throwable chain) {
+        super ((msg == null ? "" : msg+" ")
+               + (parser == null ? "" : "(position:"+parser.getPositionDescription()+") ")
+               + (chain == null ? "" : "caused by: "+chain));
+
+        if (parser != null) {
+            this.row = parser.getLineNumber();
+            this.column = parser.getColumnNumber();
+        }
+        this.detail = chain;
+    }
+
+    public Throwable getDetail() { return detail; }
+    //    public void setDetail(Throwable cause) { this.detail = cause; }
+    public int getLineNumber() { return row; }
+    public int getColumnNumber() { return column; }
+
+    /*
+    public String getMessage() {
+        if(detail == null)
+            return super.getMessage();
+        else
+            return super.getMessage() + "; nested exception is: \n\t"
+                + detail.getMessage();
+    }
+    */
+
+    //NOTE: code that prints this and detail is difficult in J2ME
+    public void printStackTrace() {
+        if (detail == null) {
+            super.printStackTrace();
+        } else {
+            synchronized(System.err) {
+                System.err.println(super.getMessage() + "; nested exception is:");
+                detail.printStackTrace();
+            }
+        }
+    }
+
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
new file mode 100644
index 0000000..7b786f6
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -0,0 +1,349 @@
+/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
+ * The name of actual factory class will be determined based on several parameters.
+ * It works similar to JAXP but tailored to work in J2ME environments
+ * (no access to system properties or file system) so name of parser class factory to use
+ * and its class used for loading (no class loader - on J2ME no access to context class loaders)
+ * must be passed explicitly. If no name of parser factory was passed (or is null)
+ * it will try to find name by searching in CLASSPATH for
+ * META-INF/services/org.xmlpull.v1.XmlPullParserFactory resource that should contain
+ * a comma separated list of class names of factories or parsers to try (in order from
+ * left to the right). If none found, it will throw an exception.
+ *
+ * <br /><strong>NOTE:</strong>In J2SE or J2EE environments, you may want to use
+ * <code>newInstance(property, classLoaderCtx)</code>
+ * where first argument is
+ * <code>System.getProperty(XmlPullParserFactory.PROPERTY_NAME)</code>
+ * and second is <code>Thread.getContextClassLoader().getClass()</code> .
+ *
+ * @see XmlPullParser
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ * @author Stefan Haustein
+ */
+
+public class XmlPullParserFactory {
+    /** used as default class to server as context class in newInstance() */
+    final static Class referenceContextClass;
+
+    static {
+        XmlPullParserFactory f = new XmlPullParserFactory();
+        referenceContextClass = f.getClass();
+    }
+
+    /** Name of the system or midlet property that should be used for
+     a system property containing a comma separated list of factory
+     or parser class names (value:
+     org.xmlpull.v1.XmlPullParserFactory). */
+
+
+    public static final String PROPERTY_NAME =
+        "org.xmlpull.v1.XmlPullParserFactory";
+
+    private static final String RESOURCE_NAME =
+        "/META-INF/services/" + PROPERTY_NAME;
+
+
+    // public static final String DEFAULT_PROPERTY =
+    //    "org.xmlpull.xpp3.XmlPullParser,org.kxml2.io.KXmlParser";
+
+
+    protected ArrayList parserClasses;
+    protected String classNamesLocation;
+
+    protected ArrayList serializerClasses;
+
+
+    // features are kept there
+    protected HashMap features = new HashMap();
+
+
+    /**
+     * Protected constructor to be called by factory implementations.
+     */
+
+    protected XmlPullParserFactory() {
+    }
+
+
+
+    /**
+     * Set the features to be set when XML Pull Parser is created by this factory.
+     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+     *
+     * @param name string with URI identifying feature
+     * @param state if true feature will be set; if false will be ignored
+     */
+
+    public void setFeature(String name,
+                           boolean state) throws XmlPullParserException {
+
+        features.put(name, new Boolean(state));
+    }
+
+
+    /**
+     * Return the current value of the feature with given name.
+     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+     *
+     * @param name The name of feature to be retrieved.
+     * @return The value of named feature.
+     *     Unknown features are <string>always</strong> returned as false
+     */
+
+    public boolean getFeature (String name) {
+        Boolean value = (Boolean) features.get(name);
+        return value != null ? value.booleanValue() : false;
+    }
+
+    /**
+     * Specifies that the parser produced by this factory will provide
+     * support for XML namespaces.
+     * By default the value of this is set to false.
+     *
+     * @param awareness true if the parser produced by this code
+     *    will provide support for XML namespaces;  false otherwise.
+     */
+
+    public void setNamespaceAware(boolean awareness) {
+        features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, new Boolean (awareness));
+    }
+
+    /**
+     * Indicates whether or not the factory is configured to produce
+     * parsers which are namespace aware
+     * (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
+     *
+     * @return  true if the factory is configured to produce parsers
+     *    which are namespace aware; false otherwise.
+     */
+
+    public boolean isNamespaceAware() {
+        return getFeature (XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+    }
+
+
+    /**
+     * Specifies that the parser produced by this factory will be validating
+     * (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
+     *
+     * By default the value of this is set to false.
+     *
+     * @param validating - if true the parsers created by this factory  must be validating.
+     */
+
+    public void setValidating(boolean validating) {
+        features.put (XmlPullParser.FEATURE_VALIDATION, new Boolean (validating));
+    }
+
+    /**
+     * Indicates whether or not the factory is configured to produce parsers
+     * which validate the XML content during parse.
+     *
+     * @return   true if the factory is configured to produce parsers
+     * which validate the XML content during parse; false otherwise.
+     */
+
+    public boolean isValidating() {
+        return getFeature (XmlPullParser.FEATURE_VALIDATION);
+    }
+
+    /**
+     * Creates a new instance of a XML Pull Parser
+     * using the currently configured factory features.
+     *
+     * @return A new instance of a XML Pull Parser.
+     * @throws XmlPullParserException if a parser cannot be created which satisfies the
+     * requested configuration.
+     */
+
+    public XmlPullParser newPullParser() throws XmlPullParserException {
+
+        if (parserClasses == null) throw new XmlPullParserException
+                ("Factory initialization was incomplete - has not tried "+classNamesLocation);
+
+        if (parserClasses.size() == 0) throw new XmlPullParserException
+                ("No valid parser classes found in "+classNamesLocation);
+
+        final StringBuffer issues = new StringBuffer ();
+
+        for (int i = 0; i < parserClasses.size(); i++) {
+            final Class ppClass = (Class) parserClasses.get(i);
+            try {
+                final XmlPullParser pp = (XmlPullParser) ppClass.newInstance();
+
+                for (Iterator iter = features.keySet().iterator(); iter.hasNext(); ) {
+                    final String key = (String) iter.next();
+                    final Boolean value = (Boolean) features.get(key);
+                    if(value != null && value.booleanValue()) {
+                        pp.setFeature(key, true);
+                    }
+                }
+                return pp;
+
+            } catch(Exception ex) {
+                issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
+            }
+        }
+
+        throw new XmlPullParserException ("could not create parser: "+issues);
+    }
+
+
+    /**
+     * Creates a new instance of a XML Serializer.
+     *
+     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+     *
+     * @return A new instance of a XML Serializer.
+     * @throws XmlPullParserException if a parser cannot be created which satisfies the
+     * requested configuration.
+     */
+
+    public XmlSerializer newSerializer() throws XmlPullParserException {
+
+        if (serializerClasses == null) {
+            throw new XmlPullParserException
+                ("Factory initialization incomplete - has not tried "+classNamesLocation);
+        }
+        if(serializerClasses.size() == 0) {
+            throw new XmlPullParserException
+                ("No valid serializer classes found in "+classNamesLocation);
+        }
+
+        final StringBuffer issues = new StringBuffer ();
+
+        for (int i = 0; i < serializerClasses.size (); i++) {
+            final Class ppClass = (Class) serializerClasses.get(i);
+            try {
+                final XmlSerializer ser = (XmlSerializer) ppClass.newInstance();
+
+                return ser;
+
+            } catch(Exception ex) {
+                issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
+            }
+        }
+
+        throw new XmlPullParserException ("could not create serializer: "+issues);
+    }
+
+    /**
+     * Create a new instance of a PullParserFactory that can be used
+     * to create XML pull parsers (see class description for more
+     * details).
+     *
+     * @return a new instance of a PullParserFactory, as returned by newInstance (null, null); 
+     */
+    public static XmlPullParserFactory newInstance () throws XmlPullParserException {
+        return newInstance(null, null);
+    }
+
+    public static XmlPullParserFactory newInstance (String classNames, Class context)
+        throws XmlPullParserException {
+
+        if (context == null) {
+            //NOTE: make sure context uses the same class loader as API classes
+            //      this is the best we can do without having access to context classloader in J2ME
+            //      if API is in the same classloader as implementation then this will work
+            context = referenceContextClass;
+        }
+
+        /*
+        String  classNamesLocation = null;
+
+        if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) {
+            try {
+                InputStream is = context.getResourceAsStream (RESOURCE_NAME);
+
+                if (is == null) throw new XmlPullParserException
+                        ("resource not found: "+RESOURCE_NAME
+                             +" make sure that parser implementing XmlPull API is available");
+                final StringBuffer sb = new StringBuffer();
+
+                while (true) {
+                    final int ch = is.read();
+                    if (ch < 0) break;
+                    else if (ch > ' ')
+                        sb.append((char) ch);
+                }
+                is.close ();
+
+                classNames = sb.toString ();
+            }
+            catch (Exception e) {
+                throw new XmlPullParserException (null, null, e);
+            }
+            classNamesLocation = "resource "+RESOURCE_NAME+" that contained '"+classNames+"'";
+        } else {
+            classNamesLocation =
+                "parameter classNames to newInstance() that contained '"+classNames+"'";
+        }
+        */
+        classNames = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
+
+        XmlPullParserFactory factory = null;
+        final ArrayList parserClasses = new ArrayList();
+        final ArrayList serializerClasses = new ArrayList();
+        int pos = 0;
+
+        while (pos < classNames.length ()) {
+            int cut = classNames.indexOf (',', pos);
+
+            if (cut == -1) cut = classNames.length ();
+            final String name = classNames.substring (pos, cut);
+
+            Class candidate = null;
+            Object instance = null;
+
+            try {
+                candidate = Class.forName (name);
+                // necessary because of J2ME .class issue
+                instance = candidate.newInstance ();
+            }
+            catch (Exception e) {}
+
+            if (candidate != null) {
+                boolean recognized = false;
+                if (instance instanceof XmlPullParser) {
+                    parserClasses.add(candidate);
+                    recognized = true;
+                }
+                if (instance instanceof XmlSerializer) {
+                    serializerClasses.add(candidate);
+                    recognized = true;
+                }
+                if (instance instanceof XmlPullParserFactory) {
+                    if (factory == null) {
+                        factory = (XmlPullParserFactory) instance;
+                    }
+                    recognized = true;
+                }
+                if (!recognized) {
+                    throw new XmlPullParserException ("incompatible class: "+name);
+                }
+            }
+            pos = cut + 1;
+        }
+
+        if (factory == null) {
+            factory = new XmlPullParserFactory ();
+        }
+        factory.parserClasses = parserClasses;
+        factory.serializerClasses = serializerClasses;
+        factory.classNamesLocation = "org.kxml2.io.kXmlParser,org.kxml2.io.KXmlSerializer";
+        return factory;
+    }
+}
+
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java b/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java
new file mode 100644
index 0000000..8e85e2f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java
@@ -0,0 +1,326 @@
+package org.xmlpull.v1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * Define an interface to serialziation of XML Infoset.
+ * This interface abstracts away if serialized XML is XML 1.0 comaptible text or
+ * other formats of XML 1.0 serializations (such as binary XML for example with WBXML).
+ *
+ * <p><b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API.
+ * It is included as basis for discussion. It may change in any way.
+ *
+ * <p>Exceptions that may be thrown are: IOException or runtime exception
+ * (more runtime exceptions can be thrown but are not declared and as such
+ * have no semantics defined for this interface):
+ * <ul>
+ * <li><em>IllegalArgumentException</em> - for almost all methods to signal that
+ *     argument is illegal
+ * <li><em>IllegalStateException</em> - to signal that call has good arguments but
+ *     is not expected here (violation of contract) and for features/properties
+ *    when requesting setting unimplemented feature/property
+ *    (UnsupportedOperationException would be better but it is not in MIDP)
+ *  </ul>
+ *
+ * <p><b>NOTE:</b> writing  CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE,
+ *  PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some implementations
+ * may not be supported (for example when serializing to WBXML).
+ * In such case IllegalStateException will be thrown and it is recommened
+ * to use an optional feature to signal that implementation is not
+ * supporting this kind of output.
+ */
+
+public interface XmlSerializer {
+    
+    /**
+     * Set feature identified by name (recommended to be URI for uniqueness).
+     * Some well known optional features are defined in
+     * <a href="http://www.xmlpull.org/v1/doc/features.html">
+     * http://www.xmlpull.org/v1/doc/features.html</a>.
+     *
+     * If feature is not recocgnized or can not be set
+     * then IllegalStateException MUST be thrown.
+     *
+     * @exception IllegalStateException If the feature is not supported or can not be set
+     */
+    void setFeature(String name,
+                           boolean state)
+        throws IllegalArgumentException, IllegalStateException;
+    
+    
+    /**
+     * Return the current value of the feature with given name.
+     * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null
+     *
+     * @param name The name of feature to be retrieved.
+     * @return The value of named feature.
+     * @exception IllegalArgumentException if feature string is null
+     */
+    boolean getFeature(String name);
+    
+    
+    /**
+     * Set the value of a property.
+     * (the property name is recommened to be URI for uniqueness).
+     * Some well known optional properties are defined in
+     * <a href="http://www.xmlpull.org/v1/doc/properties.html">
+     * http://www.xmlpull.org/v1/doc/properties.html</a>.
+     *
+     * If property is not recocgnized or can not be set
+     * then IllegalStateException MUST be thrown.
+     *
+     * @exception IllegalStateException if the property is not supported or can not be set
+     */
+    void setProperty(String name,
+                            Object value)
+        throws IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Look up the value of a property.
+     *
+     * The property name is any fully-qualified URI. I
+     * <p><strong>NOTE:</strong> unknown properties are <string>always</strong> returned as null
+     *
+     * @param name The name of property to be retrieved.
+     * @return The value of named property.
+     */
+    Object getProperty(String name);
+    
+    /**
+     * Set to use binary output stream with given encoding.
+     */
+    void setOutput (OutputStream os, String encoding)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Set the output to the given writer.
+     * <p><b>WARNING</b> no information about encoding is available!
+     */
+    void setOutput (Writer writer)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Write &lt;&#63;xml declaration with encoding (if encoding not null)
+     * and standalone flag (if standalone not null)
+     * This method can only be called just after setOutput.
+     */
+    void startDocument (String encoding, Boolean standalone)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Finish writing. All unclosed start tags will be closed and output
+     * will be flushed. After calling this method no more output can be
+     * serialized until next call to setOutput()
+     */
+    void endDocument ()
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Binds the given prefix to the given namespace.
+     * This call is valid for the next element including child elements.
+     * The prefix and namespace MUST be always declared even if prefix
+     * is not used in element (startTag() or attribute()) - for XML 1.0
+     * it must result in declaring <code>xmlns:prefix='namespace'</code>
+     * (or <code>xmlns:prefix="namespace"</code> depending what character is used
+     * to quote attribute value).
+     *
+     * <p><b>NOTE:</b> this method MUST be called directly before startTag()
+     *   and if anything but startTag() or setPrefix() is called next there will be exception.
+     * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
+     *   and can not be redefined see:
+     * <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>.
+     * <p><b>NOTE:</b> to set default namespace use as prefix empty string.
+     *
+     * @param prefix must be not null (or IllegalArgumentException is thrown)
+     * @param namespace must be not null
+     */
+    void setPrefix (String prefix, String namespace)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Return namespace that corresponds to given prefix
+     * If there is no prefix bound to this namespace return null
+     * but if generatePrefix is false then return generated prefix.
+     *
+     * <p><b>NOTE:</b> if the prefix is empty string "" and defualt namespace is bound
+     * to this prefix then empty string ("") is returned.
+     *
+     * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
+     *   will have values as defined
+     * <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a>
+     */
+    String getPrefix (String namespace, boolean generatePrefix)
+        throws IllegalArgumentException;
+    
+    /**
+     * Returns the current depth of the element.
+     * Outside the root element, the depth is 0. The
+     * depth is incremented by 1 when startTag() is called.
+     * The depth is decremented after the call to endTag()
+     * event was observed.
+     *
+     * <pre>
+     * &lt;!-- outside --&gt;     0
+     * &lt;root&gt;               1
+     *   sometext                 1
+     *     &lt;foobar&gt;         2
+     *     &lt;/foobar&gt;        2
+     * &lt;/root&gt;              1
+     * &lt;!-- outside --&gt;     0
+     * </pre>
+     */
+    int getDepth();
+    
+    /**
+     * Returns the namespace URI of the current element as set by startTag().
+     *
+     * <p><b>NOTE:</b> that measn in particaulr that: <ul>
+     * <li>if there was startTag("", ...) then getNamespace() returns ""
+     * <li>if there was startTag(null, ...) then getNamespace() returns null
+     * </ul>
+     *
+     * @return namespace set by startTag() that is currently in scope
+     */
+    String getNamespace ();
+    
+    /**
+     * Returns the name of the current element as set by startTag().
+     * It can only be null before first call to startTag()
+     * or when last endTag() is called to close first startTag().
+     *
+     * @return namespace set by startTag() that is currently in scope
+     */
+    String getName();
+    
+    /**
+     * Writes a start tag with the given namespace and name.
+     * If there is no prefix defined for the given namespace,
+     * a prefix will be defined automatically.
+     * The explicit prefixes for namespaces can be established by calling setPrefix()
+     * immediately before this method.
+     * If namespace is null no namespace prefix is printed but just name.
+     * If namespace is empty string then serialzier will make sure that
+     * default empty namespace is declared (in XML 1.0 xmlns='')
+     * or throw IllegalStateException if default namespace is already bound
+     * to non-empty string.
+     */
+    XmlSerializer startTag (String namespace, String name)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Write an attribute. Calls to attribute() MUST follow a call to
+     * startTag() immediately. If there is no prefix defined for the
+     * given namespace, a prefix will be defined automatically.
+     * If namespace is null or empty string
+     * no namespace prefix is printed but just name.
+     */
+    XmlSerializer attribute (String namespace, String name, String value)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Write end tag. Repetition of namespace and name is just for avoiding errors.
+     * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
+     *  very difficult to find...
+     * If namespace is null no namespace prefix is printed but just name.
+     * If namespace is empty string then serialzier will make sure that
+     * default empty namespace is declared (in XML 1.0 xmlns='').
+     */
+    XmlSerializer endTag (String namespace, String name)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    
+    //    /**
+    //     * Writes a start tag with the given namespace and name.
+    //     * <br />If there is no prefix defined (prefix == null) for the given namespace,
+    //     * a prefix will be defined automatically.
+    //     * <br />If explicit prefixes is passed (prefix != null) then it will be used
+    //      *and namespace declared if not already declared or
+    //     * throw IllegalStateException the same prefix was already set on this
+    //     * element (setPrefix()) and was bound to different namespace.
+    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+    //     * <br />If namespace is null then no namespace prefix is printed but just name.
+    //     * <br />If namespace is empty string then serializer will make sure that
+    //     * default empty namespace is declared (in XML 1.0 xmlns='')
+    //     * or throw IllegalStateException if default namespace is already bound
+    //     * to non-empty string.
+    //     */
+    //    XmlSerializer startTag (String prefix, String namespace, String name)
+    //        throws IOException, IllegalArgumentException, IllegalStateException;
+    //
+    //    /**
+    //     * Write an attribute. Calls to attribute() MUST follow a call to
+    //     * startTag() immediately.
+    //     * <br />If there is no prefix defined (prefix == null) for the given namespace,
+    //     * a prefix will be defined automatically.
+    //     * <br />If explicit prefixes is passed (prefix != null) then it will be used
+    //     * and namespace declared if not already declared or
+    //     * throw IllegalStateException the same prefix was already set on this
+    //     * element (setPrefix()) and was bound to different namespace.
+    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+    //     * <br />If namespace is null then no namespace prefix is printed but just name.
+    //     * <br />If namespace is empty string then serializer will make sure that
+    //     * default empty namespace is declared (in XML 1.0 xmlns='')
+    //     * or throw IllegalStateException if default namespace is already bound
+    //     * to non-empty string.
+    //     */
+    //    XmlSerializer attribute (String prefix, String namespace, String name, String value)
+    //        throws IOException, IllegalArgumentException, IllegalStateException;
+    //
+    //    /**
+    //     * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors.
+    //     * <br />If namespace or name arguments are different from corresponding startTag call
+    //     * then IllegalArgumentException is thrown, if prefix argument is not null and is different
+    //     * from corresponding starTag then IllegalArgumentException is thrown.
+    //     * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+    //     * <br />If namespace is null then no namespace prefix is printed but just name.
+    //     * <br />If namespace is empty string then serializer will make sure that
+    //     * default empty namespace is declared (in XML 1.0 xmlns='').
+    //     * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
+    //     *  very difficult to find...</p>
+    //     */
+    // ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking
+    //    XmlSerializer endTag (String prefix, String namespace, String name)
+    //        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Writes text, where special XML chars are escaped automatically
+     */
+    XmlSerializer text (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Writes text, where special XML chars are escaped automatically
+     */
+    XmlSerializer text (char [] buf, int start, int len)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    void cdsect (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    void entityRef (String text)  throws IOException,
+        IllegalArgumentException, IllegalStateException;
+    void processingInstruction (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    void comment (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    void docdecl (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    void ignorableWhitespace (String text)
+        throws IOException, IllegalArgumentException, IllegalStateException;
+    
+    /**
+     * Write all pending output to the stream.
+     * If method startTag() or attribute() was called then start tag is closed (final &gt;)
+     * before flush() is called on underlying output stream.
+     *
+     * <p><b>NOTE:</b> if there is need to close start tag
+     * (so no more attribute() calls are allowed) but without flushinging output
+     * call method text() with empty string (text("")).
+     *
+     */
+    void flush ()
+        throws IOException;
+    
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
new file mode 100644
index 0000000..0bd2d4f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
@@ -0,0 +1,469 @@
+/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1.sax2;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Reader;
+
+// not J2ME classes -- remove if you want to run in MIDP devices
+import java.net.URL;
+import java.net.MalformedURLException;
+
+
+// not J2ME classes
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+/**
+ * SAX2 Driver that pulls events from XmlPullParser
+ * and comverts them into SAX2 callbacks.
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+
+public class Driver implements Locator, XMLReader, Attributes
+{
+
+    protected static final String DECLARATION_HANDLER_PROPERTY =
+        "http://xml.org/sax/properties/declaration-handler";
+
+    protected static final String LEXICAL_HANDLER_PROPERTY =
+        "http://xml.org/sax/properties/lexical-handler";
+
+    protected static final String NAMESPACES_FEATURE =
+        "http://xml.org/sax/features/namespaces";
+
+    protected static final String NAMESPACE_PREFIXES_FEATURE =
+        "http://xml.org/sax/features/namespace-prefixes";
+
+    protected static final String VALIDATION_FEATURE =
+        "http://xml.org/sax/features/validation";
+
+    protected static final String APACHE_SCHEMA_VALIDATION_FEATURE =
+        "http://apache.org/xml/features/validation/schema";
+
+    protected static final String APACHE_DYNAMIC_VALIDATION_FEATURE =
+        "http://apache.org/xml/features/validation/dynamic";
+
+    protected ContentHandler contentHandler = new DefaultHandler();
+    protected ErrorHandler errorHandler = new DefaultHandler();;
+
+    protected String systemId;
+
+    protected XmlPullParser pp;
+
+    //private final static boolean DEBUG = false;
+
+    /**
+     */
+    public Driver() throws XmlPullParserException {
+        final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+        factory.setNamespaceAware(true);
+        pp = factory.newPullParser();
+    }
+
+    public Driver(XmlPullParser pp) throws XmlPullParserException {
+        this.pp = pp;
+    }
+
+    // -- Attributes interface
+
+    public int getLength() { return pp.getAttributeCount(); }
+    public String getURI(int index) { return pp.getAttributeNamespace(index); }
+    public String getLocalName(int index) { return pp.getAttributeName(index); }
+    public String getQName(int index) {
+        final String prefix = pp.getAttributePrefix(index);
+        if(prefix != null) {
+            return prefix+':'+pp.getAttributeName(index);
+        } else {
+            return pp.getAttributeName(index);
+        }
+    }
+    public String getType(int index) { return pp.getAttributeType(index); }
+    public String getValue(int index) { return pp.getAttributeValue(index); }
+
+    public int getIndex(String uri, String localName) {
+        for (int i = 0; i < pp.getAttributeCount(); i++)
+        {
+            if(pp.getAttributeNamespace(i).equals(uri)
+               && pp.getAttributeName(i).equals(localName))
+            {
+                return i;
+            }
+
+        }
+        return -1;
+    }
+
+    public int getIndex(String qName) {
+        for (int i = 0; i < pp.getAttributeCount(); i++)
+        {
+            if(pp.getAttributeName(i).equals(qName))
+            {
+                return i;
+            }
+
+        }
+        return -1;
+    }
+
+    public String getType(String uri, String localName) {
+        for (int i = 0; i < pp.getAttributeCount(); i++)
+        {
+            if(pp.getAttributeNamespace(i).equals(uri)
+               && pp.getAttributeName(i).equals(localName))
+            {
+                return pp.getAttributeType(i);
+            }
+
+        }
+        return null;
+    }
+    public String getType(String qName) {
+        for (int i = 0; i < pp.getAttributeCount(); i++)
+        {
+            if(pp.getAttributeName(i).equals(qName))
+            {
+                return pp.getAttributeType(i);
+            }
+
+        }
+        return null;
+    }
+    public String getValue(String uri, String localName) {
+        return pp.getAttributeValue(uri, localName);
+    }
+    public String getValue(String qName) {
+        return pp.getAttributeValue(null, qName);
+    }
+
+    // -- Locator interface
+
+    public String getPublicId() { return null; }
+    public String getSystemId() { return systemId; }
+    public int getLineNumber() { return pp.getLineNumber(); }
+    public int getColumnNumber() { return pp.getColumnNumber(); }
+
+    // --- XMLReader interface
+
+    public boolean getFeature(String name)
+        throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+        if(NAMESPACES_FEATURE.equals(name)) {
+            return pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+        } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
+            return pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
+        } else if(VALIDATION_FEATURE.equals(name)) {
+            return pp.getFeature(XmlPullParser.FEATURE_VALIDATION);
+            //        } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
+            //            return false;  //TODO
+            //        } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
+            //            return false; //TODO
+        } else {
+            return pp.getFeature(name);
+            //throw new SAXNotRecognizedException("unrecognized feature "+name);
+        }
+    }
+
+    public void setFeature (String name, boolean value)
+        throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+        try {
+            if(NAMESPACES_FEATURE.equals(name)) {
+                pp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, value);
+            } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
+                if(pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES) != value) {
+                    pp.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, value);
+                }
+            } else if(VALIDATION_FEATURE.equals(name)) {
+                pp.setFeature(XmlPullParser.FEATURE_VALIDATION, value);
+                //          } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
+                //              // can ignore as validation must be false ...
+                //              //              if(true == value) {
+                //              //                  throw new SAXNotSupportedException("schema validation is not supported");
+                //              //              }
+                //          } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
+                //              if(true == value) {
+                //                  throw new SAXNotSupportedException("dynamic validation is not supported");
+                //              }
+            } else {
+                pp.setFeature(name, value);
+                //throw new SAXNotRecognizedException("unrecognized feature "+name);
+            }
+        } catch(XmlPullParserException ex) {
+           // throw new SAXNotSupportedException("problem with setting feature "+name+": "+ex);
+        }
+    }
+
+    public Object getProperty (String name)
+        throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+        if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
+            return null;
+        } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
+            return null;
+        } else {
+            return pp.getProperty(name);
+            //throw new SAXNotRecognizedException("not recognized get property "+name);
+        }
+    }
+
+    public void setProperty (String name, Object value)
+        throws SAXNotRecognizedException, SAXNotSupportedException
+    {
+        //
+        if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
+            throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
+        } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
+            throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
+        } else {
+            try {
+                pp.setProperty(name, value);
+            } catch(XmlPullParserException ex) {
+                throw new SAXNotSupportedException("not supported set property "+name+": "+ ex);
+            }
+            //throw new SAXNotRecognizedException("not recognized set property "+name);
+        }
+    }
+
+    public void setEntityResolver (EntityResolver resolver) {}
+
+    public EntityResolver getEntityResolver () { return null; }
+
+    public void setDTDHandler (DTDHandler handler) {}
+
+    public DTDHandler getDTDHandler () { return null; }
+
+    public void setContentHandler (ContentHandler handler)
+    {
+        this.contentHandler = handler;
+    }
+
+    public ContentHandler getContentHandler() { return contentHandler; }
+
+    public void setErrorHandler(ErrorHandler handler) {
+        this.errorHandler = handler;
+    }
+
+    public ErrorHandler getErrorHandler() { return errorHandler; }
+
+    public void parse(InputSource source) throws SAXException, IOException
+    {
+
+        systemId = source.getSystemId();
+        contentHandler.setDocumentLocator(this);
+
+        final Reader reader = source.getCharacterStream();
+        try {
+            if (reader == null) {
+                InputStream stream = source.getByteStream();
+                final String encoding = source.getEncoding();
+
+                if (stream == null) {
+                    systemId = source.getSystemId();
+                    if(systemId == null) {
+                        SAXParseException saxException = new SAXParseException(
+                            "null source systemId" , this);
+                        errorHandler.fatalError(saxException);
+                        return;
+                    }
+                    // NOTE: replace with Connection to run in J2ME environment
+                    try {
+                        final URL url = new URL(systemId);
+                        stream = url.openStream();
+                    } catch (MalformedURLException nue) {
+                        try {
+                            stream = new FileInputStream(systemId);
+                        } catch (FileNotFoundException fnfe) {
+                            final SAXParseException saxException = new SAXParseException(
+                                "could not open file with systemId "+systemId, this, fnfe);
+                            errorHandler.fatalError(saxException);
+                            return;
+                        }
+                    }
+                }
+                pp.setInput(stream, encoding);
+            } else {
+                pp.setInput(reader);
+            }
+        } catch (XmlPullParserException ex)  {
+            final SAXParseException saxException = new SAXParseException(
+                "parsing initialization error: "+ex, this, ex);
+            //if(DEBUG) ex.printStackTrace();
+            errorHandler.fatalError(saxException);
+            return;
+        }
+
+        // start parsing - move to first start tag
+        try {
+            contentHandler.startDocument();
+            // get first event
+            pp.next();
+            // it should be start tag...
+            if(pp.getEventType() != XmlPullParser.START_TAG) {
+                final SAXParseException saxException = new SAXParseException(
+                    "expected start tag not"+pp.getPositionDescription(), this);
+                //throw saxException;
+                errorHandler.fatalError(saxException);
+                return;
+            }
+        } catch (XmlPullParserException ex)  {
+            final SAXParseException saxException = new SAXParseException(
+                "parsing initialization error: "+ex, this, ex);
+            //ex.printStackTrace();
+            errorHandler.fatalError(saxException);
+            return;
+        }
+
+        // now real parsing can start!
+
+        parseSubTree(pp);
+
+        // and finished ...
+
+        contentHandler.endDocument();
+    }
+
+    public void parse(String systemId) throws SAXException, IOException {
+        parse(new InputSource(systemId));
+    }
+
+
+    public void parseSubTree(XmlPullParser pp) throws SAXException, IOException {
+        this.pp = pp;
+        final boolean namespaceAware = pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+        try {
+            if(pp.getEventType() != XmlPullParser.START_TAG) {
+                throw new SAXException(
+                    "start tag must be read before skiping subtree"+pp.getPositionDescription());
+            }
+            final int[] holderForStartAndLength = new int[2];
+            final StringBuffer rawName = new StringBuffer(16);
+            String prefix = null;
+            String name = null;
+            int level = pp.getDepth() - 1;
+            int type = XmlPullParser.START_TAG;
+
+            LOOP:
+            do {
+                switch(type) {
+                    case XmlPullParser.START_TAG:
+                        if(namespaceAware) {
+                            final int depth = pp.getDepth() - 1;
+                            final int countPrev =
+                                (level > depth) ? pp.getNamespaceCount(depth) : 0;
+                            //int countPrev = pp.getNamespaceCount(pp.getDepth() - 1);
+                            final int count = pp.getNamespaceCount(depth + 1);
+                            for (int i = countPrev; i < count; i++)
+                            {
+                                contentHandler.startPrefixMapping(
+                                    pp.getNamespacePrefix(i),
+                                    pp.getNamespaceUri(i)
+                                );
+                            }
+                            name = pp.getName();
+                            prefix = pp.getPrefix();
+                            if(prefix != null) {
+                                rawName.setLength(0);
+                                rawName.append(prefix);
+                                rawName.append(':');
+                                rawName.append(name);
+                            }
+                            startElement(pp.getNamespace(),
+                                         name,
+                                         // TODO Fixed this. Was "not equals".
+                                         prefix == null ? name : rawName.toString());
+                        } else {
+                            startElement(pp.getNamespace(),
+                                         pp.getName(),
+                                         pp.getName());
+                        }
+                        //++level;
+
+                        break;
+                    case XmlPullParser.TEXT:
+                        final char[] chars = pp.getTextCharacters(holderForStartAndLength);
+                        contentHandler.characters(chars,
+                                                  holderForStartAndLength[0], //start
+                                                  holderForStartAndLength[1] //len
+                                                 );
+                        break;
+                    case XmlPullParser.END_TAG:
+                        //--level;
+                        if(namespaceAware) {
+                            name = pp.getName();
+                            prefix = pp.getPrefix();
+                            if(prefix != null) {
+                                rawName.setLength(0);
+                                rawName.append(prefix);
+                                rawName.append(':');
+                                rawName.append(name);
+                            }
+                            contentHandler.endElement(pp.getNamespace(),
+                                                      name,
+                                                      prefix != null ? name : rawName.toString()
+                                                     );
+                            // when entering show prefixes for all levels!!!!
+                            final int depth = pp.getDepth();
+                            final int countPrev =
+                                (level > depth) ? pp.getNamespaceCount(pp.getDepth()) : 0;
+                            int count = pp.getNamespaceCount(pp.getDepth() - 1);
+                            // undeclare them in reverse order
+                            for (int i = count - 1; i >= countPrev; i--)
+                            {
+                                contentHandler.endPrefixMapping(
+                                    pp.getNamespacePrefix(i)
+                                );
+                            }
+                        } else {
+                            contentHandler.endElement(pp.getNamespace(),
+                                                      pp.getName(),
+                                                      pp.getName()
+                                                     );
+
+                        }
+                        break;
+                    case XmlPullParser.END_DOCUMENT:
+                        break LOOP;
+                }
+                type = pp.next();
+            } while(pp.getDepth() > level);
+        } catch (XmlPullParserException ex)  {
+            final SAXParseException saxException = new SAXParseException("parsing error: "+ex, this, ex);
+            ex.printStackTrace();
+            errorHandler.fatalError(saxException);
+        }
+    }
+
+    /**
+     * Calls {@link ContentHandler#startElement(String, String, String, Attributes) startElement}
+     * on the <code>ContentHandler</code> with <code>this</code> driver object as the
+     * {@link Attributes} implementation. In default implementation
+     * {@link Attributes} object is valid only during this method call and may not
+     * be stored. Sub-classes can overwrite this method to cache attributes.
+     */
+    protected void startElement(String namespace, String localName, String qName) throws SAXException {
+        contentHandler.startElement(namespace, localName, qName, this);
+    }
+
+}
