diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 23d679d..8c128d3 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -27,7 +27,6 @@
 sources := \
 	BigBuffer.cpp \
 	BinaryResourceParser.cpp \
-	BinaryXmlPullParser.cpp \
 	BindingXmlPullParser.cpp \
 	ConfigDescription.cpp \
 	Debug.cpp \
@@ -53,6 +52,7 @@
 	ScopedXmlPullParser.cpp \
 	SourceXmlPullParser.cpp \
 	XliffXmlPullParser.cpp \
+	XmlDom.cpp \
 	XmlFlattener.cpp \
 	ZipEntry.cpp \
 	ZipFile.cpp
@@ -76,6 +76,7 @@
 	StringPool_test.cpp \
 	Util_test.cpp \
 	XliffXmlPullParser_test.cpp \
+	XmlDom_test.cpp \
 	XmlFlattener_test.cpp
 
 cIncludes := \
diff --git a/tools/aapt2/BinaryXmlPullParser.cpp b/tools/aapt2/BinaryXmlPullParser.cpp
deleted file mode 100644
index 476a215..0000000
--- a/tools/aapt2/BinaryXmlPullParser.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#include "BinaryXmlPullParser.h"
-#include "Maybe.h"
-#include "Util.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace aapt {
-
-static XmlPullParser::Event codeToEvent(android::ResXMLParser::event_code_t code) {
-    switch (code) {
-        case android::ResXMLParser::START_DOCUMENT:
-            return XmlPullParser::Event::kStartDocument;
-        case android::ResXMLParser::END_DOCUMENT:
-            return XmlPullParser::Event::kEndDocument;
-        case android::ResXMLParser::START_NAMESPACE:
-            return XmlPullParser::Event::kStartNamespace;
-        case android::ResXMLParser::END_NAMESPACE:
-            return XmlPullParser::Event::kEndNamespace;
-        case android::ResXMLParser::START_TAG:
-            return XmlPullParser::Event::kStartElement;
-        case android::ResXMLParser::END_TAG:
-            return XmlPullParser::Event::kEndElement;
-        case android::ResXMLParser::TEXT:
-            return XmlPullParser::Event::kText;
-        default:
-            break;
-    }
-    return XmlPullParser::Event::kBadDocument;
-}
-
-BinaryXmlPullParser::BinaryXmlPullParser(const std::shared_ptr<android::ResXMLTree>& parser)
-    : mParser(parser), mEvent(Event::kStartDocument), mHasComment(false), sEmpty(), sEmpty8(),
-      mDepth(0) {
-}
-
-XmlPullParser::Event BinaryXmlPullParser::next() {
-    mStr1.clear();
-    mStr2.clear();
-    mAttributes.clear();
-
-    android::ResXMLParser::event_code_t code;
-    if (mHasComment) {
-        mHasComment = false;
-        code = mParser->getEventType();
-    } else {
-        code = mParser->next();
-        if (code != android::ResXMLParser::BAD_DOCUMENT) {
-            size_t len;
-            const char16_t* comment = mParser->getComment(&len);
-            if (comment) {
-                mHasComment = true;
-                mStr1.assign(comment, len);
-                return XmlPullParser::Event::kComment;
-            }
-        }
-    }
-
-    size_t len;
-    const char16_t* data;
-    mEvent = codeToEvent(code);
-    switch (mEvent) {
-        case Event::kStartNamespace:
-        case Event::kEndNamespace: {
-            data = mParser->getNamespacePrefix(&len);
-            if (data) {
-                mStr1.assign(data, len);
-            } else {
-                mStr1.clear();
-            }
-            data = mParser->getNamespaceUri(&len);
-            if (data) {
-                mStr2.assign(data, len);
-            } else {
-                mStr2.clear();
-            }
-
-            Maybe<std::u16string> result = util::extractPackageFromNamespace(mStr2);
-            if (result) {
-                if (mEvent == Event::kStartNamespace) {
-                    mPackageAliases.emplace_back(mStr1, result.value());
-                } else {
-                    assert(mPackageAliases.back().second == result.value());
-                    mPackageAliases.pop_back();
-                }
-            }
-            break;
-        }
-
-        case Event::kStartElement:
-            copyAttributes();
-            // fallthrough
-
-        case Event::kEndElement:
-            data = mParser->getElementNamespace(&len);
-            if (data) {
-                mStr1.assign(data, len);
-            } else {
-                mStr1.clear();
-            }
-            data = mParser->getElementName(&len);
-            if (data) {
-                mStr2.assign(data, len);
-            } else {
-                mStr2.clear();
-            }
-            break;
-
-        case Event::kText:
-            data = mParser->getText(&len);
-            if (data) {
-                mStr1.assign(data, len);
-            } else {
-                mStr1.clear();
-            }
-            break;
-
-        default:
-            break;
-    }
-    return mEvent;
-}
-
-XmlPullParser::Event BinaryXmlPullParser::getEvent() const {
-    if (mHasComment) {
-        return XmlPullParser::Event::kComment;
-    }
-    return mEvent;
-}
-
-const std::string& BinaryXmlPullParser::getLastError() const {
-    return sEmpty8;
-}
-
-const std::u16string& BinaryXmlPullParser::getComment() const {
-    if (mHasComment) {
-        return mStr1;
-    }
-    return sEmpty;
-}
-
-size_t BinaryXmlPullParser::getLineNumber() const {
-    return mParser->getLineNumber();
-}
-
-size_t BinaryXmlPullParser::getDepth() const {
-    return mDepth;
-}
-
-const std::u16string& BinaryXmlPullParser::getText() const {
-    if (!mHasComment && mEvent == XmlPullParser::Event::kText) {
-        return mStr1;
-    }
-    return sEmpty;
-}
-
-const std::u16string& BinaryXmlPullParser::getNamespacePrefix() const {
-    if (!mHasComment && (mEvent == XmlPullParser::Event::kStartNamespace ||
-            mEvent == XmlPullParser::Event::kEndNamespace)) {
-        return mStr1;
-    }
-    return sEmpty;
-}
-
-const std::u16string& BinaryXmlPullParser::getNamespaceUri() const {
-    if (!mHasComment && (mEvent == XmlPullParser::Event::kStartNamespace ||
-            mEvent == XmlPullParser::Event::kEndNamespace)) {
-        return mStr2;
-    }
-    return sEmpty;
-}
-
-bool BinaryXmlPullParser::applyPackageAlias(std::u16string* package,
-                                            const std::u16string& defaultPackage) const {
-    const auto endIter = mPackageAliases.rend();
-    for (auto iter = mPackageAliases.rbegin(); iter != endIter; ++iter) {
-        if (iter->first == *package) {
-            if (iter->second.empty()) {
-                *package = defaultPackage;
-            } else {
-                *package = iter->second;
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-const std::u16string& BinaryXmlPullParser::getElementNamespace() const {
-    if (!mHasComment && (mEvent == XmlPullParser::Event::kStartElement ||
-            mEvent == XmlPullParser::Event::kEndElement)) {
-        return mStr1;
-    }
-    return sEmpty;
-}
-
-const std::u16string& BinaryXmlPullParser::getElementName() const {
-    if (!mHasComment && (mEvent == XmlPullParser::Event::kStartElement ||
-            mEvent == XmlPullParser::Event::kEndElement)) {
-        return mStr2;
-    }
-    return sEmpty;
-}
-
-size_t BinaryXmlPullParser::getAttributeCount() const {
-    return mAttributes.size();
-}
-
-XmlPullParser::const_iterator BinaryXmlPullParser::beginAttributes() const {
-    return mAttributes.begin();
-}
-
-XmlPullParser::const_iterator BinaryXmlPullParser::endAttributes() const {
-    return mAttributes.end();
-}
-
-void BinaryXmlPullParser::copyAttributes() {
-    const size_t attrCount = mParser->getAttributeCount();
-    if (attrCount > 0) {
-        mAttributes.reserve(attrCount);
-        for (size_t i = 0; i < attrCount; i++) {
-            XmlPullParser::Attribute attr;
-            size_t len;
-            const char16_t* str = mParser->getAttributeNamespace(i, &len);
-            if (str) {
-                attr.namespaceUri.assign(str, len);
-            }
-            str = mParser->getAttributeName(i, &len);
-            if (str) {
-                attr.name.assign(str, len);
-            }
-            str = mParser->getAttributeStringValue(i, &len);
-            if (str) {
-                attr.value.assign(str, len);
-            }
-            mAttributes.push_back(std::move(attr));
-        }
-    }
-}
-
-} // namespace aapt
diff --git a/tools/aapt2/BinaryXmlPullParser.h b/tools/aapt2/BinaryXmlPullParser.h
deleted file mode 100644
index 16fc8b7..0000000
--- a/tools/aapt2/BinaryXmlPullParser.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef AAPT_BINARY_XML_PULL_PARSER_H
-#define AAPT_BINARY_XML_PULL_PARSER_H
-
-#include "XmlPullParser.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace aapt {
-
-/**
- * Wraps a ResTable into the canonical XmlPullParser interface.
- */
-class BinaryXmlPullParser : public XmlPullParser {
-public:
-    BinaryXmlPullParser(const std::shared_ptr<android::ResXMLTree>& parser);
-    BinaryXmlPullParser(const BinaryXmlPullParser& rhs) = delete;
-
-    Event getEvent() const override;
-    const std::string& getLastError() const override;
-    Event next() override;
-
-    const std::u16string& getComment() const override;
-    size_t getLineNumber() const override;
-    size_t getDepth() const override;
-
-    const std::u16string& getText() const override;
-
-    const std::u16string& getNamespacePrefix() const override;
-    const std::u16string& getNamespaceUri() const override;
-    bool applyPackageAlias(std::u16string* package, const std::u16string& defaultpackage)
-            const override;
-
-    const std::u16string& getElementNamespace() const override;
-    const std::u16string& getElementName() const override;
-
-    const_iterator beginAttributes() const override;
-    const_iterator endAttributes() const override;
-    size_t getAttributeCount() const override;
-
-private:
-    void copyAttributes();
-
-    std::shared_ptr<android::ResXMLTree> mParser;
-    std::u16string mStr1;
-    std::u16string mStr2;
-    std::vector<Attribute> mAttributes;
-    Event mEvent;
-    bool mHasComment;
-    const std::u16string sEmpty;
-    const std::string sEmpty8;
-    size_t mDepth;
-    std::vector<std::pair<std::u16string, std::u16string>> mPackageAliases;
-};
-
-} // namespace aapt
-
-#endif // AAPT_BINARY_XML_PULL_PARSER_H
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 91639c5..84957b4 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -17,7 +17,6 @@
 #include "AppInfo.h"
 #include "BigBuffer.h"
 #include "BinaryResourceParser.h"
-#include "BinaryXmlPullParser.h"
 #include "BindingXmlPullParser.h"
 #include "Debug.h"
 #include "Files.h"
@@ -128,7 +127,7 @@
                     auto iter = style.entries.begin();
                     while (iter != style.entries.end()) {
                         if (iter->key.name.package == u"android") {
-                            size_t sdkLevel = findAttributeSdkLevel(iter->key.name.entry);
+                            size_t sdkLevel = findAttributeSdkLevel(iter->key.name);
                             if (sdkLevel > 1 && sdkLevel > configValue.config.sdkVersion) {
                                 // Record that we are about to strip this.
                                 stripped.emplace_back(std::move(*iter));
@@ -300,6 +299,42 @@
     ResourceName dumpStyleTarget;
 };
 
+struct IdCollector : public xml::Visitor {
+    IdCollector(const Source& source, const std::shared_ptr<ResourceTable>& table) :
+            mSource(source), mTable(table) {
+    }
+
+    virtual void visit(xml::Text* node) override {}
+
+    virtual void visit(xml::Namespace* node) override {
+        for (const auto& child : node->children) {
+            child->accept(this);
+        }
+    }
+
+    virtual void visit(xml::Element* node) override {
+        for (const xml::Attribute& attr : node->attributes) {
+            bool create = false;
+            bool priv = false;
+            ResourceNameRef nameRef;
+            if (ResourceParser::tryParseReference(attr.value, &nameRef, &create, &priv)) {
+                if (create) {
+                    mTable->addResource(nameRef, {}, mSource.line(node->lineNumber),
+                                        util::make_unique<Id>());
+                }
+            }
+        }
+
+        for (const auto& child : node->children) {
+            child->accept(this);
+        }
+    }
+
+private:
+    Source mSource;
+    std::shared_ptr<ResourceTable> mTable;
+};
+
 bool compileXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
                 const CompileItem& item, ZipFile* outApk) {
     std::ifstream in(item.source.path, std::ifstream::binary);
@@ -308,20 +343,19 @@
         return false;
     }
 
+    SourceLogger logger(item.source);
+    std::unique_ptr<xml::Node> root = xml::inflate(&in, &logger);
+    if (!root) {
+        return false;
+    }
+
+    // Collect any resource ID's declared here.
+    IdCollector idCollector(item.source, table);
+    root->accept(&idCollector);
+
     BigBuffer outBuffer(1024);
-
-    // No resolver, since we are not compiling attributes here.
-    XmlFlattener flattener(table, {});
-
-    XmlFlattener::Options xmlOptions;
-    xmlOptions.defaultPackage = table->getPackage();
-    xmlOptions.keepRawValues = true;
-
-    std::shared_ptr<XmlPullParser> parser = std::make_shared<SourceXmlPullParser>(in);
-
-    Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, parser, &outBuffer,
-                                                     xmlOptions);
-    if (!minStrippedSdk) {
+    if (!xml::flatten(root.get(), options.appInfo.package, &outBuffer)) {
+        logger.error() << "failed to encode XML." << std::endl;
         return false;
     }
 
@@ -369,19 +403,13 @@
 bool linkXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
              const std::shared_ptr<IResolver>& resolver, const LinkItem& item,
              const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue) {
-    std::shared_ptr<android::ResXMLTree> tree = std::make_shared<android::ResXMLTree>();
-    if (tree->setTo(data, dataLen, false) != android::NO_ERROR) {
+    SourceLogger logger(item.source);
+    std::unique_ptr<xml::Node> root = xml::inflate(data, dataLen, &logger);
+    if (!root) {
         return false;
     }
 
-    std::shared_ptr<XmlPullParser> parser = std::make_shared<BinaryXmlPullParser>(tree);
-
-    BigBuffer outBuffer(1024);
-    XmlFlattener flattener({}, resolver);
-
-    XmlFlattener::Options xmlOptions;
-    xmlOptions.defaultPackage = item.originalPackage;
-
+    xml::FlattenOptions xmlOptions;
     if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
         xmlOptions.keepRawValues = true;
     }
@@ -392,16 +420,12 @@
         xmlOptions.maxSdkAttribute = item.config.sdkVersion ? item.config.sdkVersion : 1;
     }
 
-    std::shared_ptr<BindingXmlPullParser> binding;
-    if (item.name.type == ResourceType::kLayout) {
-        // Layouts may have defined bindings, so we need to make sure they get processed.
-        binding = std::make_shared<BindingXmlPullParser>(parser);
-        parser = binding;
-    }
-
-    Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, parser, &outBuffer,
-                                                     xmlOptions);
+    BigBuffer outBuffer(1024);
+    Maybe<size_t> minStrippedSdk = xml::flattenAndLink(item.source, root.get(),
+                                                       item.originalPackage, resolver,
+                                                       xmlOptions, &outBuffer);
     if (!minStrippedSdk) {
+        logger.error() << "failed to encode XML." << std::endl;
         return false;
     }
 
@@ -431,30 +455,6 @@
                                       << buildFileReference(item) << "' to apk." << std::endl;
         return false;
     }
-
-    if (binding && !options.bindingOutput.path.empty()) {
-        // We generated a binding xml file, write it out.
-        Source bindingOutput = options.bindingOutput;
-        appendPath(&bindingOutput.path, buildFileReference(item));
-
-        if (!mkdirs(bindingOutput.path)) {
-            Logger::error(bindingOutput) << strerror(errno) << std::endl;
-            return false;
-        }
-
-        appendPath(&bindingOutput.path, "bind.xml");
-
-        std::ofstream bout(bindingOutput.path);
-        if (!bout) {
-            Logger::error(bindingOutput) << strerror(errno) << std::endl;
-            return false;
-        }
-
-        if (!binding->writeToFile(bout)) {
-            Logger::error(bindingOutput) << strerror(errno) << std::endl;
-            return false;
-        }
-    }
     return true;
 }
 
@@ -504,13 +504,15 @@
         return false;
     }
 
-    BigBuffer outBuffer(1024);
-    std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(in);
-    XmlFlattener flattener({}, resolver);
+    SourceLogger logger(options.manifest);
+    std::unique_ptr<xml::Node> root = xml::inflate(&in, &logger);
+    if (!root) {
+        return false;
+    }
 
-    XmlFlattener::Options xmlOptions;
-    xmlOptions.defaultPackage = options.appInfo.package;
-    if (!flattener.flatten(options.manifest, xmlParser, &outBuffer, xmlOptions)) {
+    BigBuffer outBuffer(1024);
+    if (!xml::flattenAndLink(options.manifest, root.get(), options.appInfo.package, resolver, {},
+                &outBuffer)) {
         return false;
     }
 
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 3f156a6..9bdae49 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -14,11 +14,51 @@
  * limitations under the License.
  */
 
+#include "SdkConstants.h"
+
+#include <algorithm>
 #include <string>
 #include <unordered_map>
+#include <vector>
 
 namespace aapt {
 
+static const std::vector<std::pair<uint16_t, size_t>> sAttrIdMap = {
+    { 0x021c, 1 },
+    { 0x021d, 2 },
+    { 0x0269, SDK_CUPCAKE },
+    { 0x028d, SDK_DONUT },
+    { 0x02ad, SDK_ECLAIR },
+    { 0x02b3, SDK_ECLAIR_0_1 },
+    { 0x02b5, SDK_ECLAIR_MR1 },
+    { 0x02bd, SDK_FROYO },
+    { 0x02cb, SDK_GINGERBREAD },
+    { 0x0361, SDK_HONEYCOMB },
+    { 0x0366, SDK_HONEYCOMB_MR1 },
+    { 0x03a6, SDK_HONEYCOMB_MR2 },
+    { 0x03ae, SDK_JELLY_BEAN },
+    { 0x03cc, SDK_JELLY_BEAN_MR1 },
+    { 0x03da, SDK_JELLY_BEAN_MR2 },
+    { 0x03f1, SDK_KITKAT },
+    { 0x03f6, SDK_KITKAT_WATCH },
+    { 0x04ce, SDK_LOLLIPOP },
+};
+
+static bool lessEntryId(const std::pair<uint16_t, size_t>& p, uint16_t entryId) {
+    return p.first < entryId;
+}
+
+size_t findAttributeSdkLevel(ResourceId id) {
+    if (id.packageId() != 0x01 && id.typeId() != 0x01) {
+        return 0;
+    }
+    auto iter = std::lower_bound(sAttrIdMap.begin(), sAttrIdMap.end(), id.entryId(), lessEntryId);
+    if (iter == sAttrIdMap.end()) {
+        return SDK_LOLLIPOP_MR1;
+    }
+    return iter->second;
+}
+
 static const std::unordered_map<std::u16string, size_t> sAttrMap = {
     { u"marqueeRepeatLimit", 2 },
     { u"windowNoDisplay", 3 },
@@ -682,12 +722,16 @@
     { u"colorEdgeEffect", 21 }
 };
 
-size_t findAttributeSdkLevel(const std::u16string& name) {
-    auto iter = sAttrMap.find(name);
+size_t findAttributeSdkLevel(const ResourceName& name) {
+    if (name.package != u"android" && name.type != ResourceType::kAttr) {
+        return 0;
+    }
+
+    auto iter = sAttrMap.find(name.entry);
     if (iter != sAttrMap.end()) {
         return iter->second;
     }
-    return 0;
+    return SDK_LOLLIPOP_MR1;
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index 469c355..803da03 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -19,8 +19,6 @@
 
 #include "Resource.h"
 
-#include <string>
-
 namespace aapt {
 
 enum {
@@ -46,7 +44,8 @@
     SDK_LOLLIPOP_MR1 = 22,
 };
 
-size_t findAttributeSdkLevel(const std::u16string& name);
+size_t findAttributeSdkLevel(ResourceId id);
+size_t findAttributeSdkLevel(const ResourceName& name);
 
 } // namespace aapt
 
diff --git a/tools/aapt2/XmlDom.cpp b/tools/aapt2/XmlDom.cpp
new file mode 100644
index 0000000..763029f
--- /dev/null
+++ b/tools/aapt2/XmlDom.cpp
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include "Logger.h"
+#include "Util.h"
+#include "XmlDom.h"
+#include "XmlPullParser.h"
+
+#include <cassert>
+#include <memory>
+#include <stack>
+#include <string>
+#include <tuple>
+
+namespace aapt {
+namespace xml {
+
+constexpr char kXmlNamespaceSep = 1;
+
+struct Stack {
+    std::unique_ptr<xml::Node> root;
+    std::stack<xml::Node*> nodeStack;
+    std::u16string pendingComment;
+};
+
+/**
+ * Extracts the namespace and name of an expanded element or attribute name.
+ */
+static void splitName(const char* name, std::u16string* outNs, std::u16string* outName) {
+    const char* p = name;
+    while (*p != 0 && *p != kXmlNamespaceSep) {
+        p++;
+    }
+
+    if (*p == 0) {
+        outNs->clear();
+        *outName = util::utf8ToUtf16(name);
+    } else {
+        *outNs = util::utf8ToUtf16(StringPiece(name, (p - name)));
+        *outName = util::utf8ToUtf16(p + 1);
+    }
+}
+
+static void addToStack(Stack* stack, XML_Parser parser, std::unique_ptr<Node> node) {
+    node->lineNumber = XML_GetCurrentLineNumber(parser);
+    node->columnNumber = XML_GetCurrentColumnNumber(parser);
+
+    Node* thisNode = node.get();
+    if (!stack->nodeStack.empty()) {
+        stack->nodeStack.top()->addChild(std::move(node));
+    } else {
+        stack->root = std::move(node);
+    }
+
+    if (thisNode->type != NodeType::kText) {
+        stack->nodeStack.push(thisNode);
+    }
+}
+
+static void XMLCALL startNamespaceHandler(void* userData, const char* prefix, const char* uri) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    std::unique_ptr<Namespace> ns = util::make_unique<Namespace>();
+    if (prefix) {
+        ns->namespacePrefix = util::utf8ToUtf16(prefix);
+    }
+
+    if (uri) {
+        ns->namespaceUri = util::utf8ToUtf16(uri);
+    }
+
+    addToStack(stack, parser, std::move(ns));
+}
+
+static void XMLCALL endNamespaceHandler(void* userData, const char* prefix) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    assert(!stack->nodeStack.empty());
+    stack->nodeStack.pop();
+}
+
+static bool lessAttribute(const Attribute& lhs, const Attribute& rhs) {
+    return std::tie(lhs.namespaceUri, lhs.name, lhs.value) <
+            std::tie(rhs.namespaceUri, rhs.name, rhs.value);
+}
+
+static void XMLCALL startElementHandler(void* userData, const char* name, const char** attrs) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    std::unique_ptr<Element> el = util::make_unique<Element>();
+    splitName(name, &el->namespaceUri, &el->name);
+
+    while (*attrs) {
+        Attribute attribute;
+        splitName(*attrs++, &attribute.namespaceUri, &attribute.name);
+        attribute.value = util::utf8ToUtf16(*attrs++);
+
+        // Insert in sorted order.
+        auto iter = std::lower_bound(el->attributes.begin(), el->attributes.end(), attribute,
+                                     lessAttribute);
+        el->attributes.insert(iter, std::move(attribute));
+    }
+
+    el->comment = std::move(stack->pendingComment);
+    addToStack(stack, parser, std::move(el));
+}
+
+static void XMLCALL endElementHandler(void* userData, const char* name) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    assert(!stack->nodeStack.empty());
+    stack->nodeStack.top()->comment = std::move(stack->pendingComment);
+    stack->nodeStack.pop();
+}
+
+static void XMLCALL characterDataHandler(void* userData, const char* s, int len) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    if (!s || len <= 0) {
+        return;
+    }
+
+    // See if we can just append the text to a previous text node.
+    if (!stack->nodeStack.empty()) {
+        Node* currentParent = stack->nodeStack.top();
+        if (!currentParent->children.empty()) {
+            Node* lastChild = currentParent->children.back().get();
+            if (lastChild->type == NodeType::kText) {
+                Text* text = static_cast<Text*>(lastChild);
+                text->text += util::utf8ToUtf16(StringPiece(s, len));
+                return;
+            }
+        }
+    }
+
+    std::unique_ptr<Text> text = util::make_unique<Text>();
+    text->text = util::utf8ToUtf16(StringPiece(s, len));
+    addToStack(stack, parser, std::move(text));
+}
+
+static void XMLCALL commentDataHandler(void* userData, const char* comment) {
+    XML_Parser parser = reinterpret_cast<XML_Parser>(userData);
+    Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser));
+
+    if (!stack->pendingComment.empty()) {
+        stack->pendingComment += '\n';
+    }
+    stack->pendingComment += util::utf8ToUtf16(comment);
+}
+
+std::unique_ptr<Node> inflate(std::istream* in, SourceLogger* logger) {
+    Stack stack;
+
+    XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
+    XML_SetUserData(parser, &stack);
+    XML_UseParserAsHandlerArg(parser);
+    XML_SetElementHandler(parser, startElementHandler, endElementHandler);
+    XML_SetNamespaceDeclHandler(parser, startNamespaceHandler, endNamespaceHandler);
+    XML_SetCharacterDataHandler(parser, characterDataHandler);
+    XML_SetCommentHandler(parser, commentDataHandler);
+
+    char buffer[1024];
+    while (!in->eof()) {
+        in->read(buffer, sizeof(buffer) / sizeof(buffer[0]));
+        if (in->bad() && !in->eof()) {
+            stack.root = {};
+            logger->error() << strerror(errno) << std::endl;
+            break;
+        }
+
+        if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == XML_STATUS_ERROR) {
+            stack.root = {};
+            logger->error(XML_GetCurrentLineNumber(parser))
+                    << XML_ErrorString(XML_GetErrorCode(parser)) << std::endl;
+            break;
+        }
+    }
+
+    XML_ParserFree(parser);
+    return std::move(stack.root);
+}
+
+static void copyAttributes(Element* el, android::ResXMLParser* parser) {
+    const size_t attrCount = parser->getAttributeCount();
+    if (attrCount > 0) {
+        el->attributes.reserve(attrCount);
+        for (size_t i = 0; i < attrCount; i++) {
+            Attribute attr;
+            size_t len;
+            const char16_t* str16 = parser->getAttributeNamespace(i, &len);
+            if (str16) {
+                attr.namespaceUri.assign(str16, len);
+            }
+
+            str16 = parser->getAttributeName(i, &len);
+            if (str16) {
+                attr.name.assign(str16, len);
+            }
+
+            str16 = parser->getAttributeStringValue(i, &len);
+            if (str16) {
+                attr.value.assign(str16, len);
+            }
+            el->attributes.push_back(std::move(attr));
+        }
+    }
+}
+
+std::unique_ptr<Node> inflate(const void* data, size_t dataLen, SourceLogger* logger) {
+    std::unique_ptr<Node> root;
+    std::stack<Node*> nodeStack;
+
+    android::ResXMLTree tree;
+    if (tree.setTo(data, dataLen) != android::NO_ERROR) {
+        return {};
+    }
+
+    android::ResXMLParser::event_code_t code;
+    while ((code = tree.next()) != android::ResXMLParser::BAD_DOCUMENT &&
+            code != android::ResXMLParser::END_DOCUMENT) {
+        std::unique_ptr<Node> newNode;
+        switch (code) {
+            case android::ResXMLParser::START_NAMESPACE: {
+                std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
+                size_t len;
+                const char16_t* str16 = tree.getNamespacePrefix(&len);
+                if (str16) {
+                    node->namespacePrefix.assign(str16, len);
+                }
+
+                str16 = tree.getNamespaceUri(&len);
+                if (str16) {
+                    node->namespaceUri.assign(str16, len);
+                }
+                newNode = std::move(node);
+                break;
+            }
+
+            case android::ResXMLParser::START_TAG: {
+                std::unique_ptr<Element> node = util::make_unique<Element>();
+                size_t len;
+                const char16_t* str16 = tree.getElementNamespace(&len);
+                if (str16) {
+                    node->namespaceUri.assign(str16, len);
+                }
+
+                str16 = tree.getElementName(&len);
+                if (str16) {
+                    node->name.assign(str16, len);
+                }
+
+                copyAttributes(node.get(), &tree);
+
+                newNode = std::move(node);
+                break;
+            }
+
+            case android::ResXMLParser::TEXT: {
+                std::unique_ptr<Text> node = util::make_unique<Text>();
+                size_t len;
+                const char16_t* str16 = tree.getText(&len);
+                if (str16) {
+                    node->text.assign(str16, len);
+                }
+                newNode = std::move(node);
+                break;
+            }
+
+            case android::ResXMLParser::END_NAMESPACE:
+            case android::ResXMLParser::END_TAG:
+                assert(!nodeStack.empty());
+                nodeStack.pop();
+                break;
+
+            default:
+                assert(false);
+                break;
+        }
+
+        if (newNode) {
+            newNode->lineNumber = tree.getLineNumber();
+
+            Node* thisNode = newNode.get();
+            if (!root) {
+                assert(nodeStack.empty());
+                root = std::move(newNode);
+            } else {
+                assert(!nodeStack.empty());
+                nodeStack.top()->addChild(std::move(newNode));
+            }
+
+            if (thisNode->type != NodeType::kText) {
+                nodeStack.push(thisNode);
+            }
+        }
+    }
+    return std::move(root);
+}
+
+Node::Node(NodeType type) : type(type), parent(nullptr), lineNumber(0), columnNumber(0) {
+}
+
+void Node::addChild(std::unique_ptr<Node> child) {
+    child->parent = this;
+    children.push_back(std::move(child));
+}
+
+Namespace::Namespace() : BaseNode(NodeType::kNamespace) {
+}
+
+std::unique_ptr<Node> Namespace::clone() const {
+    Namespace* ns = new Namespace();
+    ns->lineNumber = lineNumber;
+    ns->columnNumber = columnNumber;
+    ns->comment = comment;
+    ns->namespacePrefix = namespacePrefix;
+    ns->namespaceUri = namespaceUri;
+    for (auto& child : children) {
+        ns->addChild(child->clone());
+    }
+    return std::unique_ptr<Node>(ns);
+}
+
+Element::Element() : BaseNode(NodeType::kElement) {
+}
+
+std::unique_ptr<Node> Element::clone() const {
+    Element* el = new Element();
+    el->lineNumber = lineNumber;
+    el->columnNumber = columnNumber;
+    el->comment = comment;
+    el->namespaceUri = namespaceUri;
+    el->name = name;
+    el->attributes = attributes;
+    for (auto& child : children) {
+        el->addChild(child->clone());
+    }
+    return std::unique_ptr<Node>(el);
+}
+
+Attribute* Element::findAttribute(const StringPiece16& ns, const StringPiece16& name) {
+    for (auto& attr : attributes) {
+        if (ns == attr.namespaceUri && name == attr.name) {
+            return &attr;
+        }
+    }
+    return nullptr;
+}
+
+Element* Element::findChild(const StringPiece16& ns, const StringPiece16& name) {
+    return findChildWithAttribute(ns, name, nullptr);
+}
+
+Element* Element::findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name,
+                                         const Attribute* reqAttr) {
+    for (auto& childNode : children) {
+        Node* child = childNode.get();
+        while (child->type == NodeType::kNamespace) {
+            if (child->children.empty()) {
+                break;
+            }
+            child = child->children[0].get();
+        }
+
+        if (child->type == NodeType::kElement) {
+            Element* el = static_cast<Element*>(child);
+            if (ns == el->namespaceUri && name == el->name) {
+                if (!reqAttr) {
+                    return el;
+                }
+
+                Attribute* attrName = el->findAttribute(reqAttr->namespaceUri, reqAttr->name);
+                if (attrName && attrName->value == reqAttr->value) {
+                    return el;
+                }
+            }
+        }
+    }
+    return nullptr;
+}
+
+std::vector<Element*> Element::getChildElements() {
+    std::vector<Element*> elements;
+    for (auto& childNode : children) {
+        Node* child = childNode.get();
+        while (child->type == NodeType::kNamespace) {
+            if (child->children.empty()) {
+                break;
+            }
+            child = child->children[0].get();
+        }
+
+        if (child->type == NodeType::kElement) {
+            elements.push_back(static_cast<Element*>(child));
+        }
+    }
+    return elements;
+}
+
+Text::Text() : BaseNode(NodeType::kText) {
+}
+
+std::unique_ptr<Node> Text::clone() const {
+    Text* el = new Text();
+    el->lineNumber = lineNumber;
+    el->columnNumber = columnNumber;
+    el->comment = comment;
+    el->text = text;
+    return std::unique_ptr<Node>(el);
+}
+
+} // namespace xml
+} // namespace aapt
diff --git a/tools/aapt2/XmlDom.h b/tools/aapt2/XmlDom.h
new file mode 100644
index 0000000..6931884
--- /dev/null
+++ b/tools/aapt2/XmlDom.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef AAPT_XML_DOM_H
+#define AAPT_XML_DOM_H
+
+#include "Logger.h"
+#include "StringPiece.h"
+
+#include <istream>
+#include <libexpat/expat.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aapt {
+namespace xml {
+
+struct Visitor;
+
+/**
+ * The type of node. Can be used to downcast to the concrete XML node
+ * class.
+ */
+enum class NodeType {
+    kNamespace,
+    kElement,
+    kText,
+};
+
+/**
+ * Base class for all XML nodes.
+ */
+struct Node {
+    NodeType type;
+    Node* parent;
+    size_t lineNumber;
+    size_t columnNumber;
+    std::u16string comment;
+    std::vector<std::unique_ptr<Node>> children;
+
+    Node(NodeType type);
+    void addChild(std::unique_ptr<Node> child);
+    virtual std::unique_ptr<Node> clone() const = 0;
+    virtual void accept(Visitor* visitor) = 0;
+    virtual ~Node() {}
+};
+
+/**
+ * Base class that implements the visitor methods for a
+ * subclass of Node.
+ */
+template <typename Derived>
+struct BaseNode : public Node {
+    BaseNode(NodeType t);
+    virtual void accept(Visitor* visitor) override;
+};
+
+/**
+ * A Namespace XML node. Can only have one child.
+ */
+struct Namespace : public BaseNode<Namespace> {
+    std::u16string namespacePrefix;
+    std::u16string namespaceUri;
+
+    Namespace();
+    virtual std::unique_ptr<Node> clone() const override;
+};
+
+/**
+ * An XML attribute.
+ */
+struct Attribute {
+    std::u16string namespaceUri;
+    std::u16string name;
+    std::u16string value;
+};
+
+/**
+ * An Element XML node.
+ */
+struct Element : public BaseNode<Element> {
+    std::u16string namespaceUri;
+    std::u16string name;
+    std::vector<Attribute> attributes;
+
+    Element();
+    virtual std::unique_ptr<Node> clone() const override;
+    Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name);
+    xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name);
+    xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name,
+                                         const xml::Attribute* reqAttr);
+    std::vector<xml::Element*> getChildElements();
+};
+
+/**
+ * A Text (CDATA) XML node. Can not have any children.
+ */
+struct Text : public BaseNode<Text> {
+    std::u16string text;
+
+    Text();
+    virtual std::unique_ptr<Node> clone() const override;
+};
+
+/**
+ * Inflates an XML DOM from a text stream, logging errors to the logger.
+ * Returns the root node on success, or nullptr on failure.
+ */
+std::unique_ptr<Node> inflate(std::istream* in, SourceLogger* logger);
+
+/**
+ * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger.
+ * Returns the root node on success, or nullptr on failure.
+ */
+std::unique_ptr<Node> inflate(const void* data, size_t dataLen, SourceLogger* logger);
+
+/**
+ * A visitor interface for the different XML Node subtypes.
+ */
+struct Visitor {
+    virtual void visit(Namespace* node) = 0;
+    virtual void visit(Element* node) = 0;
+    virtual void visit(Text* text) = 0;
+};
+
+// Implementations
+
+template <typename Derived>
+BaseNode<Derived>::BaseNode(NodeType type) : Node(type) {
+}
+
+template <typename Derived>
+void BaseNode<Derived>::accept(Visitor* visitor) {
+    visitor->visit(static_cast<Derived*>(this));
+}
+
+} // namespace xml
+} // namespace aapt
+
+#endif // AAPT_XML_DOM_H
diff --git a/tools/aapt2/XmlDom_test.cpp b/tools/aapt2/XmlDom_test.cpp
new file mode 100644
index 0000000..0217144
--- /dev/null
+++ b/tools/aapt2/XmlDom_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include "XmlDom.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+
+TEST(XmlDomTest, Inflate) {
+    std::stringstream in(kXmlPreamble);
+    in << R"EOF(
+        <Layout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+            <TextView android:id="@+id/id"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content" />
+        </Layout>
+    )EOF";
+
+    SourceLogger logger(Source{ "/test/path" });
+    std::unique_ptr<xml::Node> root = xml::inflate(&in, &logger);
+    ASSERT_NE(root, nullptr);
+
+    EXPECT_EQ(root->type, xml::NodeType::kNamespace);
+    xml::Namespace* ns = static_cast<xml::Namespace*>(root.get());
+    EXPECT_EQ(ns->namespaceUri, u"http://schemas.android.com/apk/res/android");
+    EXPECT_EQ(ns->namespacePrefix, u"android");
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XmlFlattener.cpp b/tools/aapt2/XmlFlattener.cpp
index f78e38d..56b5613d 100644
--- a/tools/aapt2/XmlFlattener.cpp
+++ b/tools/aapt2/XmlFlattener.cpp
@@ -34,425 +34,444 @@
 #include <vector>
 
 namespace aapt {
+namespace xml {
 
-constexpr const char16_t* kSchemaAndroid = u"http://schemas.android.com/apk/res/android";
+constexpr uint32_t kLowPriority = 0xffffffffu;
 
-struct AttributeValueFlattener : ValueVisitor {
-    AttributeValueFlattener(
-            std::shared_ptr<IResolver> resolver, SourceLogger* logger,
-            android::Res_value* outValue, std::shared_ptr<XmlPullParser> parser, bool* outError,
-            StringPool::Ref rawValue, std::u16string* defaultPackage,
-            std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>>* outStringRefs) :
-            mResolver(resolver), mLogger(logger), mOutValue(outValue), mParser(parser),
-            mError(outError), mRawValue(rawValue), mDefaultPackage(defaultPackage),
-            mStringRefs(outStringRefs) {
+// A vector that maps String refs to their final destination in the out buffer.
+using FlatStringRefList = std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>>;
+
+struct XmlFlattener : public Visitor {
+    XmlFlattener(BigBuffer* outBuffer, StringPool* pool, FlatStringRefList* stringRefs,
+                 const std::u16string& defaultPackage) :
+            mOut(outBuffer), mPool(pool), mStringRefs(stringRefs),
+            mDefaultPackage(defaultPackage) {
     }
 
-    void visit(Reference& reference, ValueVisitorArgs&) override {
-        // First see if we can convert the package name from a prefix to a real
-        // package name.
-        ResourceName aliasedName = reference.name;
+    // No copying.
+    XmlFlattener(const XmlFlattener&) = delete;
+    XmlFlattener& operator=(const XmlFlattener&) = delete;
 
-        if (!reference.name.package.empty()) {
-            // Only if we specified a package do we look for its alias.
-            mParser->applyPackageAlias(&reference.name.package, *mDefaultPackage);
-        } else {
-            reference.name.package = *mDefaultPackage;
+    void writeNamespace(Namespace* node, uint16_t type) {
+        const size_t startIndex = mOut->size();
+        android::ResXMLTree_node* flatNode = mOut->nextBlock<android::ResXMLTree_node>();
+        android::ResXMLTree_namespaceExt* flatNs =
+                mOut->nextBlock<android::ResXMLTree_namespaceExt>();
+        mOut->align4();
+
+        flatNode->header = { type, sizeof(*flatNode), (uint32_t)(mOut->size() - startIndex) };
+        flatNode->lineNumber = node->lineNumber;
+        flatNode->comment.index = -1;
+        addString(node->namespacePrefix, kLowPriority, &flatNs->prefix);
+        addString(node->namespaceUri, kLowPriority, &flatNs->uri);
+    }
+
+    virtual void visit(Namespace* node) override {
+        // Extract the package/prefix from this namespace node.
+        Maybe<std::u16string> package = util::extractPackageFromNamespace(node->namespaceUri);
+        if (package) {
+            mPackageAliases.emplace_back(
+                    node->namespacePrefix,
+                    package.value().empty() ? mDefaultPackage : package.value());
         }
 
-        Maybe<ResourceId> result = mResolver->findId(reference.name);
-        if (!result || !result.value().isValid()) {
-            std::ostream& out = mLogger->error(mParser->getLineNumber())
-                    << "unresolved reference '"
-                    << aliasedName
-                    << "'";
-            if (aliasedName != reference.name) {
-                out << " (aka '" << reference.name << "')";
+        writeNamespace(node, android::RES_XML_START_NAMESPACE_TYPE);
+        for (const auto& child : node->children) {
+            child->accept(this);
+        }
+        writeNamespace(node, android::RES_XML_END_NAMESPACE_TYPE);
+
+        if (package) {
+            mPackageAliases.pop_back();
+        }
+    }
+
+    virtual void visit(Text* node) override {
+        if (util::trimWhitespace(node->text).empty()) {
+            return;
+        }
+
+        const size_t startIndex = mOut->size();
+        android::ResXMLTree_node* flatNode = mOut->nextBlock<android::ResXMLTree_node>();
+        android::ResXMLTree_cdataExt* flatText = mOut->nextBlock<android::ResXMLTree_cdataExt>();
+        mOut->align4();
+
+        const uint16_t type = android::RES_XML_CDATA_TYPE;
+        flatNode->header = { type, sizeof(*flatNode), (uint32_t)(mOut->size() - startIndex) };
+        flatNode->lineNumber = node->lineNumber;
+        flatNode->comment.index = -1;
+        addString(node->text, kLowPriority, &flatText->data);
+    }
+
+    virtual void visit(Element* node) override {
+        const size_t startIndex = mOut->size();
+        android::ResXMLTree_node* flatNode = mOut->nextBlock<android::ResXMLTree_node>();
+        android::ResXMLTree_attrExt* flatElem = mOut->nextBlock<android::ResXMLTree_attrExt>();
+
+        const uint16_t type = android::RES_XML_START_ELEMENT_TYPE;
+        flatNode->header = { type, sizeof(*flatNode), 0 };
+        flatNode->lineNumber = node->lineNumber;
+        flatNode->comment.index = -1;
+
+        addString(node->namespaceUri, kLowPriority, &flatElem->ns);
+        addString(node->name, kLowPriority, &flatElem->name);
+        flatElem->attributeStart = sizeof(*flatElem);
+        flatElem->attributeSize = sizeof(android::ResXMLTree_attribute);
+        flatElem->attributeCount = node->attributes.size();
+
+        if (!writeAttributes(mOut, node, flatElem)) {
+            mError = true;
+        }
+
+        mOut->align4();
+        flatNode->header.size = (uint32_t)(mOut->size() - startIndex);
+
+        for (const auto& child : node->children) {
+            child->accept(this);
+        }
+
+        const size_t startEndIndex = mOut->size();
+        android::ResXMLTree_node* flatEndNode = mOut->nextBlock<android::ResXMLTree_node>();
+        android::ResXMLTree_endElementExt* flatEndElem =
+                mOut->nextBlock<android::ResXMLTree_endElementExt>();
+        mOut->align4();
+
+        const uint16_t endType = android::RES_XML_END_ELEMENT_TYPE;
+        flatEndNode->header = { endType, sizeof(*flatEndNode),
+                (uint32_t)(mOut->size() - startEndIndex) };
+        flatEndNode->lineNumber = node->lineNumber;
+        flatEndNode->comment.index = -1;
+
+        addString(node->namespaceUri, kLowPriority, &flatEndElem->ns);
+        addString(node->name, kLowPriority, &flatEndElem->name);
+    }
+
+    bool success() const {
+        return !mError;
+    }
+
+protected:
+    void addString(const StringPiece16& str, uint32_t priority, android::ResStringPool_ref* dest) {
+        if (!str.empty()) {
+            mStringRefs->emplace_back(mPool->makeRef(str, StringPool::Context{ priority }), dest);
+        } else {
+            // The device doesn't think a string of size 0 is the same as null.
+            dest->index = -1;
+        }
+    }
+
+    void addString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
+        mStringRefs->emplace_back(ref, dest);
+    }
+
+    Maybe<std::u16string> getPackageAlias(const std::u16string& prefix) {
+        const auto endIter = mPackageAliases.rend();
+        for (auto iter = mPackageAliases.rbegin(); iter != endIter; ++iter) {
+            if (iter->first == prefix) {
+                return iter->second;
             }
-            out << "'." << std::endl;
-            *mError = true;
-        } else {
-            reference.id = result.value();
-            reference.flatten(*mOutValue);
         }
+        return {};
     }
 
-    void visit(String& string, ValueVisitorArgs&) override {
-        mOutValue->dataType = android::Res_value::TYPE_STRING;
-        mStringRefs->emplace_back(
-                mRawValue,
-                reinterpret_cast<android::ResStringPool_ref*>(mOutValue->data));
+    const std::u16string& getDefaultPackage() const {
+        return mDefaultPackage;
     }
 
-    void visitItem(Item& item, ValueVisitorArgs&) override {
-        item.flatten(*mOutValue);
-    }
+    /**
+     * Subclasses override this to deal with attributes. Attributes can be flattened as
+     * raw values or as resources.
+     */
+    virtual bool writeAttributes(BigBuffer* out, Element* node,
+                                 android::ResXMLTree_attrExt* flatElem) = 0;
 
 private:
-    std::shared_ptr<IResolver> mResolver;
-    SourceLogger* mLogger;
-    android::Res_value* mOutValue;
-    std::shared_ptr<XmlPullParser> mParser;
-    bool* mError;
-    StringPool::Ref mRawValue;
-    std::u16string* mDefaultPackage;
-    std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>>* mStringRefs;
+    BigBuffer* mOut;
+    StringPool* mPool;
+    FlatStringRefList* mStringRefs;
+    std::u16string mDefaultPackage;
+    bool mError = false;
+    std::vector<std::pair<std::u16string, std::u16string>> mPackageAliases;
 };
 
-struct XmlAttribute {
-    uint32_t resourceId;
-    const XmlPullParser::Attribute* xmlAttr;
-    const Attribute* attr;
-    StringPool::Ref nameRef;
+/**
+ * Flattens XML, encoding the attributes as raw strings. This is used in the compile phase.
+ */
+struct CompileXmlFlattener : public XmlFlattener {
+    CompileXmlFlattener(BigBuffer* outBuffer, StringPool* pool, FlatStringRefList* stringRefs,
+                        const std::u16string& defaultPackage) :
+            XmlFlattener(outBuffer, pool, stringRefs, defaultPackage) {
+    }
+
+    virtual bool writeAttributes(BigBuffer* out, Element* node,
+                                 android::ResXMLTree_attrExt* flatElem) override {
+        flatElem->attributeCount = node->attributes.size();
+        if (node->attributes.empty()) {
+            return true;
+        }
+
+        android::ResXMLTree_attribute* flatAttrs = out->nextBlock<android::ResXMLTree_attribute>(
+                node->attributes.size());
+        for (const Attribute& attr : node->attributes) {
+            addString(attr.namespaceUri, kLowPriority, &flatAttrs->ns);
+            addString(attr.name, kLowPriority, &flatAttrs->name);
+            addString(attr.value, kLowPriority, &flatAttrs->rawValue);
+            flatAttrs++;
+        }
+        return true;
+    }
 };
 
-static bool lessAttributeId(const XmlAttribute& a, uint32_t id) {
+struct AttributeToFlatten {
+    uint32_t resourceId = 0;
+    const Attribute* xmlAttr = nullptr;
+    const ::aapt::Attribute* resourceAttr = nullptr;
+};
+
+static bool lessAttributeId(const AttributeToFlatten& a, uint32_t id) {
     return a.resourceId < id;
 }
 
-XmlFlattener::XmlFlattener(const std::shared_ptr<ResourceTable>& table,
-                           const std::shared_ptr<IResolver>& resolver) :
-        mTable(table), mResolver(resolver) {
-}
+/**
+ * Flattens XML, encoding the attributes as resources.
+ */
+struct LinkedXmlFlattener : public XmlFlattener {
+    LinkedXmlFlattener(BigBuffer* outBuffer, StringPool* pool,
+                       std::map<std::u16string, StringPool>* packagePools,
+                       FlatStringRefList* stringRefs,
+                       const std::u16string& defaultPackage,
+                       const std::shared_ptr<IResolver>& resolver,
+                       SourceLogger* logger,
+                       const FlattenOptions& options) :
+            XmlFlattener(outBuffer, pool, stringRefs, defaultPackage), mResolver(resolver),
+            mLogger(logger), mPackagePools(packagePools), mOptions(options) {
+    }
+
+    virtual bool writeAttributes(BigBuffer* out, Element* node,
+                                 android::ResXMLTree_attrExt* flatElem) override {
+        bool error = false;
+        std::vector<AttributeToFlatten> sortedAttributes;
+        uint32_t nextAttributeId = 0x80000000u;
+
+        // Sort and filter attributes by their resource ID.
+        for (const Attribute& attr : node->attributes) {
+            AttributeToFlatten attrToFlatten;
+            attrToFlatten.xmlAttr = &attr;
+
+            Maybe<std::u16string> package = util::extractPackageFromNamespace(attr.namespaceUri);
+            if (package) {
+                // Find the Attribute object via our Resolver.
+                ResourceName attrName = { package.value(), ResourceType::kAttr, attr.name };
+                if (attrName.package.empty()) {
+                    attrName.package = getDefaultPackage();
+                }
+
+                Maybe<IResolver::Entry> result = mResolver->findAttribute(attrName);
+                if (!result || !result.value().id.isValid() || !result.value().attr) {
+                    error = true;
+                    mLogger->error(node->lineNumber)
+                            << "unresolved attribute '" << attrName << "'."
+                            << std::endl;
+                } else {
+                    attrToFlatten.resourceId = result.value().id.id;
+                    attrToFlatten.resourceAttr = result.value().attr;
+
+                    size_t sdk = findAttributeSdkLevel(attrToFlatten.resourceId);
+                    if (mOptions.maxSdkAttribute && sdk > mOptions.maxSdkAttribute.value()) {
+                        // We need to filter this attribute out.
+                        mSmallestFilteredSdk = std::min(mSmallestFilteredSdk, sdk);
+                        continue;
+                    }
+                }
+            }
+
+            if (attrToFlatten.resourceId == 0) {
+                // Attributes that have no resource ID (because they don't belong to a
+                // package) should appear after those that do have resource IDs. Assign
+                // them some integer value that will appear after.
+                attrToFlatten.resourceId = nextAttributeId++;
+            }
+
+            // Insert the attribute into the sorted vector.
+            auto iter = std::lower_bound(sortedAttributes.begin(), sortedAttributes.end(),
+                                         attrToFlatten.resourceId, lessAttributeId);
+            sortedAttributes.insert(iter, std::move(attrToFlatten));
+        }
+
+        flatElem->attributeCount = sortedAttributes.size();
+        if (sortedAttributes.empty()) {
+            return true;
+        }
+
+        android::ResXMLTree_attribute* flatAttr = out->nextBlock<android::ResXMLTree_attribute>(
+                sortedAttributes.size());
+
+        // Now that we have sorted the attributes into their final encoded order, it's time
+        // to actually write them out.
+        uint16_t attributeIndex = 1;
+        for (const AttributeToFlatten& attrToFlatten : sortedAttributes) {
+            Maybe<std::u16string> package = util::extractPackageFromNamespace(
+                    attrToFlatten.xmlAttr->namespaceUri);
+
+            // Assign the indices for specific attributes.
+            if (package && package.value() == u"android" && attrToFlatten.xmlAttr->name == u"id") {
+                flatElem->idIndex = attributeIndex;
+            } else if (attrToFlatten.xmlAttr->namespaceUri.empty()) {
+                if (attrToFlatten.xmlAttr->name == u"class") {
+                    flatElem->classIndex = attributeIndex;
+                } else if (attrToFlatten.xmlAttr->name == u"style") {
+                    flatElem->styleIndex = attributeIndex;
+                }
+            }
+            attributeIndex++;
+
+            // Add the namespaceUri and name to the list of StringRefs to encode.
+            addString(attrToFlatten.xmlAttr->namespaceUri, kLowPriority, &flatAttr->ns);
+            flatAttr->rawValue.index = -1;
+
+            if (!attrToFlatten.resourceAttr) {
+                addString(attrToFlatten.xmlAttr->name, kLowPriority, &flatAttr->name);
+            } else {
+                // We've already extracted the package successfully before.
+                assert(package);
+
+                // Attribute names are stored without packages, but we use
+                // their StringPool index to lookup their resource IDs.
+                // This will cause collisions, so we can't dedupe
+                // attribute names from different packages. We use separate
+                // pools that we later combine.
+                //
+                // Lookup the StringPool for this package and make the reference there.
+                StringPool::Ref nameRef = (*mPackagePools)[package.value()].makeRef(
+                        attrToFlatten.xmlAttr->name,
+                        StringPool::Context{ attrToFlatten.resourceId });
+
+                // Add it to the list of strings to flatten.
+                addString(nameRef, &flatAttr->name);
+
+                if (mOptions.keepRawValues) {
+                    // Keep raw values (this is for static libraries).
+                    // TODO(with a smarter inflater for binary XML, we can do without this).
+                    addString(attrToFlatten.xmlAttr->value, kLowPriority, &flatAttr->rawValue);
+                }
+            }
+
+            error |= !flattenItem(node, attrToFlatten.xmlAttr->value, attrToFlatten.resourceAttr,
+                                  flatAttr);
+            flatAttr->typedValue.size = sizeof(flatAttr->typedValue);
+            flatAttr++;
+        }
+        return !error;
+    }
+
+    Maybe<size_t> getSmallestFilteredSdk() const {
+        if (mSmallestFilteredSdk == std::numeric_limits<size_t>::max()) {
+            return {};
+        }
+        return mSmallestFilteredSdk;
+    }
+
+private:
+    bool flattenItem(const Node* el, const std::u16string& value, const ::aapt::Attribute* attr,
+                     android::ResXMLTree_attribute* flatAttr) {
+        std::unique_ptr<Item> item;
+        if (!attr) {
+            bool create = false;
+            item = ResourceParser::tryParseReference(value, &create);
+            if (!item) {
+                flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING;
+                addString(value, kLowPriority, &flatAttr->rawValue);
+                addString(value, kLowPriority, reinterpret_cast<android::ResStringPool_ref*>(
+                        &flatAttr->typedValue.data));
+                return true;
+            }
+        } else {
+            item = ResourceParser::parseItemForAttribute(value, *attr);
+            if (!item) {
+                if (!(attr->typeMask & android::ResTable_map::TYPE_STRING)) {
+                    mLogger->error(el->lineNumber)
+                            << "'"
+                            << value
+                            << "' is not compatible with attribute '"
+                            << *attr
+                            << "'."
+                            << std::endl;
+                    return false;
+                }
+
+                flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING;
+                addString(value, kLowPriority, &flatAttr->rawValue);
+                addString(value, kLowPriority, reinterpret_cast<android::ResStringPool_ref*>(
+                        &flatAttr->typedValue.data));
+                return true;
+            }
+        }
+
+        assert(item);
+
+        bool error = false;
+
+        // If this is a reference, resolve the name into an ID.
+        visitFunc<Reference>(*item, [&](Reference& reference) {
+            // First see if we can convert the package name from a prefix to a real
+            // package name.
+            ResourceName realName = reference.name;
+            if (!realName.package.empty()) {
+                Maybe<std::u16string> package = getPackageAlias(realName.package);
+                if (package) {
+                    realName.package = package.value();
+                }
+            } else {
+                realName.package = getDefaultPackage();
+            }
+
+            Maybe<ResourceId> result = mResolver->findId(realName);
+            if (!result || !result.value().isValid()) {
+                std::ostream& out = mLogger->error(el->lineNumber)
+                        << "unresolved reference '"
+                        << reference.name
+                        << "'";
+                if (realName != reference.name) {
+                    out << " (aka '" << realName << "')";
+                }
+                out << "'." << std::endl;
+                error = true;
+            } else {
+                reference.id = result.value();
+            }
+        });
+
+        if (error) {
+            return false;
+        }
+
+        item->flatten(flatAttr->typedValue);
+        return true;
+    }
+
+    std::shared_ptr<IResolver> mResolver;
+    SourceLogger* mLogger;
+    std::map<std::u16string, StringPool>* mPackagePools;
+    FlattenOptions mOptions;
+    size_t mSmallestFilteredSdk = std::numeric_limits<size_t>::max();
+};
 
 /**
- * Reads events from the parser and writes to a BigBuffer. The binary XML file
- * expects the StringPool to appear first, but we haven't collected the strings yet. We
- * write to a temporary BigBuffer while parsing the input, adding strings we encounter
- * to the StringPool. At the end, we write the StringPool to the given BigBuffer and
+ * The binary XML file expects the StringPool to appear first, but we haven't collected the
+ * strings yet. We write to a temporary BigBuffer while parsing the input, adding strings
+ * we encounter to the StringPool. At the end, we write the StringPool to the given BigBuffer and
  * then move the data from the temporary BigBuffer into the given one. This incurs no
  * copies as the given BigBuffer simply takes ownership of the data.
  */
-Maybe<size_t> XmlFlattener::flatten(const Source& source,
-                                    const std::shared_ptr<XmlPullParser>& parser,
-                                    BigBuffer* outBuffer, Options options) {
-    SourceLogger logger(source);
-    StringPool pool;
-    bool error = false;
-
-    size_t smallestStrippedAttributeSdk = std::numeric_limits<size_t>::max();
-
-    // Attribute names are stored without packages, but we use
-    // their StringPool index to lookup their resource IDs.
-    // This will cause collisions, so we can't dedupe
-    // attribute names from different packages. We use separate
-    // pools that we later combine.
-    std::map<std::u16string, StringPool> packagePools;
-
-    // Attribute resource IDs are stored in the same order
-    // as the attribute names appear in the StringPool.
-    // Since the StringPool contains more than just attribute
-    // names, to maintain a tight packing of resource IDs,
-    // we must ensure that attribute names appear first
-    // in our StringPool. For this, we assign a low priority
-    // (0xffffffff) to non-attribute strings. Attribute
-    // names will be stored along with a priority equal
-    // to their resource ID so that they are ordered.
-    StringPool::Context lowPriority { 0xffffffffu };
-
-    // Once we sort the StringPool, we can assign the updated indices
-    // to the correct data locations.
-    std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>> stringRefs;
-
-    // Since we don't know the size of the final StringPool, we write to this
-    // temporary BigBuffer, which we will append to outBuffer later.
-    BigBuffer out(1024);
-    while (XmlPullParser::isGoodEvent(parser->next())) {
-        XmlPullParser::Event event = parser->getEvent();
-        switch (event) {
-            case XmlPullParser::Event::kStartNamespace:
-            case XmlPullParser::Event::kEndNamespace: {
-                const size_t startIndex = out.size();
-                android::ResXMLTree_node* node = out.nextBlock<android::ResXMLTree_node>();
-                if (event == XmlPullParser::Event::kStartNamespace) {
-                    node->header.type = android::RES_XML_START_NAMESPACE_TYPE;
-                } else {
-                    node->header.type = android::RES_XML_END_NAMESPACE_TYPE;
-                }
-
-                node->header.headerSize = sizeof(*node);
-                node->lineNumber = parser->getLineNumber();
-                node->comment.index = -1;
-
-                android::ResXMLTree_namespaceExt* ns =
-                        out.nextBlock<android::ResXMLTree_namespaceExt>();
-                stringRefs.emplace_back(
-                        pool.makeRef(parser->getNamespacePrefix(), lowPriority), &ns->prefix);
-                stringRefs.emplace_back(
-                        pool.makeRef(parser->getNamespaceUri(), lowPriority), &ns->uri);
-
-                out.align4();
-                node->header.size = out.size() - startIndex;
-                break;
-            }
-
-            case XmlPullParser::Event::kStartElement: {
-                const size_t startIndex = out.size();
-                android::ResXMLTree_node* node = out.nextBlock<android::ResXMLTree_node>();
-                node->header.type = android::RES_XML_START_ELEMENT_TYPE;
-                node->header.headerSize = sizeof(*node);
-                node->lineNumber = parser->getLineNumber();
-                node->comment.index = -1;
-
-                android::ResXMLTree_attrExt* elem = out.nextBlock<android::ResXMLTree_attrExt>();
-                if (!parser->getElementNamespace().empty()) {
-                    stringRefs.emplace_back(
-                            pool.makeRef(parser->getElementNamespace(), lowPriority), &elem->ns);
-                } else {
-                    // The device doesn't think a string of size 0 is the same as null.
-                    elem->ns.index = -1;
-                }
-                stringRefs.emplace_back(
-                        pool.makeRef(parser->getElementName(), lowPriority), &elem->name);
-                elem->attributeStart = sizeof(*elem);
-                elem->attributeSize = sizeof(android::ResXMLTree_attribute);
-
-                // The resource system expects attributes to be sorted by resource ID.
-                std::vector<XmlAttribute> sortedAttributes;
-                uint32_t nextAttributeId = 0;
-                const auto endAttrIter = parser->endAttributes();
-                for (auto attrIter = parser->beginAttributes();
-                        attrIter != endAttrIter;
-                        ++attrIter) {
-                    uint32_t id;
-                    StringPool::Ref nameRef;
-                    const Attribute* attr = nullptr;
-
-                    if (options.maxSdkAttribute && attrIter->namespaceUri == kSchemaAndroid) {
-                        size_t sdkVersion = findAttributeSdkLevel(attrIter->name);
-                        if (sdkVersion > options.maxSdkAttribute.value()) {
-                            // We will silently omit this attribute
-                            smallestStrippedAttributeSdk =
-                                    std::min(smallestStrippedAttributeSdk, sdkVersion);
-                            continue;
-                        }
-                    }
-
-                    ResourceNameRef genIdName;
-                    bool create = false;
-                    bool privateRef = false;
-                    if (mTable && ResourceParser::tryParseReference(attrIter->value, &genIdName,
-                            &create, &privateRef) && create) {
-                        mTable->addResource(genIdName, {}, source.line(parser->getLineNumber()),
-                                            util::make_unique<Id>());
-                    }
-
-
-                    Maybe<std::u16string> package = util::extractPackageFromNamespace(
-                            attrIter->namespaceUri);
-                    if (!package || !mResolver) {
-                        // Attributes that have no resource ID (because they don't belong to a
-                        // package) should appear after those that do have resource IDs. Assign
-                        // them some integer value that will appear after.
-                        id = 0x80000000u | nextAttributeId++;
-                        nameRef = pool.makeRef(attrIter->name, StringPool::Context{ id });
-
-                    } else {
-                        // Find the Attribute object via our Resolver.
-                        ResourceName attrName = {
-                                package.value(), ResourceType::kAttr, attrIter->name };
-
-                        if (attrName.package.empty()) {
-                            attrName.package = options.defaultPackage;
-                        }
-
-                        Maybe<IResolver::Entry> result = mResolver->findAttribute(attrName);
-                        if (!result || !result.value().id.isValid()) {
-                            logger.error(parser->getLineNumber())
-                                    << "unresolved attribute '"
-                                    << attrName
-                                    << "'."
-                                    << std::endl;
-                            error = true;
-                            continue;
-                        }
-
-                        if (!result.value().attr) {
-                            logger.error(parser->getLineNumber())
-                                    << "not a valid attribute '"
-                                    << attrName
-                                    << "'."
-                                    << std::endl;
-                            error = true;
-                            continue;
-                        }
-
-                        id = result.value().id.id;
-                        attr = result.value().attr;
-
-                        // Put the attribute name into a package specific pool, since we don't
-                        // want to collapse names from different packages.
-                        nameRef = packagePools[package.value()].makeRef(
-                                attrIter->name, StringPool::Context{ id });
-                    }
-
-                    // Insert the attribute into the sorted vector.
-                    auto iter = std::lower_bound(sortedAttributes.begin(), sortedAttributes.end(),
-                                                 id, lessAttributeId);
-                    sortedAttributes.insert(iter, XmlAttribute{ id, &*attrIter, attr, nameRef });
-                }
-
-                if (error) {
-                    break;
-                }
-
-                // Now that we have filtered out some attributes, get the final count.
-                elem->attributeCount = sortedAttributes.size();
-
-                // Flatten the sorted attributes.
-                uint16_t attributeIndex = 1;
-                for (auto entry : sortedAttributes) {
-                    android::ResXMLTree_attribute* attr =
-                            out.nextBlock<android::ResXMLTree_attribute>();
-                    if (!entry.xmlAttr->namespaceUri.empty()) {
-                        stringRefs.emplace_back(
-                                pool.makeRef(entry.xmlAttr->namespaceUri, lowPriority), &attr->ns);
-                    } else {
-                        attr->ns.index = -1;
-                    }
-
-                    StringPool::Ref rawValueRef = pool.makeRef(entry.xmlAttr->value, lowPriority);
-
-                    stringRefs.emplace_back(entry.nameRef, &attr->name);
-
-                    if (options.keepRawValues) {
-                        stringRefs.emplace_back(rawValueRef, &attr->rawValue);
-                    } else {
-                        attr->rawValue.index = -1;
-                    }
-
-                    // Assign the indices for specific attributes.
-                    if (entry.xmlAttr->namespaceUri == kSchemaAndroid &&
-                            entry.xmlAttr->name == u"id") {
-                        elem->idIndex = attributeIndex;
-                    } else if (entry.xmlAttr->namespaceUri.empty()) {
-                        if (entry.xmlAttr->name == u"class") {
-                            elem->classIndex = attributeIndex;
-                        } else if (entry.xmlAttr->name == u"style") {
-                            elem->styleIndex = attributeIndex;
-                        }
-                    }
-                    attributeIndex++;
-
-                    std::unique_ptr<Item> value;
-                    if (entry.attr) {
-                        value = ResourceParser::parseItemForAttribute(entry.xmlAttr->value,
-                                                                      *entry.attr);
-                    } else {
-                        bool create = false;
-                        value = ResourceParser::tryParseReference(entry.xmlAttr->value, &create);
-                    }
-
-                    if (mResolver && value) {
-                        AttributeValueFlattener flattener(
-                                mResolver,
-                                &logger,
-                                &attr->typedValue,
-                                parser,
-                                &error,
-                                rawValueRef,
-                                &options.defaultPackage,
-                                &stringRefs);
-                        value->accept(flattener, {});
-                    } else if (!value && entry.attr &&
-                            !(entry.attr->typeMask & android::ResTable_map::TYPE_STRING)) {
-                        logger.error(parser->getLineNumber())
-                                << "'"
-                                << *rawValueRef
-                                << "' is not compatible with attribute "
-                                << *entry.attr
-                                << "."
-                                << std::endl;
-                        error = true;
-                    } else {
-                        attr->typedValue.dataType = android::Res_value::TYPE_STRING;
-                        if (!options.keepRawValues) {
-                            // Don't set the string twice.
-                            stringRefs.emplace_back(rawValueRef, &attr->rawValue);
-                        }
-                        stringRefs.emplace_back(rawValueRef,
-                                reinterpret_cast<android::ResStringPool_ref*>(
-                                        &attr->typedValue.data));
-                    }
-                    attr->typedValue.size = sizeof(attr->typedValue);
-                }
-
-                out.align4();
-                node->header.size = out.size() - startIndex;
-                break;
-            }
-
-            case XmlPullParser::Event::kEndElement: {
-                const size_t startIndex = out.size();
-                android::ResXMLTree_node* node = out.nextBlock<android::ResXMLTree_node>();
-                node->header.type = android::RES_XML_END_ELEMENT_TYPE;
-                node->header.headerSize = sizeof(*node);
-                node->lineNumber = parser->getLineNumber();
-                node->comment.index = -1;
-
-                android::ResXMLTree_endElementExt* elem =
-                        out.nextBlock<android::ResXMLTree_endElementExt>();
-                stringRefs.emplace_back(
-                        pool.makeRef(parser->getElementNamespace(), lowPriority), &elem->ns);
-                stringRefs.emplace_back(
-                        pool.makeRef(parser->getElementName(), lowPriority), &elem->name);
-
-                out.align4();
-                node->header.size = out.size() - startIndex;
-                break;
-            }
-
-            case XmlPullParser::Event::kText: {
-                StringPiece16 text = util::trimWhitespace(parser->getText());
-                if (text.empty()) {
-                    break;
-                }
-
-                const size_t startIndex = out.size();
-                android::ResXMLTree_node* node = out.nextBlock<android::ResXMLTree_node>();
-                node->header.type = android::RES_XML_CDATA_TYPE;
-                node->header.headerSize = sizeof(*node);
-                node->lineNumber = parser->getLineNumber();
-                node->comment.index = -1;
-
-                android::ResXMLTree_cdataExt* elem = out.nextBlock<android::ResXMLTree_cdataExt>();
-                stringRefs.emplace_back(pool.makeRef(text, lowPriority), &elem->data);
-
-                out.align4();
-                node->header.size = out.size() - startIndex;
-                break;
-            }
-
-            default:
-                break;
-        }
-
-    }
-    out.align4();
-
-    if (error) {
-        return {};
-    }
-
-    if (parser->getEvent() == XmlPullParser::Event::kBadDocument) {
-        logger.error(parser->getLineNumber())
-                << parser->getLastError()
-                << std::endl;
-        return {};
-    }
-
-    // Merge the package pools into the main pool.
-    for (auto& packagePoolEntry : packagePools) {
-        pool.merge(std::move(packagePoolEntry.second));
-    }
-
-    // Sort so that attribute resource IDs show up first.
-    pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+static void flattenXml(StringPool* pool, FlatStringRefList* stringRefs, BigBuffer* outBuffer,
+                       BigBuffer&& xmlTreeBuffer) {
+    // Sort the string pool so that attribute resource IDs show up first.
+    pool->sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
         return a.context.priority < b.context.priority;
     });
 
     // Now we flatten the string pool references into the correct places.
-    for (const auto& refEntry : stringRefs) {
+    for (const auto& refEntry : *stringRefs) {
         refEntry.second->index = refEntry.first.getIndex();
     }
 
@@ -463,36 +482,93 @@
     header->header.headerSize = sizeof(*header);
 
     // Flatten the StringPool.
-    StringPool::flattenUtf16(outBuffer, pool);
+    StringPool::flattenUtf16(outBuffer, *pool);
 
     // Write the array of resource IDs, indexed by StringPool order.
     const size_t beforeResIdMapIndex = outBuffer->size();
     android::ResChunk_header* resIdMapChunk = outBuffer->nextBlock<android::ResChunk_header>();
     resIdMapChunk->type = android::RES_XML_RESOURCE_MAP_TYPE;
     resIdMapChunk->headerSize = sizeof(*resIdMapChunk);
-    for (const auto& str : pool) {
+    for (const auto& str : *pool) {
         ResourceId id { str->context.priority };
-        if (!id.isValid()) {
+        if (id.id == kLowPriority || !id.isValid()) {
             // When we see the first non-resource ID,
             // we're done.
             break;
         }
 
-        uint32_t* flatId = outBuffer->nextBlock<uint32_t>();
-        *flatId = id.id;
+        *outBuffer->nextBlock<uint32_t>() = id.id;
     }
     resIdMapChunk->size = outBuffer->size() - beforeResIdMapIndex;
 
     // Move the temporary BigBuffer into outBuffer.
-    outBuffer->appendBuffer(std::move(out));
-
+    outBuffer->appendBuffer(std::move(xmlTreeBuffer));
     header->header.size = outBuffer->size() - beforeXmlTreeIndex;
-
-    if (smallestStrippedAttributeSdk == std::numeric_limits<size_t>::max()) {
-        // Nothing was stripped
-        return 0u;
-    }
-    return smallestStrippedAttributeSdk;
 }
 
+bool flatten(Node* root, const std::u16string& defaultPackage, BigBuffer* outBuffer) {
+    StringPool pool;
+
+    // This will hold the StringRefs and the location in which to write the index.
+    // Once we sort the StringPool, we can assign the updated indices
+    // to the correct data locations.
+    FlatStringRefList stringRefs;
+
+    // Since we don't know the size of the final StringPool, we write to this
+    // temporary BigBuffer, which we will append to outBuffer later.
+    BigBuffer out(1024);
+
+    CompileXmlFlattener flattener(&out, &pool, &stringRefs, defaultPackage);
+    root->accept(&flattener);
+
+    if (!flattener.success()) {
+        return false;
+    }
+
+    flattenXml(&pool, &stringRefs, outBuffer, std::move(out));
+    return true;
+};
+
+Maybe<size_t> flattenAndLink(const Source& source, Node* root,
+                             const std::u16string& defaultPackage,
+                             const std::shared_ptr<IResolver>& resolver,
+                             const FlattenOptions& options, BigBuffer* outBuffer) {
+    SourceLogger logger(source);
+    StringPool pool;
+
+    // Attribute names are stored without packages, but we use
+    // their StringPool index to lookup their resource IDs.
+    // This will cause collisions, so we can't dedupe
+    // attribute names from different packages. We use separate
+    // pools that we later combine.
+    std::map<std::u16string, StringPool> packagePools;
+
+    FlatStringRefList stringRefs;
+
+    // Since we don't know the size of the final StringPool, we write to this
+    // temporary BigBuffer, which we will append to outBuffer later.
+    BigBuffer out(1024);
+
+    LinkedXmlFlattener flattener(&out, &pool, &packagePools, &stringRefs, defaultPackage, resolver,
+                                 &logger, options);
+    root->accept(&flattener);
+
+    if (!flattener.success()) {
+        return {};
+    }
+
+    // Merge the package pools into the main pool.
+    for (auto& packagePoolEntry : packagePools) {
+        pool.merge(std::move(packagePoolEntry.second));
+    }
+
+    flattenXml(&pool, &stringRefs, outBuffer, std::move(out));
+
+    if (flattener.getSmallestFilteredSdk()) {
+        return flattener.getSmallestFilteredSdk();
+    }
+    return 0;
+}
+
+} // namespace xml
 } // namespace aapt
diff --git a/tools/aapt2/XmlFlattener.h b/tools/aapt2/XmlFlattener.h
index 2cfcc16..4ece0a3 100644
--- a/tools/aapt2/XmlFlattener.h
+++ b/tools/aapt2/XmlFlattener.h
@@ -21,64 +21,49 @@
 #include "Maybe.h"
 #include "Resolver.h"
 #include "Source.h"
-#include "XmlPullParser.h"
+#include "XmlDom.h"
 
 #include <string>
 
 namespace aapt {
+namespace xml {
 
 /**
  * Flattens an XML file into a binary representation parseable by
- * the Android resource system. References to resources are checked
- * and string values are transformed to typed data where possible.
+ * the Android resource system.
  */
-class XmlFlattener {
-public:
-    struct Options {
-        /**
-         * The package to use when a reference has no package specified
-         * (or a namespace URI equals "http://schemas.android.com/apk/res-auto").
-         */
-        std::u16string defaultPackage;
+bool flatten(Node* root, const std::u16string& defaultPackage, BigBuffer* outBuffer);
 
-        /**
-         * If set, tells the XmlFlattener to strip out
-         * attributes that have been introduced after
-         * max SDK.
-         */
-        Maybe<size_t> maxSdkAttribute;
-
-        /**
-         * Setting this to true will keep the raw string value of
-         * an attribute's value when it has been resolved.
-         */
-        bool keepRawValues = false;
-    };
+/**
+ * Options for flattenAndLink.
+ */
+struct FlattenOptions {
+    /**
+     * Keep attribute raw string values along with typed values.
+     */
+    bool keepRawValues = false;
 
     /**
-     * Creates a flattener with a Resolver to resolve references
-     * and attributes.
+     * If set, any attribute introduced in a later SDK will not be encoded.
      */
-    XmlFlattener(const std::shared_ptr<ResourceTable>& table,
-                 const std::shared_ptr<IResolver>& resolver);
-
-    XmlFlattener(const XmlFlattener&) = delete; // Not copyable.
-
-    /**
-     * Flatten an XML file, reading from the XML parser and writing to the
-     * BigBuffer. The source object is mainly for logging errors. If the
-     * function succeeds, returns the smallest SDK version of an attribute that
-     * was stripped out. If no attributes were stripped out, the return value
-     * is 0.
-     */
-    Maybe<size_t> flatten(const Source& source, const std::shared_ptr<XmlPullParser>& parser,
-                          BigBuffer* outBuffer, Options options);
-
-private:
-    std::shared_ptr<ResourceTable> mTable;
-    std::shared_ptr<IResolver> mResolver;
+    Maybe<size_t> maxSdkAttribute;
 };
 
+/**
+ * Like flatten(Node*,BigBuffer*), but references to resources are checked
+ * and string values are transformed to typed data where possible.
+ *
+ * `defaultPackage` is used when a reference has no package or the namespace URI
+ * "http://schemas.android.com/apk/res-auto" is used.
+ *
+ * `resolver` is used to resolve references to resources.
+ */
+Maybe<size_t> flattenAndLink(const Source& source, Node* root,
+                             const std::u16string& defaultPackage,
+                             const std::shared_ptr<IResolver>& resolver,
+                             const FlattenOptions& options, BigBuffer* outBuffer);
+
+} // namespace xml
 } // namespace aapt
 
 #endif // AAPT_XML_FLATTENER_H
diff --git a/tools/aapt2/XmlFlattener_test.cpp b/tools/aapt2/XmlFlattener_test.cpp
index b45cd9b..8915d24 100644
--- a/tools/aapt2/XmlFlattener_test.cpp
+++ b/tools/aapt2/XmlFlattener_test.cpp
@@ -17,7 +17,6 @@
 #include "MockResolver.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
-#include "SourceXmlPullParser.h"
 #include "Util.h"
 #include "XmlFlattener.h"
 
@@ -30,13 +29,14 @@
 using namespace android;
 
 namespace aapt {
+namespace xml {
 
 constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
 class XmlFlattenerTest : public ::testing::Test {
 public:
     virtual void SetUp() override {
-        std::shared_ptr<IResolver> resolver = std::make_shared<MockResolver>(
+        mResolver = std::make_shared<MockResolver>(
                 std::make_shared<ResourceTable>(),
                 std::map<ResourceName, ResourceId>({
                         { ResourceName{ u"android", ResourceType::kAttr, u"attr" },
@@ -47,18 +47,21 @@
                           ResourceId{ 0x01010001u } },
                         { ResourceName{ u"com.lib", ResourceType::kId, u"id" },
                           ResourceId{ 0x01020001u } }}));
-
-        mFlattener = std::make_shared<XmlFlattener>(nullptr, resolver);
     }
 
     ::testing::AssertionResult testFlatten(const std::string& in, ResXMLTree* outTree) {
         std::stringstream input(kXmlPreamble);
         input << in << std::endl;
-        std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(input);
+
+        SourceLogger logger(Source{ "test.xml" });
+        std::unique_ptr<Node> root = inflate(&input, &logger);
+        if (!root) {
+            return ::testing::AssertionFailure();
+        }
+
         BigBuffer outBuffer(1024);
-        XmlFlattener::Options xmlOptions;
-        xmlOptions.defaultPackage = u"android";
-        if (!mFlattener->flatten(Source{ "test" }, xmlParser, &outBuffer, xmlOptions)) {
+        if (!flattenAndLink(Source{ "test.xml" }, root.get(), std::u16string(u"android"),
+                    mResolver, {}, &outBuffer)) {
             return ::testing::AssertionFailure();
         }
 
@@ -69,16 +72,48 @@
         return ::testing::AssertionSuccess();
     }
 
-    std::shared_ptr<XmlFlattener> mFlattener;
+    std::shared_ptr<IResolver> mResolver;
 };
 
 TEST_F(XmlFlattenerTest, ParseSimpleView) {
-    std::string input = "<View xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
-                        "      android:attr=\"@id/id\">\n"
-                        "</View>";
+    std::string input = R"EOF(
+        <View xmlns:android="http://schemas.android.com/apk/res/android"
+              android:attr="@id/id"
+              class="str"
+              style="@id/id">
+        </View>
+    )EOF";
     ResXMLTree tree;
     ASSERT_TRUE(testFlatten(input, &tree));
 
+    while (tree.next() != ResXMLTree::START_TAG) {
+        ASSERT_NE(tree.getEventType(), ResXMLTree::END_DOCUMENT);
+        ASSERT_NE(tree.getEventType(), ResXMLTree::BAD_DOCUMENT);
+    }
+
+    const StringPiece16 androidNs = u"http://schemas.android.com/apk/res/android";
+    const StringPiece16 attrName = u"attr";
+    ssize_t idx = tree.indexOfAttribute(androidNs.data(), androidNs.size(), attrName.data(),
+                                        attrName.size());
+    ASSERT_GE(idx, 0);
+    EXPECT_EQ(tree.getAttributeNameResID(idx), 0x01010000u);
+    EXPECT_EQ(tree.getAttributeDataType(idx), android::Res_value::TYPE_REFERENCE);
+
+    const StringPiece16 class16 = u"class";
+    idx = tree.indexOfAttribute(nullptr, 0, class16.data(), class16.size());
+    ASSERT_GE(idx, 0);
+    EXPECT_EQ(tree.getAttributeNameResID(idx), 0u);
+    EXPECT_EQ(tree.getAttributeDataType(idx), android::Res_value::TYPE_STRING);
+    EXPECT_EQ(tree.getAttributeData(idx), tree.getAttributeValueStringID(idx));
+
+    const StringPiece16 style16 = u"style";
+    idx = tree.indexOfAttribute(nullptr, 0, style16.data(), style16.size());
+    ASSERT_GE(idx, 0);
+    EXPECT_EQ(tree.getAttributeNameResID(idx), 0u);
+    EXPECT_EQ(tree.getAttributeDataType(idx), android::Res_value::TYPE_REFERENCE);
+    EXPECT_EQ((uint32_t) tree.getAttributeData(idx), 0x01020000u);
+    EXPECT_EQ(tree.getAttributeValueStringID(idx), -1);
+
     while (tree.next() != ResXMLTree::END_DOCUMENT) {
         ASSERT_NE(tree.getEventType(), ResXMLTree::BAD_DOCUMENT);
     }
@@ -193,4 +228,5 @@
     EXPECT_GE(tree.indexOfAttribute(nullptr, 0, kPackage.data(), kPackage.size()), 0);
 }
 
+} // namespace xml
 } // namespace aapt
