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
index 59a8b78..c071899 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
@@ -73,7 +73,7 @@
             throw new DOMException(DOMException.NAMESPACE_ERR, localName);
         }
             
-        if (!document.isXMLIdentifier(localName)) {
+        if (!DocumentImpl.isXMLIdentifier(localName)) {
             throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName);
         }
             
@@ -90,11 +90,11 @@
             String prefix = name.substring(0, prefixSeparator);
             String localName = name.substring(prefixSeparator + 1);
             
-            if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+            if (!DocumentImpl.isXMLIdentifier(prefix) || !DocumentImpl.isXMLIdentifier(localName)) {
                 throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
             }
         } else {
-            if (!document.isXMLIdentifier(name)) {
+            if (!DocumentImpl.isXMLIdentifier(name)) {
                 throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
             }
         }
@@ -108,7 +108,9 @@
     }
 
     public String getName() {
-        return (prefix != null ? prefix + ":" : "") + localName;
+        return prefix != null
+                ? prefix + ":" + localName
+                : localName;
     }
 
     @Override
@@ -154,22 +156,7 @@
     
     @Override
     public void setPrefix(String prefix) {
-        if (!namespaceAware) {
-            throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
-        }
-        
-        if (prefix != null) {
-            if (namespaceURI == null
-                    || !DocumentImpl.isXMLIdentifier(prefix)
-                    || ("xmlns".equals(prefix)
-                            && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI))
-                    || ("xml".equals(prefix)
-                            && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI))) {
-                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
-            }
-        }
-
-        this.prefix = prefix;
+        this.prefix = validatePrefix(prefix, namespaceAware, namespaceURI);
     }
     
     public void setValue(String value) throws DOMException {
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
index 230e444..df1383d 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -65,7 +65,7 @@
             qualifiedName = qualifiedName.substring(p + 1);
         }
         
-        if (!document.isXMLIdentifier(qualifiedName)) {
+        if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
             throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
         }
             
@@ -82,11 +82,11 @@
             String prefix = name.substring(0, p);
             String localName = name.substring(p + 1);
             
-            if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+            if (!DocumentImpl.isXMLIdentifier(prefix) || !DocumentImpl.isXMLIdentifier(localName)) {
                 throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
             }
         } else {
-            if (!document.isXMLIdentifier(name)) {
+            if (!DocumentImpl.isXMLIdentifier(name)) {
                 throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
             }
         }
@@ -241,7 +241,9 @@
     }
 
     public String getTagName() {
-        return (prefix != null ? prefix + ":" : "") + localName;
+        return prefix != null
+                ? prefix + ":" + localName
+                : localName;
     }
 
     public boolean hasAttribute(String name) {
@@ -281,7 +283,7 @@
             throw new DOMException(DOMException.NOT_FOUND_ERR, null);
         }
 
-        attributes.remove(oldAttr);
+        attributes.remove(oldAttrImpl);
         oldAttrImpl.ownerElement = null;
 
         return oldAttrImpl;
@@ -362,21 +364,7 @@
 
     @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;
+        this.prefix = validatePrefix(prefix, namespaceAware, namespaceURI);
     }
     
     public class ElementAttrNamedNodeMapImpl implements NamedNodeMap {
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
index b752506..57ff7dc 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -16,6 +16,7 @@
 
 package org.apache.harmony.xml.dom;
 
+import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
@@ -24,16 +25,15 @@
 import org.w3c.dom.UserDataHandler;
 
 /**
- * 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.
+ * A straightforward implementation of the corresponding W3C DOM node.
+ *
+ * <p>Some fields have package visibility so other classes can access them while
+ * maintaining the DOM structure.
+ *
+ * <p>This class represents a Node that has neither a parent nor children.
+ * Subclasses may have either.
+ *
+ * <p>Some code was adapted from Apache Xerces.
  */
 public abstract class NodeImpl implements Node {
 
@@ -142,6 +142,29 @@
     }
 
     /**
+     * Validates the element or attribute namespace prefix on this node.
+     *
+     * @param namespaceAware whether this node is namespace aware
+     * @param namespaceURI this node's namespace URI
+     */
+    protected String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) {
+        if (!namespaceAware) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+        }
+
+        if (prefix != null) {
+            if (namespaceURI == null
+                    || !DocumentImpl.isXMLIdentifier(prefix)
+                    || "xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI)
+                    || "xmlns".equals(prefix) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
+                throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+            }
+        }
+
+        return prefix;
+    }
+
+    /**
      * 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.
@@ -190,7 +213,34 @@
     }
 
     public String getBaseURI() {
-        return null; // TODO
+        /*
+         * TODO: implement. For reference, here's Xerces' behaviour:
+         *
+         * In all cases, the returned URI should be sanitized before it is
+         * returned. If the URI is malformed, null should be returned instead.
+         *
+         * For document nodes, this should return a member field that's
+         * initialized by the parser.
+         *
+         * For element nodes, this should first look for the xml:base attribute.
+         *   if that exists and is absolute, it should be returned.
+         *   if that exists and is relative, it should be resolved to the parent's base URI
+         *   if it doesn't exist, the parent's baseURI should be returned
+         *
+         * For entity nodes, if a base URI exists that should be returned.
+         * Otherwise the document's base URI should be returned
+         *
+         * For entity references, if a base URI exists that should be returned
+         * otherwise it dereferences the entity (via the document) and uses the
+         * entity's base URI.
+         *
+         * For notations, it returns the base URI field.
+         *
+         * For processing instructions, it returns the parent's base URI.
+         *
+         * For all other node types, it returns null.
+         */
+        return null;
     }
 
     public short compareDocumentPosition(Node other)
@@ -210,23 +260,190 @@
     }
 
     public void setTextContent(String textContent) throws DOMException {
-        throw new UnsupportedOperationException(); // TODO
+        switch (getNodeType()) {
+            case DOCUMENT_TYPE_NODE:
+            case DOCUMENT_NODE:
+                return; // do nothing!
+
+            case ELEMENT_NODE:
+            case ENTITY_NODE:
+            case ENTITY_REFERENCE_NODE:
+            case DOCUMENT_FRAGMENT_NODE:
+                // remove all existing children
+                Node child;
+                while ((child = getFirstChild()) != null) {
+                    removeChild(child);
+                }
+                // create a text node to hold the given content
+                if (textContent != null && textContent.length() != 0){
+                    appendChild(getOwnerDocument().createTextNode(textContent));
+                }
+                return;
+
+            case ATTRIBUTE_NODE:
+            case TEXT_NODE:
+            case CDATA_SECTION_NODE:
+            case PROCESSING_INSTRUCTION_NODE:
+            case COMMENT_NODE:
+            case NOTATION_NODE:
+                setNodeValue(textContent);
+                return;
+
+            default:
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
+                        "Unsupported node type " + getNodeType());
+        }
     }
 
     public boolean isSameNode(Node other) {
-        throw new UnsupportedOperationException(); // TODO
+        return this == other;
     }
 
-    public String lookupPrefix(String namespaceURI) {
-        throw new UnsupportedOperationException(); // TODO
+    /**
+     * Returns the element whose namespace definitions apply to this node. Use
+     * this element when mapping prefixes to URIs and vice versa.
+     */
+    private NodeImpl getNamespacingElement() {
+        switch (this.getNodeType()) {
+            case ELEMENT_NODE:
+                return this;
+
+            case DOCUMENT_NODE:
+                return (NodeImpl) ((Document) this).getDocumentElement();
+
+            case ENTITY_NODE:
+            case NOTATION_NODE:
+            case DOCUMENT_FRAGMENT_NODE:
+            case DOCUMENT_TYPE_NODE:
+                return null;
+
+            case ATTRIBUTE_NODE:
+                return (NodeImpl) ((Attr) this).getOwnerElement();
+
+            case TEXT_NODE:
+            case CDATA_SECTION_NODE:
+            case ENTITY_REFERENCE_NODE:
+            case PROCESSING_INSTRUCTION_NODE:
+            case COMMENT_NODE:
+                return getContainingElement();
+
+            default:
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
+                        "Unsupported node type " + getNodeType());
+        }
+    }
+
+    /**
+     * Returns the nearest ancestor element that contains this node.
+     */
+    private NodeImpl getContainingElement() {
+        for (Node p = getParentNode(); p != null; p = p.getParentNode()) {
+            if (p.getNodeType() == ELEMENT_NODE) {
+                return (NodeImpl) p;
+            }
+        }
+        return null;
+    }
+
+    public final String lookupPrefix(String namespaceURI) {
+        if (namespaceURI == null) {
+            return null;
+        }
+
+        // the XML specs define some prefixes (like "xml" and "xmlns") but this
+        // API is explicitly defined to ignore those.
+
+        NodeImpl target = getNamespacingElement();
+        for (NodeImpl node = target; node != null; node = node.getContainingElement()) {
+            // check this element's namespace first
+            if (namespaceURI.equals(node.getNamespaceURI())
+                    && target.isPrefixMappedToUri(node.getPrefix(), namespaceURI)) {
+                return node.getPrefix();
+            }
+
+            // search this element for an attribute of this form:
+            //   xmlns:foo="http://namespaceURI"
+            if (!node.hasAttributes()) {
+                continue;
+            }
+            NamedNodeMap attributes = node.getAttributes();
+            for (int i = 0, length = attributes.getLength(); i < length; i++) {
+                Node attr = attributes.item(i);
+                if (!"http://www.w3.org/2000/xmlns/".equals(attr.getNamespaceURI())
+                        || !"xmlns".equals(attr.getPrefix())
+                        || !namespaceURI.equals(attr.getNodeValue())) {
+                    continue;
+                }
+                if (target.isPrefixMappedToUri(attr.getLocalName(), namespaceURI)) {
+                    return attr.getLocalName();
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns true if the given prefix is mapped to the given URI on this
+     * element. Since child elements can redefine prefixes, this check is
+     * necessary: {@code
+     * <foo xmlns:a="http://good">
+     *   <bar xmlns:a="http://evil">
+     *     <a:baz />
+     *   </bar>
+     * </foo>}
+     *
+     * @param prefix the prefix to find. Nullable.
+     * @param uri the URI to match. Non-null.
+     */
+    boolean isPrefixMappedToUri(String prefix, String uri) {
+        if (prefix == null) {
+            return false;
+        }
+
+        String actual = lookupNamespaceURI(prefix);
+        return uri.equals(actual);
     }
 
     public boolean isDefaultNamespace(String namespaceURI) {
         throw new UnsupportedOperationException(); // TODO
     }
 
-    public String lookupNamespaceURI(String prefix) {
-        throw new UnsupportedOperationException(); // TODO
+    public final String lookupNamespaceURI(String prefix) {
+        NodeImpl target = getNamespacingElement();
+        for (NodeImpl node = target; node != null; node = node.getContainingElement()) {
+            // check this element's namespace first
+            String nodePrefix = node.getPrefix();
+            if (node.getNamespaceURI() != null) {
+                if (prefix == null // null => default prefix
+                        ? nodePrefix == null
+                        : prefix.equals(nodePrefix)) {
+                    return node.getNamespaceURI();
+                }
+            }
+
+            // search this element for an attribute of the appropriate form.
+            //    default namespace: xmlns="http://resultUri"
+            //          non default: xmlns:specifiedPrefix="http://resultUri"
+            if (!node.hasAttributes()) {
+                continue;
+            }
+            NamedNodeMap attributes = node.getAttributes();
+            for (int i = 0, length = attributes.getLength(); i < length; i++) {
+                Node attr = attributes.item(i);
+                if (!"http://www.w3.org/2000/xmlns/".equals(attr.getNamespaceURI())) {
+                    continue;
+                }
+                if (prefix == null // null => default prefix
+                        ? "xmlns".equals(attr.getNodeName())
+                        : "xmlns".equals(attr.getPrefix()) && prefix.equals(attr.getLocalName())) {
+                    String value = attr.getNodeValue();
+                    return value.length() > 0 ? value : null;
+                }
+            }
+        }
+
+        return null;
     }
 
     public boolean isEqualNode(Node arg) {
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
index 5a3c48c..52240aa 100644
--- a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -115,8 +115,8 @@
         Document document = newDocument();
 
         try {
-            XmlPullParser parser = new KXmlParser();
-
+            KXmlParser parser = new KXmlParser();
+            parser.keepNamespaceAttributes();
             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,
                     namespaceAware);
             
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
index c4d8f3d..99eb03b 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ b/xml/src/main/java/org/kxml2/io/KXmlParser.java
@@ -45,6 +45,7 @@
 
     private boolean processNsp;
     private boolean relaxed;
+    private boolean keepNamespaceAttributes; // android-added
     private Hashtable entityMap;
     private int depth;
     private String[] elementStack = new String[16];
@@ -80,6 +81,14 @@
 
     private boolean degenerated;
     private int attributeCount;
+
+    /**
+     * The current element's attributes arranged in groups of 4:
+     * i + 0 = attribute namespace URI
+     * i + 1 = attribute namespace prefix
+     * i + 2 = attribute qualified name (may contain ":", as in "html:h1")
+     * i + 3 = attribute value
+     */
     private String[] attributes = new String[16];
 //    private int stackMismatch = 0;
     private String error;
@@ -100,6 +109,19 @@
             new char[Runtime.getRuntime().freeMemory() >= 1048576 ? 8192 : 128];
     }
 
+    // BEGIN android-added
+    /**
+     * Retains namespace attributes like {@code xmlns="http://foo"} or {@code
+     * xmlns:foo="http:foo"} in pulled elements. Most applications will only be
+     * interested in the effective namespaces of their elements, so these
+     * attributes aren't useful. But for structure preserving wrappers like DOM,
+     * it is necessary to keep the namespace data around.
+     */
+    public void keepNamespaceAttributes() {
+        this.keepNamespaceAttributes = true;
+    }
+    // END android-added
+
     private final boolean isProp(String n1, boolean prop, String n2) {
         if (!n1.startsWith("http://xmlpull.org/v1/doc/"))
             return false;
@@ -148,14 +170,23 @@
 
                 //System.out.println (prefixMap);
 
-                System.arraycopy(
-                    attributes,
-                    i + 4,
-                    attributes,
-                    i,
-                    ((--attributeCount) << 2) - i);
+                // BEGIN android-changed
+                if (keepNamespaceAttributes) {
+                    // explicitly set the namespace for unprefixed attributes 
+                    // such as xmlns="http://foo"
+                    attributes[i] = "http://www.w3.org/2000/xmlns/";
+                    any = true;
+                } else {
+                    System.arraycopy(
+                            attributes,
+                            i + 4,
+                            attributes,
+                            i,
+                            ((--attributeCount) << 2) - i);
 
-                i -= 4;
+                    i -= 4;
+                }
+                // END android-changed
             }
         }
 
diff --git a/xml/src/main/java/org/w3c/dom/Attr.java b/xml/src/main/java/org/w3c/dom/Attr.java
index d9ed6ff..bd7267b 100644
--- a/xml/src/main/java/org/w3c/dom/Attr.java
+++ b/xml/src/main/java/org/w3c/dom/Attr.java
@@ -176,7 +176,7 @@
     /**
      * On retrieval, 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 
+     * values. See also the method <code>getAttribute</code> on the
      * <code>Element</code> interface.
      * <br>On setting, this creates a <code>Text</code> node with the unparsed 
      * contents of the string, i.e. any characters that an XML processor 
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
index 02b6d80..6b10a0d 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
@@ -34,6 +34,7 @@
 import tests.api.org.xml.sax.support.MethodLogger;
 import tests.api.org.xml.sax.support.MockHandler;
 import tests.api.org.xml.sax.support.MockResolver;
+import tests.support.resource.Support_Resources;
 import tests.util.TestEnvironment;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -41,8 +42,6 @@
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -272,7 +271,7 @@
         args = {java.io.File.class}
     )
     public void testGetBaseURI() throws IOException, SAXException {
-        File f = resourceToTmpFile("/simple.xml");
+        File f = Support_Resources.resourceToTempFile("/simple.xml");
         Document d = db.parse(f);
         assertTrue(d.getDocumentElement().getBaseURI().startsWith("file://"));
     }
@@ -291,7 +290,7 @@
         args = {java.io.File.class}
     )
     public void test_parseLjava_io_File() throws IOException {
-        File f = resourceToTmpFile("/simple.xml");
+        File f = Support_Resources.resourceToTempFile("/simple.xml");
 
         // case 1: Trivial use.
         try {
@@ -333,7 +332,7 @@
         }
 
         // case 4: Try to parse incorrect xml file
-        f = resourceToTmpFile("/wrong.xml");
+        f = Support_Resources.resourceToTempFile("/wrong.xml");
         try {
             db.parse(f);
             fail("Expected SAXException was not thrown");
@@ -344,22 +343,6 @@
         }
     }
 
-    private File resourceToTmpFile(String path) throws IOException,
-            FileNotFoundException {
-        File f = File.createTempFile("out", ".xml");
-        f.deleteOnExit();
-        FileOutputStream out = new FileOutputStream(f);
-
-        InputStream xml = getClass().getResourceAsStream(path);
-        while (xml.available() > 0) {
-            out.write(xml.read());
-        }
-        out.flush();
-        out.close();
-        xml.close();
-        return f;
-    }
-
     /**
      * @tests javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
      * Case 1: Try to parse correct xml document.
diff --git a/xml/src/test/java/tests/xml/AllTests.java b/xml/src/test/java/tests/xml/AllTests.java
index 45ca18e..89da364 100644
--- a/xml/src/test/java/tests/xml/AllTests.java
+++ b/xml/src/test/java/tests/xml/AllTests.java
@@ -26,7 +26,7 @@
 
         suite.addTestSuite(SimpleParserTest.class);
         suite.addTestSuite(SimpleBuilderTest.class);
-        suite.addTestSuite(NodeTests.class);
+        suite.addTestSuite(NodeTest.class);
         
         //suite.addTest(tests.org.w3c.dom.AllTests.suite());
         suite.addTest(tests.api.javax.xml.parsers.AllTests.suite());
diff --git a/xml/src/test/java/tests/xml/DomTest.java b/xml/src/test/java/tests/xml/DomTest.java
new file mode 100644
index 0000000..d6031ed
--- /dev/null
+++ b/xml/src/test/java/tests/xml/DomTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2010 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 tests.xml;
+
+import junit.framework.TestCase;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Entity;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Construct a DOM and then interrogate it.
+ */
+public class DomTest extends TestCase {
+
+    private final String xml
+            = "<!DOCTYPE menu ["
+            + "  <!ENTITY sp \"Maple Syrup\">"
+            + "]>"
+            + "<menu>\n"
+            + "  <item xmlns=\"http://food\" xmlns:a=\"http://addons\">\n"
+            + "    <name a:standard=\"strawberry\" deluxe=\"&sp;\">Waffles</name>\n"
+            + "    <description xmlns=\"http://marketing\">Belgian<![CDATA[ waffles & strawberries (< 5g ]]>of fat)</description>\n"
+            + "    <a:option>Whipped Cream</a:option>\n"
+            + "    <a:option>&sp;</a:option>\n"
+            + "    <?wafflemaker square shape?>\n"
+            + "    <nutrition>\n"
+            + "      <a:vitamins xmlns:a=\"http://usda\">\n"
+            + "        <!-- add other vitamins? --> \n"
+            + "        <a:vitaminc>60%</a:vitaminc>\n"
+            + "      </a:vitamins>\n"
+            + "    </nutrition>\n"
+            + "  </item>\n"
+            + "</menu>";
+
+    private Document document;
+    private DocumentType doctype;
+    private Entity sp;
+    private Element menu;
+    private Element item;
+    private Attr itemXmlns;
+    private Attr itemXmlnsA;
+    private Element name;
+    private Attr standard;
+    private Attr deluxe;
+    private Element description;
+    private Text descriptionText1;
+    private CDATASection descriptionText2;
+    private Text descriptionText3;
+    private Element option1;
+    private Element option2;
+    private Node option2Reference; // Text on RI, EntityReference on Dalvik
+    private ProcessingInstruction wafflemaker;
+    private Element nutrition;
+    private Element vitamins;
+    private Attr vitaminsXmlnsA;
+    private Comment comment;
+    private Element vitaminc;
+    private Text vitamincText;
+
+    private List<Node> allNodes;
+
+    @Override protected void setUp() throws Exception {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+
+        document = factory.newDocumentBuilder()
+                .parse(new InputSource(new StringReader(xml)));
+
+        // doctype nodes
+        doctype = document.getDoctype();
+        if (doctype.getEntities() != null) {
+            sp = (Entity) doctype.getEntities().item(0);
+        }
+
+        // document nodes
+        menu = document.getDocumentElement();
+        item = (Element) menu.getChildNodes().item(1);
+        itemXmlns = item.getAttributeNode("xmlns");
+        itemXmlnsA = item.getAttributeNode("xmlns:a");
+        name = (Element) item.getChildNodes().item(1);
+        standard = name.getAttributeNode("a:standard");
+        deluxe = name.getAttributeNode("deluxe");
+        description = (Element) item.getChildNodes().item(3);
+        descriptionText1 = (Text) description.getChildNodes().item(0);
+        descriptionText2 = (CDATASection) description.getChildNodes().item(1);
+        descriptionText3 = (Text) description.getChildNodes().item(2);
+        option1 = (Element) item.getChildNodes().item(5);
+        option2 = (Element) item.getChildNodes().item(7);
+        option2Reference = option2.getChildNodes().item(0);
+        wafflemaker = (ProcessingInstruction) item.getChildNodes().item(9);
+        nutrition = (Element) item.getChildNodes().item(11);
+        vitamins = (Element) nutrition.getChildNodes().item(1);
+        vitaminsXmlnsA = vitamins.getAttributeNode("xmlns:a");
+        comment = (Comment) vitamins.getChildNodes().item(1);
+        vitaminc = (Element) vitamins.getChildNodes().item(3);
+        vitamincText = (Text) vitaminc.getChildNodes().item(0);
+
+        allNodes = new ArrayList<Node>();
+
+        if (sp != null) {
+            allNodes.add(sp);
+        }
+
+        allNodes.addAll(Arrays.asList(document, doctype, menu, item, itemXmlns,
+                itemXmlnsA, name, standard, deluxe, description,
+                descriptionText1, descriptionText2, descriptionText3, option1,
+                option2, option2Reference, wafflemaker, nutrition, vitamins,
+                vitaminsXmlnsA, comment, vitaminc, vitamincText));
+    }
+
+    /**
+     * Android's parsed DOM doesn't include entity declarations. These nodes will
+     * only be tested for implementations that support them.
+     */
+    public void testEntityDeclarations() {
+        assertNotNull("This implementation does not parse entity declarations", sp);
+    }
+
+    public void testLookupNamespaceURIByPrefix() {
+        assertEquals(null, doctype.lookupNamespaceURI("a"));
+        if (sp != null) {
+            assertEquals(null, sp.lookupNamespaceURI("a"));
+        }
+        assertEquals(null, document.lookupNamespaceURI("a"));
+        assertEquals(null, menu.lookupNamespaceURI("a"));
+        assertEquals("http://addons", item.lookupNamespaceURI("a"));
+        assertEquals("http://addons", itemXmlns.lookupNamespaceURI("a"));
+        assertEquals("http://addons", itemXmlnsA.lookupNamespaceURI("a"));
+        assertEquals("http://addons", name.lookupNamespaceURI("a"));
+        assertEquals("http://addons", standard.lookupNamespaceURI("a"));
+        assertEquals("http://addons", deluxe.lookupNamespaceURI("a"));
+        assertEquals("http://addons", description.lookupNamespaceURI("a"));
+        assertEquals("http://addons", descriptionText1.lookupNamespaceURI("a"));
+        assertEquals("http://addons", descriptionText2.lookupNamespaceURI("a"));
+        assertEquals("http://addons", descriptionText3.lookupNamespaceURI("a"));
+        assertEquals("http://addons", option1.lookupNamespaceURI("a"));
+        assertEquals("http://addons", option2.lookupNamespaceURI("a"));
+        assertEquals("http://addons", option2Reference.lookupNamespaceURI("a"));
+        assertEquals("http://addons", wafflemaker.lookupNamespaceURI("a"));
+        assertEquals("http://addons", nutrition.lookupNamespaceURI("a"));
+        assertEquals("http://usda", vitamins.lookupNamespaceURI("a"));
+        assertEquals("http://usda", vitaminsXmlnsA.lookupNamespaceURI("a"));
+        assertEquals("http://usda", comment.lookupNamespaceURI("a"));
+        assertEquals("http://usda", vitaminc.lookupNamespaceURI("a"));
+        assertEquals("http://usda", vitamincText.lookupNamespaceURI("a"));
+    }
+
+    public void testLookupNamespaceURIWithNullPrefix() {
+        assertEquals(null, document.lookupNamespaceURI(null));
+        assertEquals(null, doctype.lookupNamespaceURI(null));
+        if (sp != null) {
+            assertEquals(null, sp.lookupNamespaceURI(null));
+        }
+        assertEquals(null, menu.lookupNamespaceURI(null));
+        assertEquals("http://food", item.lookupNamespaceURI(null));
+        assertEquals("http://food", itemXmlns.lookupNamespaceURI(null));
+        assertEquals("http://food", itemXmlnsA.lookupNamespaceURI(null));
+        assertEquals("http://food", name.lookupNamespaceURI(null));
+        assertEquals("http://food", standard.lookupNamespaceURI(null));
+        assertEquals("http://food", deluxe.lookupNamespaceURI(null));
+        assertEquals("http://marketing", description.lookupNamespaceURI(null));
+        assertEquals("http://marketing", descriptionText1.lookupNamespaceURI(null));
+        assertEquals("http://marketing", descriptionText2.lookupNamespaceURI(null));
+        assertEquals("http://marketing", descriptionText3.lookupNamespaceURI(null));
+        assertEquals("http://food", option1.lookupNamespaceURI(null));
+        assertEquals("http://food", option2.lookupNamespaceURI(null));
+        assertEquals("http://food", option2Reference.lookupNamespaceURI(null));
+        assertEquals("http://food", wafflemaker.lookupNamespaceURI(null));
+        assertEquals("http://food", nutrition.lookupNamespaceURI(null));
+        assertEquals("http://food", vitamins.lookupNamespaceURI(null));
+        assertEquals("http://food", vitaminsXmlnsA.lookupNamespaceURI(null));
+        assertEquals("http://food", comment.lookupNamespaceURI(null));
+        assertEquals("http://food", vitaminc.lookupNamespaceURI(null));
+        assertEquals("http://food", vitamincText.lookupNamespaceURI(null));
+    }
+
+    public void testLookupNamespaceURIWithXmlnsPrefix() {
+        for (Node node : allNodes) {
+            assertEquals(null, node.lookupNamespaceURI("xmlns"));
+        }
+    }
+
+    public void testLookupPrefixWithShadowedUri() {
+        assertEquals(null, document.lookupPrefix("http://addons"));
+        assertEquals(null, doctype.lookupPrefix("http://addons"));
+        if (sp != null) {
+            assertEquals(null, sp.lookupPrefix("http://addons"));
+        }
+        assertEquals(null, menu.lookupPrefix("http://addons"));
+        assertEquals("a", item.lookupPrefix("http://addons"));
+        assertEquals("a", itemXmlns.lookupPrefix("http://addons"));
+        assertEquals("a", itemXmlnsA.lookupPrefix("http://addons"));
+        assertEquals("a", name.lookupPrefix("http://addons"));
+        assertEquals("a", standard.lookupPrefix("http://addons"));
+        assertEquals("a", deluxe.lookupPrefix("http://addons"));
+        assertEquals("a", description.lookupPrefix("http://addons"));
+        assertEquals("a", descriptionText1.lookupPrefix("http://addons"));
+        assertEquals("a", descriptionText2.lookupPrefix("http://addons"));
+        assertEquals("a", descriptionText3.lookupPrefix("http://addons"));
+        assertEquals("a", option1.lookupPrefix("http://addons"));
+        assertEquals("a", option2.lookupPrefix("http://addons"));
+        assertEquals("a", option2Reference.lookupPrefix("http://addons"));
+        assertEquals("a", wafflemaker.lookupPrefix("http://addons"));
+        assertEquals("a", nutrition.lookupPrefix("http://addons"));
+        assertEquals(null, vitamins.lookupPrefix("http://addons"));
+        assertEquals(null, vitaminsXmlnsA.lookupPrefix("http://addons"));
+        assertEquals(null, comment.lookupPrefix("http://addons"));
+        assertEquals(null, vitaminc.lookupPrefix("http://addons"));
+        assertEquals(null, vitamincText.lookupPrefix("http://addons"));
+    }
+
+    public void testLookupPrefixWithUnusedUri() {
+        for (Node node : allNodes) {
+            assertEquals(null, node.lookupPrefix("http://unused"));
+        }
+    }
+
+    public void testLookupPrefixWithNullUri() {
+        for (Node node : allNodes) {
+            assertEquals(null, node.lookupPrefix(null));
+        }
+    }
+
+    public void testLookupPrefixWithShadowingUri() {
+        assertEquals(null, document.lookupPrefix("http://usda"));
+        assertEquals(null, doctype.lookupPrefix("http://usda"));
+        if (sp != null) {
+            assertEquals(null, sp.lookupPrefix("http://usda"));
+        }
+        assertEquals(null, menu.lookupPrefix("http://usda"));
+        assertEquals(null, item.lookupPrefix("http://usda"));
+        assertEquals(null, itemXmlns.lookupPrefix("http://usda"));
+        assertEquals(null, itemXmlnsA.lookupPrefix("http://usda"));
+        assertEquals(null, name.lookupPrefix("http://usda"));
+        assertEquals(null, standard.lookupPrefix("http://usda"));
+        assertEquals(null, deluxe.lookupPrefix("http://usda"));
+        assertEquals(null, description.lookupPrefix("http://usda"));
+        assertEquals(null, descriptionText1.lookupPrefix("http://usda"));
+        assertEquals(null, descriptionText2.lookupPrefix("http://usda"));
+        assertEquals(null, descriptionText3.lookupPrefix("http://usda"));
+        assertEquals(null, option1.lookupPrefix("http://usda"));
+        assertEquals(null, option2.lookupPrefix("http://usda"));
+        assertEquals(null, option2Reference.lookupPrefix("http://usda"));
+        assertEquals(null, wafflemaker.lookupPrefix("http://usda"));
+        assertEquals(null, nutrition.lookupPrefix("http://usda"));
+        assertEquals("a", vitamins.lookupPrefix("http://usda"));
+        assertEquals("a", vitaminsXmlnsA.lookupPrefix("http://usda"));
+        assertEquals("a", comment.lookupPrefix("http://usda"));
+        assertEquals("a", vitaminc.lookupPrefix("http://usda"));
+        assertEquals("a", vitamincText.lookupPrefix("http://usda"));
+    }
+}
diff --git a/xml/src/test/java/tests/xml/NodeTest.java b/xml/src/test/java/tests/xml/NodeTest.java
new file mode 100644
index 0000000..dc3a333
--- /dev/null
+++ b/xml/src/test/java/tests/xml/NodeTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 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 tests.xml;
+
+import dalvik.annotation.TestTargetClass;
+import junit.framework.TestCase;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import tests.support.resource.Support_Resources;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+@TestTargetClass(Node.class)
+public class NodeTest extends TestCase {
+
+    /**
+     * For bug 779: Node#getNextSibling throws IndexOutOfBoundsException.
+     */
+    public void test_getNextSibling() throws Exception {
+        // Calling getNextSibling when there is no next sibling should return null.
+        // From http://code.google.com/p/android/issues/detail?id=779.
+        ByteArrayInputStream bis = new ByteArrayInputStream("<root/>".getBytes());
+        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bis);
+        Node root = document.getDocumentElement();
+        assertNull(root.getNextSibling());
+    }
+
+    public void testGetBaseUri() throws Exception {
+        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        File file = Support_Resources.resourceToTempFile("/simple.xml");
+        Document document = builder.parse(file);
+
+        String baseUri = "file:" + file.getPath();
+        assertEquals(baseUri, document.getBaseURI());
+
+        Element documentElement = document.getDocumentElement();
+        for (Node node : flattenSubtree(documentElement)) {
+            if (node.getNodeType() == Node.ELEMENT_NODE
+                    || node.getNodeType() == Node.DOCUMENT_NODE) {
+                assertEquals("Unexpected base URI for " + node, baseUri, node.getBaseURI());
+            } else {
+                assertNull("Unexpected base URI for " + node, node.getBaseURI());
+            }
+        }
+
+        // TODO: test other node types
+        // TODO: test resolution of relative paths
+        // TODO: test URI santization
+    }
+
+    private List<Node> flattenSubtree(Node subtree) {
+        List<Node> result = new ArrayList<Node>();
+        traverse(subtree, result);
+        return result;
+    }
+
+    private void traverse(Node node, List<Node> sink) {
+        sink.add(node);
+
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            traverse(children.item(i), sink);
+        }
+    }
+}
diff --git a/xml/src/test/java/tests/xml/NodeTests.java b/xml/src/test/java/tests/xml/NodeTests.java
deleted file mode 100644
index e46e216..0000000
--- a/xml/src/test/java/tests/xml/NodeTests.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 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 tests.xml;
-
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.ByteArrayInputStream;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-@TestTargetClass(Node.class)
-public class NodeTests extends TestCase {
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Issue #779: org.w3c.dom.Node#getNextSibling throws IndexOutOfBoundsException.",
-        method = "getNextSibling",
-        args = {}
-    )
-    public void test_getNextSibling() throws Exception {
-        // Calling getNextSibling when there is no next sibling should return null.
-        // From http://code.google.com/p/android/issues/detail?id=779.
-        ByteArrayInputStream bis = new ByteArrayInputStream("<root/>".getBytes());
-        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bis);
-        Node root = document.getDocumentElement();
-        assertNull(root.getNextSibling());
-    }
-}
