diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 65160d5..a5776a4 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1333,7 +1333,11 @@
         FLAG_COMPLEX = 0x0001,
         // If set, this resource has been declared public, so libraries
         // are allowed to reference it.
-        FLAG_PUBLIC = 0x0002
+        FLAG_PUBLIC = 0x0002,
+        // If set, this is a weak resource and may be overriden by strong
+        // resources of the same name/type. This is only useful during
+        // linking with other resource tables.
+        FLAG_WEAK = 0x0004
     };
     uint16_t flags;
     
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
new file mode 100644
index 0000000..e61fd29
--- /dev/null
+++ b/tools/aapt2/Android.mk
@@ -0,0 +1,133 @@
+#
+# 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.
+#
+
+# This tool is prebuilt if we're doing an app-only build.
+ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
+
+# ==========================================================
+# Setup some common variables for the different build
+# targets here.
+# ==========================================================
+LOCAL_PATH:= $(call my-dir)
+
+main := Main.cpp
+sources := \
+	BigBuffer.cpp \
+	BinaryResourceParser.cpp \
+	ConfigDescription.cpp \
+	Files.cpp \
+	JavaClassGenerator.cpp \
+	Linker.cpp \
+	Locale.cpp \
+	Logger.cpp \
+	ManifestParser.cpp \
+	ManifestValidator.cpp \
+	ResChunkPullParser.cpp \
+	Resolver.cpp \
+	Resource.cpp \
+	ResourceParser.cpp \
+	ResourceTable.cpp \
+	ResourceValues.cpp \
+	SdkConstants.cpp \
+	StringPool.cpp \
+	TableFlattener.cpp \
+	Util.cpp \
+	ScopedXmlPullParser.cpp \
+	SourceXmlPullParser.cpp \
+	XliffXmlPullParser.cpp \
+	XmlFlattener.cpp
+
+testSources := \
+	BigBuffer_test.cpp \
+	Compat_test.cpp \
+	ConfigDescription_test.cpp \
+	JavaClassGenerator_test.cpp \
+	Linker_test.cpp \
+	Locale_test.cpp \
+	ManifestParser_test.cpp \
+	Maybe_test.cpp \
+	ResourceParser_test.cpp \
+	Resource_test.cpp \
+	ResourceTable_test.cpp \
+	ScopedXmlPullParser_test.cpp \
+	StringPiece_test.cpp \
+	StringPool_test.cpp \
+	Util_test.cpp \
+	XliffXmlPullParser_test.cpp \
+	XmlFlattener_test.cpp
+
+cIncludes :=
+
+hostLdLibs := -lz
+hostStaticLibs := \
+	libandroidfw \
+	libutils \
+	liblog \
+	libcutils \
+	libexpat \
+	libziparchive-host
+
+cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
+cppFlags := -std=c++11 -Wno-missing-field-initializers
+
+# ==========================================================
+# Build the host static library: libaapt2
+# ==========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libaapt2
+
+LOCAL_SRC_FILES := $(sources)
+LOCAL_C_INCLUDES += $(cIncludes)
+LOCAL_CFLAGS += $(cFlags)
+LOCAL_CPPFLAGS += $(cppFlags)
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# ==========================================================
+# Build the host tests: libaapt2_tests
+# ==========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libaapt2_tests
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(testSources)
+
+LOCAL_C_INCLUDES += $(cIncludes)
+LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
+LOCAL_LDLIBS += $(hostLdLibs)
+LOCAL_CFLAGS += $(cFlags)
+LOCAL_CPPFLAGS += $(cppFlags)
+
+include $(BUILD_HOST_NATIVE_TEST)
+
+# ==========================================================
+# Build the host executable: aapt2
+# ==========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := aapt2
+
+LOCAL_SRC_FILES := $(main)
+
+LOCAL_C_INCLUDES += $(cIncludes)
+LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
+LOCAL_LDLIBS += $(hostLdLibs)
+LOCAL_CFLAGS += $(cFlags)
+LOCAL_CPPFLAGS += $(cppFlags)
+
+include $(BUILD_HOST_EXECUTABLE)
+
+endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK
diff --git a/tools/aapt2/AppInfo.h b/tools/aapt2/AppInfo.h
new file mode 100644
index 0000000..30047f7
--- /dev/null
+++ b/tools/aapt2/AppInfo.h
@@ -0,0 +1,37 @@
+/*
+ * 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_APP_INFO_H
+#define AAPT_APP_INFO_H
+
+#include <string>
+
+namespace aapt {
+
+/**
+ * Holds basic information about the app being built. Most of this information
+ * will come from the app's AndroidManifest.
+ */
+struct AppInfo {
+    /**
+     * App's package name.
+     */
+    std::u16string package;
+};
+
+} // namespace aapt
+
+#endif // AAPT_APP_INFO_H
diff --git a/tools/aapt2/BigBuffer.cpp b/tools/aapt2/BigBuffer.cpp
new file mode 100644
index 0000000..8f57172
--- /dev/null
+++ b/tools/aapt2/BigBuffer.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "BigBuffer.h"
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+namespace aapt {
+
+void* BigBuffer::nextBlockImpl(size_t size) {
+    if (!mBlocks.empty()) {
+        Block& block = mBlocks.back();
+        if (block.mBlockSize - block.size >= size) {
+            void* outBuffer = block.buffer.get() + block.size;
+            block.size += size;
+            mSize += size;
+            return outBuffer;
+        }
+    }
+
+    const size_t actualSize = std::max(mBlockSize, size);
+
+    Block block = {};
+
+    // Zero-allocate the block's buffer.
+    block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actualSize]());
+    assert(block.buffer);
+
+    block.size = size;
+    block.mBlockSize = actualSize;
+
+    mBlocks.push_back(std::move(block));
+    mSize += size;
+    return mBlocks.back().buffer.get();
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/BigBuffer.h b/tools/aapt2/BigBuffer.h
new file mode 100644
index 0000000..025142b
--- /dev/null
+++ b/tools/aapt2/BigBuffer.h
@@ -0,0 +1,158 @@
+/*
+ * 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_BIG_BUFFER_H
+#define AAPT_BIG_BUFFER_H
+
+#include <cstring>
+#include <memory>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * Inspired by protobuf's ZeroCopyOutputStream, offers blocks of memory
+ * in which to write without knowing the full size of the entire payload.
+ * This is essentially a list of memory blocks. As one fills up, another
+ * block is allocated and appended to the end of the list.
+ */
+class BigBuffer {
+public:
+    /**
+     * A contiguous block of allocated memory.
+     */
+    struct Block {
+        /**
+         * Pointer to the memory.
+         */
+        std::unique_ptr<uint8_t[]> buffer;
+
+        /**
+         * Size of memory that is currently occupied. The actual
+         * allocation may be larger.
+         */
+        size_t size;
+
+    private:
+        friend class BigBuffer;
+
+        /**
+         * The size of the memory block allocation.
+         */
+        size_t mBlockSize;
+    };
+
+    typedef std::vector<Block>::const_iterator const_iterator;
+
+    /**
+     * Create a BigBuffer with block allocation sizes
+     * of blockSize.
+     */
+    BigBuffer(size_t blockSize);
+
+    BigBuffer(const BigBuffer&) = delete; // No copying.
+
+    BigBuffer(BigBuffer&& rhs);
+
+    /**
+     * Number of occupied bytes in all the allocated blocks.
+     */
+    size_t size() const;
+
+    /**
+     * Returns a pointer to an array of T, where T is
+     * a POD type. The elements are zero-initialized.
+     */
+    template <typename T>
+    T* nextBlock(size_t count = 1);
+
+    /**
+     * Moves the specified BigBuffer into this one. When this method
+     * returns, buffer is empty.
+     */
+    void appendBuffer(BigBuffer&& buffer);
+
+    /**
+     * Pads the block with 'bytes' bytes of zero values.
+     */
+    void pad(size_t bytes);
+
+    /**
+     * Pads the block so that it aligns on a 4 byte boundary.
+     */
+    void align4();
+
+    const_iterator begin() const;
+    const_iterator end() const;
+
+private:
+    /**
+     * Returns a pointer to a buffer of the requested size.
+     * The buffer is zero-initialized.
+     */
+    void* nextBlockImpl(size_t size);
+
+    size_t mBlockSize;
+    size_t mSize;
+    std::vector<Block> mBlocks;
+};
+
+inline BigBuffer::BigBuffer(size_t blockSize) : mBlockSize(blockSize), mSize(0) {
+}
+
+inline BigBuffer::BigBuffer(BigBuffer&& rhs) :
+        mBlockSize(rhs.mBlockSize), mSize(rhs.mSize), mBlocks(std::move(rhs.mBlocks)) {
+}
+
+inline size_t BigBuffer::size() const {
+    return mSize;
+}
+
+template <typename T>
+inline T* BigBuffer::nextBlock(size_t count) {
+    assert(count != 0);
+    return reinterpret_cast<T*>(nextBlockImpl(sizeof(T) * count));
+}
+
+inline void BigBuffer::appendBuffer(BigBuffer&& buffer) {
+    std::move(buffer.mBlocks.begin(), buffer.mBlocks.end(), std::back_inserter(mBlocks));
+    mSize += buffer.mSize;
+    buffer.mBlocks.clear();
+    buffer.mSize = 0;
+}
+
+inline void BigBuffer::pad(size_t bytes) {
+    nextBlock<char>(bytes);
+}
+
+inline void BigBuffer::align4() {
+    const size_t unaligned = mSize % 4;
+    if (unaligned != 0) {
+        pad(4 - unaligned);
+    }
+}
+
+inline BigBuffer::const_iterator BigBuffer::begin() const {
+    return mBlocks.begin();
+}
+
+inline BigBuffer::const_iterator BigBuffer::end() const {
+    return mBlocks.end();
+}
+
+} // namespace aapt
+
+#endif // AAPT_BIG_BUFFER_H
diff --git a/tools/aapt2/BigBuffer_test.cpp b/tools/aapt2/BigBuffer_test.cpp
new file mode 100644
index 0000000..01ee8d7
--- /dev/null
+++ b/tools/aapt2/BigBuffer_test.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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 "BigBuffer.h"
+
+#include <gtest/gtest.h>
+
+namespace aapt {
+
+TEST(BigBufferTest, AllocateSingleBlock) {
+    BigBuffer buffer(4);
+
+    EXPECT_NE(nullptr, buffer.nextBlock<char>(2));
+    EXPECT_EQ(2u, buffer.size());
+}
+
+TEST(BigBufferTest, ReturnSameBlockIfNextAllocationFits) {
+    BigBuffer buffer(16);
+
+    char* b1 = buffer.nextBlock<char>(8);
+    EXPECT_NE(nullptr, b1);
+
+    char* b2 = buffer.nextBlock<char>(4);
+    EXPECT_NE(nullptr, b2);
+
+    EXPECT_EQ(b1 + 8, b2);
+}
+
+TEST(BigBufferTest, AllocateExactSizeBlockIfLargerThanBlockSize) {
+    BigBuffer buffer(16);
+
+    EXPECT_NE(nullptr, buffer.nextBlock<char>(32));
+    EXPECT_EQ(32u, buffer.size());
+}
+
+TEST(BigBufferTest, AppendAndMoveBlock) {
+    BigBuffer buffer(16);
+
+    uint32_t* b1 = buffer.nextBlock<uint32_t>();
+    ASSERT_NE(nullptr, b1);
+    *b1 = 33;
+
+    {
+        BigBuffer buffer2(16);
+        b1 = buffer2.nextBlock<uint32_t>();
+        ASSERT_NE(nullptr, b1);
+        *b1 = 44;
+
+        buffer.appendBuffer(std::move(buffer2));
+        EXPECT_EQ(0u, buffer2.size());
+        EXPECT_EQ(buffer2.begin(), buffer2.end());
+    }
+
+    EXPECT_EQ(2 * sizeof(uint32_t), buffer.size());
+
+    auto b = buffer.begin();
+    ASSERT_NE(b, buffer.end());
+    ASSERT_EQ(sizeof(uint32_t), b->size);
+    ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
+    ++b;
+
+    ASSERT_NE(b, buffer.end());
+    ASSERT_EQ(sizeof(uint32_t), b->size);
+    ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get()));
+    ++b;
+
+    ASSERT_EQ(b, buffer.end());
+}
+
+TEST(BigBufferTest, PadAndAlignProperly) {
+    BigBuffer buffer(16);
+
+    ASSERT_NE(buffer.nextBlock<char>(2), nullptr);
+    ASSERT_EQ(2u, buffer.size());
+    buffer.pad(2);
+    ASSERT_EQ(4u, buffer.size());
+    buffer.align4();
+    ASSERT_EQ(4u, buffer.size());
+    buffer.pad(2);
+    ASSERT_EQ(6u, buffer.size());
+    buffer.align4();
+    ASSERT_EQ(8u, buffer.size());
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp
new file mode 100644
index 0000000..d58f05a
--- /dev/null
+++ b/tools/aapt2/BinaryResourceParser.cpp
@@ -0,0 +1,794 @@
+/*
+ * 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 "BinaryResourceParser.h"
+#include "Logger.h"
+#include "ResChunkPullParser.h"
+#include "ResourceParser.h"
+#include "ResourceTable.h"
+#include "ResourceTypeExtensions.h"
+#include "ResourceValues.h"
+#include "Source.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/TypeWrappers.h>
+#include <map>
+#include <string>
+
+namespace aapt {
+
+using namespace android;
+
+template <typename T>
+inline static const T* convertTo(const ResChunk_header* chunk) {
+    if (chunk->headerSize < sizeof(T)) {
+        return nullptr;
+    }
+    return reinterpret_cast<const T*>(chunk);
+}
+
+inline static const uint8_t* getChunkData(const ResChunk_header& chunk) {
+    return reinterpret_cast<const uint8_t*>(&chunk) + chunk.headerSize;
+}
+
+inline static size_t getChunkDataLen(const ResChunk_header& chunk) {
+    return chunk.size - chunk.headerSize;
+}
+
+/*
+ * Visitor that converts a reference's resource ID to a resource name,
+ * given a mapping from resource ID to resource name.
+ */
+struct ReferenceIdToNameVisitor : ValueVisitor {
+    ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceName>& cache) : mCache(cache) {
+    }
+
+    void visit(Reference& reference, ValueVisitorArgs&) override {
+        idToName(reference);
+    }
+
+    void visit(Attribute& attr, ValueVisitorArgs&) override {
+        for (auto& entry : attr.symbols) {
+            idToName(entry.symbol);
+        }
+    }
+
+    void visit(Style& style, ValueVisitorArgs&) override {
+        if (style.parent.id.isValid()) {
+            idToName(style.parent);
+        }
+
+        for (auto& entry : style.entries) {
+            idToName(entry.key);
+            entry.value->accept(*this, {});
+        }
+    }
+
+    void visit(Styleable& styleable, ValueVisitorArgs&) override {
+        for (auto& attr : styleable.entries) {
+            idToName(attr);
+        }
+    }
+
+    void visit(Array& array, ValueVisitorArgs&) override {
+        for (auto& item : array.items) {
+            item->accept(*this, {});
+        }
+    }
+
+    void visit(Plural& plural, ValueVisitorArgs&) override {
+        for (auto& item : plural.values) {
+            if (item) {
+                item->accept(*this, {});
+            }
+        }
+    }
+
+private:
+    void idToName(Reference& reference) {
+        if (!reference.id.isValid()) {
+            return;
+        }
+
+        auto cacheIter = mCache.find(reference.id);
+        if (cacheIter == std::end(mCache)) {
+            Logger::note() << "failed to find " << reference.id << std::endl;
+        } else {
+            reference.name = cacheIter->second;
+            reference.id = 0;
+        }
+    }
+
+    const std::map<ResourceId, ResourceName>& mCache;
+};
+
+
+BinaryResourceParser::BinaryResourceParser(std::shared_ptr<ResourceTable> table,
+                                           const Source& source,
+                                           const void* data,
+                                           size_t len) :
+        mTable(table), mSource(source), mData(data), mDataLen(len) {
+}
+
+bool BinaryResourceParser::parse() {
+    ResChunkPullParser parser(mData, mDataLen);
+
+    bool error = false;
+    while(ResChunkPullParser::isGoodEvent(parser.next())) {
+        if (parser.getChunk()->type != android::RES_TABLE_TYPE) {
+            Logger::warn(mSource)
+                    << "unknown chunk of type '"
+                    << parser.getChunk()->type
+                    << "'."
+                    << std::endl;
+            continue;
+        }
+
+        error |= !parseTable(parser.getChunk());
+    }
+
+    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
+        Logger::error(mSource)
+                << "bad document: "
+                << parser.getLastError()
+                << "."
+                << std::endl;
+        return false;
+    }
+    return !error;
+}
+
+bool BinaryResourceParser::getSymbol(const void* data, ResourceNameRef* outSymbol) {
+    if (!mSymbolEntries || mSymbolEntryCount == 0) {
+        return false;
+    }
+
+    // We only support 32 bit offsets right now.
+    const ptrdiff_t offset = reinterpret_cast<uintptr_t>(data) -
+            reinterpret_cast<uintptr_t>(mData);
+    if (offset > std::numeric_limits<uint32_t>::max()) {
+        return false;
+    }
+
+    for (size_t i = 0; i < mSymbolEntryCount; i++) {
+        if (mSymbolEntries[i].offset == offset) {
+            // This offset is a symbol!
+            const StringPiece16 str = util::getString(mSymbolPool,
+                                                      mSymbolEntries[i].stringIndex);
+            StringPiece16 typeStr;
+            ResourceParser::extractResourceName(str, &outSymbol->package, &typeStr,
+                                                &outSymbol->entry);
+            const ResourceType* type = parseResourceType(typeStr);
+            if (!type) {
+                return false;
+            }
+            outSymbol->type = *type;
+
+            // Since we scan the symbol table in order, we can start looking for the
+            // next symbol from this point.
+            mSymbolEntryCount -= i + 1;
+            mSymbolEntries += i + 1;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool BinaryResourceParser::parseSymbolTable(const ResChunk_header* chunk) {
+    const SymbolTable_header* symbolTableHeader = convertTo<SymbolTable_header>(chunk);
+    if (!symbolTableHeader) {
+        Logger::error(mSource)
+                << "could not parse chunk as SymbolTable_header."
+                << std::endl;
+        return false;
+    }
+
+    const size_t entrySizeBytes = symbolTableHeader->count * sizeof(SymbolTable_entry);
+    if (entrySizeBytes > getChunkDataLen(symbolTableHeader->header)) {
+        Logger::error(mSource)
+                << "entries extend beyond chunk."
+                << std::endl;
+        return false;
+    }
+
+    mSymbolEntries = reinterpret_cast<const SymbolTable_entry*>(
+            getChunkData(symbolTableHeader->header));
+    mSymbolEntryCount = symbolTableHeader->count;
+
+    ResChunkPullParser parser(getChunkData(symbolTableHeader->header) + entrySizeBytes,
+                              getChunkDataLen(symbolTableHeader->header) - entrySizeBytes);
+    if (!ResChunkPullParser::isGoodEvent(parser.next())) {
+        Logger::error(mSource)
+                << "failed to parse chunk: "
+                << parser.getLastError()
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    if (parser.getChunk()->type != android::RES_STRING_POOL_TYPE) {
+        Logger::error(mSource)
+                << "expected Symbol string pool."
+                << std::endl;
+        return false;
+    }
+
+    if (mSymbolPool.setTo(parser.getChunk(), parser.getChunk()->size) != android::NO_ERROR) {
+        Logger::error(mSource)
+                << "failed to parse symbol string pool with code: "
+                << mSymbolPool.getError()
+                << "."
+                << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) {
+    const ResTable_header* tableHeader = convertTo<ResTable_header>(chunk);
+    if (!tableHeader) {
+        Logger::error(mSource)
+                << "could not parse chunk as ResTable_header."
+                << std::endl;
+        return false;
+    }
+
+    ResChunkPullParser parser(getChunkData(tableHeader->header),
+                              getChunkDataLen(tableHeader->header));
+    while (ResChunkPullParser::isGoodEvent(parser.next())) {
+        switch (parser.getChunk()->type) {
+        case android::RES_STRING_POOL_TYPE:
+            if (mValuePool.getError() == android::NO_INIT) {
+                if (mValuePool.setTo(parser.getChunk(), parser.getChunk()->size) !=
+                        android::NO_ERROR) {
+                    Logger::error(mSource)
+                            << "failed to parse value string pool with code: "
+                            << mValuePool.getError()
+                            << "."
+                            << std::endl;
+                    return false;
+                }
+
+                // Reserve some space for the strings we are going to add.
+                mTable->getValueStringPool().hintWillAdd(
+                        mValuePool.size(), mValuePool.styleCount());
+            } else {
+                Logger::warn(mSource)
+                    << "unexpected string pool."
+                    << std::endl;
+            }
+            break;
+
+        case RES_TABLE_SYMBOL_TABLE_TYPE:
+            if (!parseSymbolTable(parser.getChunk())) {
+                return false;
+            }
+            break;
+
+        case RES_TABLE_SOURCE_POOL_TYPE: {
+            if (mSourcePool.setTo(getChunkData(*parser.getChunk()),
+                        getChunkDataLen(*parser.getChunk())) != android::NO_ERROR) {
+                Logger::error(mSource)
+                        << "failed to parse source pool with code: "
+                        << mSourcePool.getError()
+                        << "."
+                        << std::endl;
+                return false;
+            }
+            break;
+        }
+
+        case android::RES_TABLE_PACKAGE_TYPE:
+            if (!parsePackage(parser.getChunk())) {
+                return false;
+            }
+            break;
+
+        default:
+            Logger::warn(mSource)
+                << "unexpected chunk of type "
+                << parser.getChunk()->type
+                << "."
+                << std::endl;
+            break;
+        }
+    }
+
+    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
+        Logger::error(mSource)
+            << "bad resource table: " << parser.getLastError()
+            << "."
+            << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
+    if (mValuePool.getError() != android::NO_ERROR) {
+        Logger::error(mSource)
+                << "no value string pool for ResTable."
+                << std::endl;
+        return false;
+    }
+
+    const ResTable_package* packageHeader = convertTo<ResTable_package>(chunk);
+    if (!packageHeader) {
+        Logger::error(mSource)
+                << "could not parse chunk as ResTable_header."
+                << std::endl;
+        return false;
+    }
+
+    if (mTable->getPackageId() == ResourceTable::kUnsetPackageId) {
+        // This is the first time the table has it's package ID set.
+        mTable->setPackageId(packageHeader->id);
+    } else if (mTable->getPackageId() != packageHeader->id) {
+        Logger::error(mSource)
+                << "ResTable_package has package ID "
+                << std::hex << packageHeader->id << std::dec
+                << " but ResourceTable has package ID "
+                << std::hex << mTable->getPackageId() << std::dec
+                << std::endl;
+        return false;
+    }
+
+    size_t len = strnlen16(reinterpret_cast<const char16_t*>(packageHeader->name),
+            sizeof(packageHeader->name) / sizeof(packageHeader->name[0]));
+    mTable->setPackage(StringPiece16(reinterpret_cast<const char16_t*>(packageHeader->name), len));
+
+    ResChunkPullParser parser(getChunkData(packageHeader->header),
+                              getChunkDataLen(packageHeader->header));
+    while (ResChunkPullParser::isGoodEvent(parser.next())) {
+        switch (parser.getChunk()->type) {
+        case android::RES_STRING_POOL_TYPE:
+            if (mTypePool.getError() == android::NO_INIT) {
+                if (mTypePool.setTo(parser.getChunk(), parser.getChunk()->size) !=
+                        android::NO_ERROR) {
+                    Logger::error(mSource)
+                            << "failed to parse type string pool with code "
+                            << mTypePool.getError()
+                            << "."
+                            << std::endl;
+                    return false;
+                }
+            } else if (mKeyPool.getError() == android::NO_INIT) {
+                if (mKeyPool.setTo(parser.getChunk(), parser.getChunk()->size) !=
+                        android::NO_ERROR) {
+                    Logger::error(mSource)
+                            << "failed to parse key string pool with code "
+                            << mKeyPool.getError()
+                            << "."
+                            << std::endl;
+                    return false;
+                }
+            } else {
+                Logger::warn(mSource)
+                        << "unexpected string pool."
+                        << std::endl;
+            }
+            break;
+
+        case android::RES_TABLE_TYPE_SPEC_TYPE:
+            if (!parseTypeSpec(parser.getChunk())) {
+                return false;
+            }
+            break;
+
+        case android::RES_TABLE_TYPE_TYPE:
+            if (!parseType(parser.getChunk())) {
+                return false;
+            }
+            break;
+
+        default:
+            Logger::warn(mSource)
+                    << "unexpected chunk of type "
+                    << parser.getChunk()->type
+                    << "."
+                    << std::endl;
+            break;
+        }
+    }
+
+    if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
+        Logger::error(mSource)
+                << "bad package: "
+                << parser.getLastError()
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    // Now go through the table and change resource ID references to
+    // symbolic references.
+
+    ReferenceIdToNameVisitor visitor(mIdIndex);
+    for (auto& type : *mTable) {
+        for (auto& entry : type->entries) {
+            for (auto& configValue : entry->values) {
+                configValue.value->accept(visitor, {});
+            }
+        }
+    }
+    return true;
+}
+
+bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
+    if (mTypePool.getError() != android::NO_ERROR) {
+        Logger::error(mSource)
+                << "no type string pool available for ResTable_typeSpec."
+                << std::endl;
+        return false;
+    }
+
+    const ResTable_typeSpec* typeSpec = convertTo<ResTable_typeSpec>(chunk);
+    if (!typeSpec) {
+        Logger::error(mSource)
+                << "could not parse chunk as ResTable_typeSpec."
+                << std::endl;
+        return false;
+    }
+
+    if (typeSpec->id == 0) {
+        Logger::error(mSource)
+                << "ResTable_typeSpec has invalid id: "
+                << typeSpec->id
+                << "."
+                << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool BinaryResourceParser::parseType(const ResChunk_header* chunk) {
+    if (mTypePool.getError() != android::NO_ERROR) {
+        Logger::error(mSource)
+                << "no type string pool available for ResTable_typeSpec."
+                << std::endl;
+        return false;
+    }
+
+    if (mKeyPool.getError() != android::NO_ERROR) {
+        Logger::error(mSource)
+                << "no key string pool available for ResTable_type."
+                << std::endl;
+        return false;
+    }
+
+    const ResTable_type* type = convertTo<ResTable_type>(chunk);
+    if (!type) {
+        Logger::error(mSource)
+                << "could not parse chunk as ResTable_type."
+                << std::endl;
+        return false;
+    }
+
+    if (type->id == 0) {
+        Logger::error(mSource)
+                << "ResTable_type has invalid id: "
+                << type->id
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    const ConfigDescription config(type->config);
+    const StringPiece16 typeName = util::getString(mTypePool, type->id - 1);
+
+    const ResourceType* parsedType = parseResourceType(typeName);
+    if (!parsedType) {
+        Logger::error(mSource)
+                << "invalid type name '"
+                << typeName
+                << "' for type with ID "
+                << uint32_t(type->id)
+                << "." << std::endl;
+        return false;
+    }
+
+    android::TypeVariant tv(type);
+    for (auto it = tv.beginEntries(); it != tv.endEntries(); ++it) {
+        if (!*it) {
+            continue;
+        }
+
+        const ResTable_entry* entry = *it;
+        const ResourceName name = {
+                mTable->getPackage(),
+                *parsedType,
+                util::getString(mKeyPool, entry->key.index).toString()
+        };
+
+        const ResourceId resId = { mTable->getPackageId(), type->id, it.index() };
+
+        std::unique_ptr<Value> resourceValue;
+        const ResTable_entry_source* sourceBlock = nullptr;
+        if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
+            const ResTable_map_entry* mapEntry = static_cast<const ResTable_map_entry*>(entry);
+            if (mapEntry->size - sizeof(*mapEntry) == sizeof(*sourceBlock)) {
+                const uint8_t* data = reinterpret_cast<const uint8_t*>(mapEntry);
+                data += mapEntry->size - sizeof(*sourceBlock);
+                sourceBlock = reinterpret_cast<const ResTable_entry_source*>(data);
+            }
+
+            // TODO(adamlesinski): Check that the entry count is valid.
+            resourceValue = parseMapEntry(name, config, mapEntry);
+        } else {
+            if (entry->size - sizeof(*entry) == sizeof(*sourceBlock)) {
+                const uint8_t* data = reinterpret_cast<const uint8_t*>(entry);
+                data += entry->size - sizeof(*sourceBlock);
+                sourceBlock = reinterpret_cast<const ResTable_entry_source*>(data);
+            }
+
+            const Res_value* value = reinterpret_cast<const Res_value*>(
+                    reinterpret_cast<const uint8_t*>(entry) + entry->size);
+            resourceValue = parseValue(name, config, value, entry->flags);
+        }
+
+        if (!resourceValue) {
+            // TODO(adamlesinski): For now this is ok, but it really shouldn't be.
+            continue;
+        }
+
+        SourceLine source = mSource.line(0);
+        if (sourceBlock) {
+            size_t len;
+            const char* str = mSourcePool.string8At(sourceBlock->pathIndex, &len);
+            if (str) {
+                source.path.assign(str, len);
+            }
+            source.line = sourceBlock->line;
+        }
+
+        if (!mTable->addResource(name, config, source, std::move(resourceValue))) {
+            return false;
+        }
+
+        if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) {
+            if (!mTable->markPublic(name, resId, mSource.line(0))) {
+                return false;
+            }
+        }
+
+        // Add this resource name->id mapping to the index so
+        // that we can resolve all ID references to name references.
+        auto cacheIter = mIdIndex.find(resId);
+        if (cacheIter == mIdIndex.end()) {
+            mIdIndex.insert({ resId, name });
+        }
+    }
+    return true;
+}
+
+std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& name,
+                                                       const ConfigDescription& config,
+                                                       const Res_value* value,
+                                                       uint16_t flags) {
+    if (value->dataType == Res_value::TYPE_STRING) {
+        StringPiece16 str = util::getString(mValuePool, value->data);
+
+        const ResStringPool_span* spans = mValuePool.styleAt(value->data);
+        if (spans != nullptr) {
+            StyleString styleStr = { str.toString() };
+            while (spans->name.index != ResStringPool_span::END) {
+                styleStr.spans.push_back(Span{
+                        util::getString(mValuePool, spans->name.index).toString(),
+                        spans->firstChar,
+                        spans->lastChar
+                });
+                spans++;
+            }
+            return util::make_unique<StyledString>(
+                    mTable->getValueStringPool().makeRef(
+                            styleStr, StringPool::Context{1, config}));
+        } else {
+            // There are no styles associated with this string, so treat it as
+            // a simple string.
+            return util::make_unique<String>(
+                    mTable->getValueStringPool().makeRef(
+                            str, StringPool::Context{1, config}));
+        }
+    }
+
+    if (value->dataType == Res_value::TYPE_REFERENCE ||
+            value->dataType == Res_value::TYPE_ATTRIBUTE) {
+        const Reference::Type type = (value->dataType == Res_value::TYPE_REFERENCE) ?
+                    Reference::Type::kResource : Reference::Type::kAttribute;
+
+        if (value->data != 0) {
+            // This is a normal reference.
+            return util::make_unique<Reference>(value->data, type);
+        }
+
+        // This reference has an invalid ID. Check if it is an unresolved symbol.
+        ResourceNameRef symbol;
+        if (getSymbol(&value->data, &symbol)) {
+            return util::make_unique<Reference>(symbol, type);
+        }
+
+        // This is not an unresolved symbol, so it must be the magic @null reference.
+        Res_value nullType = {};
+        nullType.dataType = Res_value::TYPE_NULL;
+        nullType.data = Res_value::DATA_NULL_UNDEFINED;
+        return util::make_unique<BinaryPrimitive>(nullType);
+    }
+
+    if (value->dataType == ExtendedTypes::TYPE_SENTINEL) {
+        return util::make_unique<Sentinel>();
+    }
+
+    if (value->dataType == ExtendedTypes::TYPE_RAW_STRING) {
+        return util::make_unique<RawString>(
+                mTable->getValueStringPool().makeRef(util::getString(mValuePool, value->data),
+                                                    StringPool::Context{ 1, config }));
+    }
+
+    if (name.type == ResourceType::kId ||
+            (value->dataType == Res_value::TYPE_NULL &&
+            value->data == Res_value::DATA_NULL_UNDEFINED &&
+            (flags & ResTable_entry::FLAG_WEAK) != 0)) {
+        return util::make_unique<Id>();
+    }
+
+    // Treat this as a raw binary primitive.
+    return util::make_unique<BinaryPrimitive>(*value);
+}
+
+std::unique_ptr<Value> BinaryResourceParser::parseMapEntry(const ResourceNameRef& name,
+                                                           const ConfigDescription& config,
+                                                           const ResTable_map_entry* map) {
+    switch (name.type) {
+        case ResourceType::kStyle:
+            return parseStyle(name, config, map);
+        case ResourceType::kAttr:
+            return parseAttr(name, config, map);
+        case ResourceType::kArray:
+            return parseArray(name, config, map);
+        case ResourceType::kStyleable:
+            return parseStyleable(name, config, map);
+        case ResourceType::kPlurals:
+            return parsePlural(name, config, map);
+        default:
+            break;
+    }
+    return {};
+}
+
+std::unique_ptr<Style> BinaryResourceParser::parseStyle(const ResourceNameRef& name,
+                                                        const ConfigDescription& config,
+                                                        const ResTable_map_entry* map) {
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+    if (map->parent.ident == 0) {
+        // The parent is either not set or it is an unresolved symbol.
+        // Check to see if it is a symbol.
+        ResourceNameRef symbol;
+        if (getSymbol(&map->parent.ident, &symbol)) {
+            style->parent.name = symbol.toResourceName();
+        }
+    } else {
+         // The parent is a regular reference to a resource.
+        style->parent.id = map->parent.ident;
+    }
+
+    for (const ResTable_map& mapEntry : map) {
+        style->entries.emplace_back();
+        Style::Entry& styleEntry = style->entries.back();
+
+        if (mapEntry.name.ident == 0) {
+            // The map entry's key (attribute) is not set. This must be
+            // a symbol reference, so resolve it.
+            ResourceNameRef symbol;
+            bool result = getSymbol(&mapEntry.name.ident, &symbol);
+            assert(result);
+            styleEntry.key.name = symbol.toResourceName();
+        } else {
+            // The map entry's key (attribute) is a regular reference.
+            styleEntry.key.id = mapEntry.name.ident;
+        }
+
+        // Parse the attribute's value.
+        styleEntry.value = parseValue(name, config, &mapEntry.value, 0);
+        assert(styleEntry.value);
+    }
+    return style;
+}
+
+std::unique_ptr<Attribute> BinaryResourceParser::parseAttr(const ResourceNameRef& name,
+                                                           const ConfigDescription& config,
+                                                           const ResTable_map_entry* map) {
+    const bool isWeak = (map->flags & ResTable_entry::FLAG_WEAK) != 0;
+    std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak);
+
+    // First we must discover what type of attribute this is. Find the type mask.
+    auto typeMaskIter = std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool {
+        return entry.name.ident == ResTable_map::ATTR_TYPE;
+    });
+
+    if (typeMaskIter != end(map)) {
+        attr->typeMask = typeMaskIter->value.data;
+    }
+
+    if (attr->typeMask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
+        for (const ResTable_map& mapEntry : map) {
+            if (Res_INTERNALID(mapEntry.name.ident)) {
+                continue;
+            }
+
+            attr->symbols.push_back(Attribute::Symbol{
+                    Reference(mapEntry.name.ident),
+                    mapEntry.value.data
+            });
+        }
+    }
+
+    // TODO(adamlesinski): Find min, max, i80n, etc attributes.
+    return attr;
+}
+
+std::unique_ptr<Array> BinaryResourceParser::parseArray(const ResourceNameRef& name,
+                                                        const ConfigDescription& config,
+                                                        const ResTable_map_entry* map) {
+    std::unique_ptr<Array> array = util::make_unique<Array>();
+    for (const ResTable_map& mapEntry : map) {
+        array->items.push_back(parseValue(name, config, &mapEntry.value, 0));
+    }
+    return array;
+}
+
+std::unique_ptr<Styleable> BinaryResourceParser::parseStyleable(const ResourceNameRef& name,
+                                                                const ConfigDescription& config,
+                                                                const ResTable_map_entry* map) {
+    std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
+    for (const ResTable_map& mapEntry : map) {
+        styleable->entries.emplace_back(mapEntry.name.ident);
+    }
+    return styleable;
+}
+
+std::unique_ptr<Plural> BinaryResourceParser::parsePlural(const ResourceNameRef& name,
+                                                          const ConfigDescription& config,
+                                                          const ResTable_map_entry* map) {
+    std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+    for (const ResTable_map& mapEntry : map) {
+        std::unique_ptr<Item> item = parseValue(name, config, &mapEntry.value, 0);
+
+        switch (mapEntry.name.ident) {
+            case android::ResTable_map::ATTR_ZERO:
+                plural->values[Plural::Zero] = std::move(item);
+                break;
+            case android::ResTable_map::ATTR_ONE:
+                plural->values[Plural::One] = std::move(item);
+                break;
+            case android::ResTable_map::ATTR_TWO:
+                plural->values[Plural::Two] = std::move(item);
+                break;
+            case android::ResTable_map::ATTR_FEW:
+                plural->values[Plural::Few] = std::move(item);
+                break;
+            case android::ResTable_map::ATTR_MANY:
+                plural->values[Plural::Many] = std::move(item);
+                break;
+            case android::ResTable_map::ATTR_OTHER:
+                plural->values[Plural::Other] = std::move(item);
+                break;
+        }
+    }
+    return plural;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/BinaryResourceParser.h b/tools/aapt2/BinaryResourceParser.h
new file mode 100644
index 0000000..9268078
--- /dev/null
+++ b/tools/aapt2/BinaryResourceParser.h
@@ -0,0 +1,153 @@
+/*
+ * 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_RESOURCE_PARSER_H
+#define AAPT_BINARY_RESOURCE_PARSER_H
+
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Source.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <string>
+
+namespace aapt {
+
+struct SymbolTable_entry;
+
+/*
+ * Parses a binary resource table (resources.arsc) and adds the entries
+ * to a ResourceTable. This is different than the libandroidfw ResTable
+ * in that it scans the table from top to bottom and doesn't require
+ * support for random access. It is also able to parse non-runtime
+ * chunks and types.
+ */
+class BinaryResourceParser {
+public:
+    /*
+     * Creates a parser, which will read `len` bytes from `data`, and
+     * add any resources parsed to `table`. `source` is for logging purposes.
+     */
+    BinaryResourceParser(std::shared_ptr<ResourceTable> table, const Source& source,
+                         const void* data, size_t len);
+
+    BinaryResourceParser(const BinaryResourceParser&) = delete; // No copy.
+
+    /*
+     * Parses the binary resource table and returns true if successful.
+     */
+    bool parse();
+
+private:
+    // Helper method to retrieve the symbol name for a given table offset specified
+    // as a pointer.
+    bool getSymbol(const void* data, ResourceNameRef* outSymbol);
+
+    bool parseTable(const android::ResChunk_header* chunk);
+    bool parseSymbolTable(const android::ResChunk_header* chunk);
+
+    // Looks up the resource ID in the reference and converts it to a name if available.
+    bool idToName(Reference* reference);
+
+    bool parsePackage(const android::ResChunk_header* chunk);
+    bool parseTypeSpec(const android::ResChunk_header* chunk);
+    bool parseType(const android::ResChunk_header* chunk);
+
+    std::unique_ptr<Item> parseValue(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::Res_value* value, uint16_t flags);
+
+    std::unique_ptr<Value> parseMapEntry(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::unique_ptr<Style> parseStyle(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::unique_ptr<Attribute> parseAttr(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::unique_ptr<Array> parseArray(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::unique_ptr<Plural> parsePlural(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::unique_ptr<Styleable> parseStyleable(const ResourceNameRef& name,
+            const ConfigDescription& config, const android::ResTable_map_entry* map);
+
+    std::shared_ptr<ResourceTable> mTable;
+
+    const Source mSource;
+
+    const void* mData;
+    const size_t mDataLen;
+
+    // The package name of the resource table.
+    std::u16string mPackage;
+
+    // The array of symbol entries. Each element points to an offset
+    // in the table and an index into the symbol table string pool.
+    const SymbolTable_entry* mSymbolEntries = nullptr;
+
+    // Number of symbol entries.
+    size_t mSymbolEntryCount = 0;
+
+    // The symbol table string pool. Holds the names of symbols
+    // referenced in this table but not defined nor resolved to an
+    // ID.
+    android::ResStringPool mSymbolPool;
+
+    // The source string pool. Resource entries may have an extra
+    // field that points into this string pool, which denotes where
+    // the resource was parsed from originally.
+    android::ResStringPool mSourcePool;
+
+    // The standard value string pool for resource values.
+    android::ResStringPool mValuePool;
+
+    // The string pool that holds the names of the types defined
+    // in this table.
+    android::ResStringPool mTypePool;
+
+    // The string pool that holds the names of the entries defined
+    // in this table.
+    android::ResStringPool mKeyPool;
+
+    // A mapping of resource ID to resource name. When we finish parsing
+    // we use this to convert all resource IDs to symbolic references.
+    std::map<ResourceId, ResourceName> mIdIndex;
+};
+
+} // namespace aapt
+
+namespace android {
+
+/**
+ * Iterator functionality for ResTable_map_entry.
+ */
+
+inline const ResTable_map* begin(const ResTable_map_entry* map) {
+    return reinterpret_cast<const ResTable_map*>(
+            reinterpret_cast<const uint8_t*>(map) + map->size);
+}
+
+inline const ResTable_map* end(const ResTable_map_entry* map) {
+    return reinterpret_cast<const ResTable_map*>(
+            reinterpret_cast<const uint8_t*>(map) + map->size) + map->count;
+}
+
+} // namespace android
+
+#endif // AAPT_BINARY_RESOURCE_PARSER_H
diff --git a/tools/aapt2/Compat_test.cpp b/tools/aapt2/Compat_test.cpp
new file mode 100644
index 0000000..96aee44
--- /dev/null
+++ b/tools/aapt2/Compat_test.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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 <gtest/gtest.h>
+
+namespace aapt {
+
+TEST(CompatTest, VersionAttributesInStyle) {
+}
+
+TEST(CompatTest, VersionAttributesInXML) {
+}
+
+TEST(CompatTest, DoNotOverrideExistingVersionedFiles) {
+}
+
+TEST(CompatTest, VersionAttributesInStyleWithCorrectPrecedence) {
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
new file mode 100644
index 0000000..6ddf94a
--- /dev/null
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -0,0 +1,752 @@
+/*
+ * 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 "ConfigDescription.h"
+#include "Locale.h"
+#include "SdkConstants.h"
+#include "StringPiece.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+using android::ResTable_config;
+
+static const char* kWildcardName = "any";
+
+static bool parseMcc(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->mcc = 0;
+        return true;
+    }
+    const char* c = name;
+    if (tolower(*c) != 'm') return false;
+    c++;
+    if (tolower(*c) != 'c') return false;
+    c++;
+    if (tolower(*c) != 'c') return false;
+    c++;
+
+    const char* val = c;
+
+    while (*c >= '0' && *c <= '9') {
+        c++;
+    }
+    if (*c != 0) return false;
+    if (c-val != 3) return false;
+
+    int d = atoi(val);
+    if (d != 0) {
+        if (out) out->mcc = d;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseMnc(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->mcc = 0;
+        return true;
+    }
+    const char* c = name;
+    if (tolower(*c) != 'm') return false;
+    c++;
+    if (tolower(*c) != 'n') return false;
+    c++;
+    if (tolower(*c) != 'c') return false;
+    c++;
+
+    const char* val = c;
+
+    while (*c >= '0' && *c <= '9') {
+        c++;
+    }
+    if (*c != 0) return false;
+    if (c-val == 0 || c-val > 3) return false;
+
+    if (out) {
+        out->mnc = atoi(val);
+        if (out->mnc == 0) {
+            out->mnc = ACONFIGURATION_MNC_ZERO;
+        }
+    }
+
+    return true;
+}
+
+static bool parseLayoutDirection(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+                | ResTable_config::LAYOUTDIR_ANY;
+        return true;
+    } else if (strcmp(name, "ldltr") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+                | ResTable_config::LAYOUTDIR_LTR;
+        return true;
+    } else if (strcmp(name, "ldrtl") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+                | ResTable_config::LAYOUTDIR_RTL;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_ANY;
+        return true;
+    } else if (strcmp(name, "small") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_SMALL;
+        return true;
+    } else if (strcmp(name, "normal") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_NORMAL;
+        return true;
+    } else if (strcmp(name, "large") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_LARGE;
+        return true;
+    } else if (strcmp(name, "xlarge") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENSIZE)
+                | ResTable_config::SCREENSIZE_XLARGE;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_ANY;
+        return true;
+    } else if (strcmp(name, "long") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_YES;
+        return true;
+    } else if (strcmp(name, "notlong") == 0) {
+        if (out) out->screenLayout =
+                (out->screenLayout&~ResTable_config::MASK_SCREENLONG)
+                | ResTable_config::SCREENLONG_NO;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseOrientation(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->orientation = out->ORIENTATION_ANY;
+        return true;
+    } else if (strcmp(name, "port") == 0) {
+        if (out) out->orientation = out->ORIENTATION_PORT;
+        return true;
+    } else if (strcmp(name, "land") == 0) {
+        if (out) out->orientation = out->ORIENTATION_LAND;
+        return true;
+    } else if (strcmp(name, "square") == 0) {
+        if (out) out->orientation = out->ORIENTATION_SQUARE;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseUiModeType(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->uiMode =
+                (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+                | ResTable_config::UI_MODE_TYPE_ANY;
+        return true;
+    } else if (strcmp(name, "desk") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+              | ResTable_config::UI_MODE_TYPE_DESK;
+        return true;
+    } else if (strcmp(name, "car") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+              | ResTable_config::UI_MODE_TYPE_CAR;
+        return true;
+    } else if (strcmp(name, "television") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+              | ResTable_config::UI_MODE_TYPE_TELEVISION;
+        return true;
+    } else if (strcmp(name, "appliance") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+              | ResTable_config::UI_MODE_TYPE_APPLIANCE;
+        return true;
+    } else if (strcmp(name, "watch") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE)
+              | ResTable_config::UI_MODE_TYPE_WATCH;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseUiModeNight(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->uiMode =
+                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
+                | ResTable_config::UI_MODE_NIGHT_ANY;
+        return true;
+    } else if (strcmp(name, "night") == 0) {
+        if (out) out->uiMode =
+                (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
+                | ResTable_config::UI_MODE_NIGHT_YES;
+        return true;
+    } else if (strcmp(name, "notnight") == 0) {
+      if (out) out->uiMode =
+              (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT)
+              | ResTable_config::UI_MODE_NIGHT_NO;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseDensity(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->density = ResTable_config::DENSITY_DEFAULT;
+        return true;
+    }
+
+    if (strcmp(name, "anydpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_ANY;
+        return true;
+    }
+
+    if (strcmp(name, "nodpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_NONE;
+        return true;
+    }
+
+    if (strcmp(name, "ldpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_LOW;
+        return true;
+    }
+
+    if (strcmp(name, "mdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_MEDIUM;
+        return true;
+    }
+
+    if (strcmp(name, "tvdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_TV;
+        return true;
+    }
+
+    if (strcmp(name, "hdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_HIGH;
+        return true;
+    }
+
+    if (strcmp(name, "xhdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_XHIGH;
+        return true;
+    }
+
+    if (strcmp(name, "xxhdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_XXHIGH;
+        return true;
+    }
+
+    if (strcmp(name, "xxxhdpi") == 0) {
+        if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
+        return true;
+    }
+
+    char* c = (char*)name;
+    while (*c >= '0' && *c <= '9') {
+        c++;
+    }
+
+    // check that we have 'dpi' after the last digit.
+    if (toupper(c[0]) != 'D' ||
+            toupper(c[1]) != 'P' ||
+            toupper(c[2]) != 'I' ||
+            c[3] != 0) {
+        return false;
+    }
+
+    // temporarily replace the first letter with \0 to
+    // use atoi.
+    char tmp = c[0];
+    c[0] = '\0';
+
+    int d = atoi(name);
+    c[0] = tmp;
+
+    if (d != 0) {
+        if (out) out->density = d;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseTouchscreen(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
+        return true;
+    } else if (strcmp(name, "notouch") == 0) {
+        if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
+        return true;
+    } else if (strcmp(name, "stylus") == 0) {
+        if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
+        return true;
+    } else if (strcmp(name, "finger") == 0) {
+        if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseKeysHidden(const char* name, ResTable_config* out) {
+    uint8_t mask = 0;
+    uint8_t value = 0;
+    if (strcmp(name, kWildcardName) == 0) {
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_ANY;
+    } else if (strcmp(name, "keysexposed") == 0) {
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_NO;
+    } else if (strcmp(name, "keyshidden") == 0) {
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_YES;
+    } else if (strcmp(name, "keyssoft") == 0) {
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_SOFT;
+    }
+
+    if (mask != 0) {
+        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseKeyboard(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->keyboard = out->KEYBOARD_ANY;
+        return true;
+    } else if (strcmp(name, "nokeys") == 0) {
+        if (out) out->keyboard = out->KEYBOARD_NOKEYS;
+        return true;
+    } else if (strcmp(name, "qwerty") == 0) {
+        if (out) out->keyboard = out->KEYBOARD_QWERTY;
+        return true;
+    } else if (strcmp(name, "12key") == 0) {
+        if (out) out->keyboard = out->KEYBOARD_12KEY;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseNavHidden(const char* name, ResTable_config* out) {
+    uint8_t mask = 0;
+    uint8_t value = 0;
+    if (strcmp(name, kWildcardName) == 0) {
+        mask = ResTable_config::MASK_NAVHIDDEN;
+        value = ResTable_config::NAVHIDDEN_ANY;
+    } else if (strcmp(name, "navexposed") == 0) {
+        mask = ResTable_config::MASK_NAVHIDDEN;
+        value = ResTable_config::NAVHIDDEN_NO;
+    } else if (strcmp(name, "navhidden") == 0) {
+        mask = ResTable_config::MASK_NAVHIDDEN;
+        value = ResTable_config::NAVHIDDEN_YES;
+    }
+
+    if (mask != 0) {
+        if (out) out->inputFlags = (out->inputFlags&~mask) | value;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseNavigation(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) out->navigation = out->NAVIGATION_ANY;
+        return true;
+    } else if (strcmp(name, "nonav") == 0) {
+        if (out) out->navigation = out->NAVIGATION_NONAV;
+        return true;
+    } else if (strcmp(name, "dpad") == 0) {
+        if (out) out->navigation = out->NAVIGATION_DPAD;
+        return true;
+    } else if (strcmp(name, "trackball") == 0) {
+        if (out) out->navigation = out->NAVIGATION_TRACKBALL;
+        return true;
+    } else if (strcmp(name, "wheel") == 0) {
+        if (out) out->navigation = out->NAVIGATION_WHEEL;
+        return true;
+    }
+
+    return false;
+}
+
+static bool parseScreenSize(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->screenWidth = out->SCREENWIDTH_ANY;
+            out->screenHeight = out->SCREENHEIGHT_ANY;
+        }
+        return true;
+    }
+
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || *x != 'x') return false;
+    std::string xName(name, x-name);
+    x++;
+
+    const char* y = x;
+    while (*y >= '0' && *y <= '9') y++;
+    if (y == name || *y != 0) return false;
+    std::string yName(x, y-x);
+
+    uint16_t w = (uint16_t)atoi(xName.c_str());
+    uint16_t h = (uint16_t)atoi(yName.c_str());
+    if (w < h) {
+        return false;
+    }
+
+    if (out) {
+        out->screenWidth = w;
+        out->screenHeight = h;
+    }
+
+    return true;
+}
+
+static bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 's') return false;
+    name++;
+    if (*name != 'w') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    std::string xName(name, x-name);
+
+    if (out) {
+        out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
+    }
+
+    return true;
+}
+
+static bool parseScreenWidthDp(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->screenWidthDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 'w') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    std::string xName(name, x-name);
+
+    if (out) {
+        out->screenWidthDp = (uint16_t)atoi(xName.c_str());
+    }
+
+    return true;
+}
+
+static bool parseScreenHeightDp(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->screenHeightDp = out->SCREENWIDTH_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 'h') return false;
+    name++;
+    const char* x = name;
+    while (*x >= '0' && *x <= '9') x++;
+    if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+    std::string xName(name, x-name);
+
+    if (out) {
+        out->screenHeightDp = (uint16_t)atoi(xName.c_str());
+    }
+
+    return true;
+}
+
+static bool parseVersion(const char* name, ResTable_config* out) {
+    if (strcmp(name, kWildcardName) == 0) {
+        if (out) {
+            out->sdkVersion = out->SDKVERSION_ANY;
+            out->minorVersion = out->MINORVERSION_ANY;
+        }
+        return true;
+    }
+
+    if (*name != 'v') {
+        return false;
+    }
+
+    name++;
+    const char* s = name;
+    while (*s >= '0' && *s <= '9') s++;
+    if (s == name || *s != 0) return false;
+    std::string sdkName(name, s-name);
+
+    if (out) {
+        out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
+        out->minorVersion = 0;
+    }
+
+    return true;
+}
+
+bool ConfigDescription::parse(const StringPiece& str, ConfigDescription* out) {
+    std::vector<std::string> parts = util::splitAndLowercase(str, '-');
+
+    ConfigDescription config;
+    ssize_t partsConsumed = 0;
+    LocaleValue locale;
+
+    const auto partsEnd = parts.end();
+    auto partIter = parts.begin();
+
+    if (str.size() == 0) {
+        goto success;
+    }
+
+    if (parseMcc(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseMnc(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    // Locale spans a few '-' separators, so we let it
+    // control the index.
+    partsConsumed = locale.initFromParts(partIter, partsEnd);
+    if (partsConsumed < 0) {
+        return false;
+    } else {
+        locale.writeTo(&config);
+        partIter += partsConsumed;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseLayoutDirection(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseSmallestScreenWidthDp(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseScreenWidthDp(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseScreenHeightDp(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseScreenLayoutSize(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseScreenLayoutLong(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseOrientation(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseUiModeType(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseUiModeNight(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseDensity(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseTouchscreen(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseKeysHidden(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseKeyboard(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseNavHidden(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseNavigation(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseScreenSize(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    if (parseVersion(partIter->c_str(), &config)) {
+        ++partIter;
+        if (partIter == partsEnd) {
+            goto success;
+        }
+    }
+
+    // Unrecognized.
+    return false;
+
+success:
+    if (out != NULL) {
+        applyVersionForCompatibility(&config);
+        *out = config;
+    }
+    return true;
+}
+
+void ConfigDescription::applyVersionForCompatibility(ConfigDescription* config) {
+    uint16_t minSdk = 0;
+    if (config->density == ResTable_config::DENSITY_ANY) {
+        minSdk = SDK_LOLLIPOP;
+    } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY
+            || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY
+            || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
+        minSdk = SDK_HONEYCOMB_MR2;
+    } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
+                != ResTable_config::UI_MODE_TYPE_ANY
+            ||  (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT)
+                != ResTable_config::UI_MODE_NIGHT_ANY) {
+        minSdk = SDK_FROYO;
+    } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE)
+                != ResTable_config::SCREENSIZE_ANY
+            ||  (config->screenLayout & ResTable_config::MASK_SCREENLONG)
+                != ResTable_config::SCREENLONG_ANY
+            || config->density != ResTable_config::DENSITY_DEFAULT) {
+        minSdk = SDK_DONUT;
+    }
+
+    if (minSdk > config->sdkVersion) {
+        config->sdkVersion = minSdk;
+    }
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h
new file mode 100644
index 0000000..67b4b75
--- /dev/null
+++ b/tools/aapt2/ConfigDescription.h
@@ -0,0 +1,129 @@
+/*
+ * 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_CONFIG_DESCRIPTION_H
+#define AAPT_CONFIG_DESCRIPTION_H
+
+#include "StringPiece.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <ostream>
+
+namespace aapt {
+
+/*
+ * Subclass of ResTable_config that adds convenient
+ * initialization and comparison methods.
+ */
+struct ConfigDescription : public android::ResTable_config {
+    /*
+     * Parse a string of the form 'fr-sw600dp-land' and fill in the
+     * given ResTable_config with resulting configuration parameters.
+     *
+     * The resulting configuration has the appropriate sdkVersion defined
+     * for backwards compatibility.
+     */
+    static bool parse(const StringPiece& str, ConfigDescription* out = nullptr);
+
+    /**
+     * If the configuration uses an axis that was added after
+     * the original Android release, make sure the SDK version
+     * is set accordingly.
+     */
+    static void applyVersionForCompatibility(ConfigDescription* config);
+
+    ConfigDescription();
+    ConfigDescription(const android::ResTable_config& o);
+    ConfigDescription(const ConfigDescription& o);
+    ConfigDescription(ConfigDescription&& o);
+
+    ConfigDescription& operator=(const android::ResTable_config& o);
+    ConfigDescription& operator=(const ConfigDescription& o);
+    ConfigDescription& operator=(ConfigDescription&& o);
+
+    bool operator<(const ConfigDescription& o) const;
+    bool operator<=(const ConfigDescription& o) const;
+    bool operator==(const ConfigDescription& o) const;
+    bool operator!=(const ConfigDescription& o) const;
+    bool operator>=(const ConfigDescription& o) const;
+    bool operator>(const ConfigDescription& o) const;
+};
+
+inline ConfigDescription::ConfigDescription() {
+    memset(this, 0, sizeof(*this));
+    size = sizeof(android::ResTable_config);
+}
+
+inline ConfigDescription::ConfigDescription(const android::ResTable_config& o) {
+    *static_cast<android::ResTable_config*>(this) = o;
+    size = sizeof(android::ResTable_config);
+}
+
+inline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
+    *static_cast<android::ResTable_config*>(this) = o;
+}
+
+inline ConfigDescription::ConfigDescription(ConfigDescription&& o) {
+    *this = o;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(const android::ResTable_config& o) {
+    *static_cast<android::ResTable_config*>(this) = o;
+    size = sizeof(android::ResTable_config);
+    return *this;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(const ConfigDescription& o) {
+    *static_cast<android::ResTable_config*>(this) = o;
+    return *this;
+}
+
+inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) {
+    *this = o;
+    return *this;
+}
+
+inline bool ConfigDescription::operator<(const ConfigDescription& o) const {
+    return compare(o) < 0;
+}
+
+inline bool ConfigDescription::operator<=(const ConfigDescription& o) const {
+    return compare(o) <= 0;
+}
+
+inline bool ConfigDescription::operator==(const ConfigDescription& o) const {
+    return compare(o) == 0;
+}
+
+inline bool ConfigDescription::operator!=(const ConfigDescription& o) const {
+    return compare(o) != 0;
+}
+
+inline bool ConfigDescription::operator>=(const ConfigDescription& o) const {
+    return compare(o) >= 0;
+}
+
+inline bool ConfigDescription::operator>(const ConfigDescription& o) const {
+    return compare(o) > 0;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const ConfigDescription& o) {
+    return out << o.toString().string();
+}
+
+} // namespace aapt
+
+#endif // AAPT_CONFIG_DESCRIPTION_H
diff --git a/tools/aapt2/ConfigDescription_test.cpp b/tools/aapt2/ConfigDescription_test.cpp
new file mode 100644
index 0000000..c57e351
--- /dev/null
+++ b/tools/aapt2/ConfigDescription_test.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 "ConfigDescription.h"
+#include "StringPiece.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+namespace aapt {
+
+static ::testing::AssertionResult TestParse(const StringPiece& input,
+                                            ConfigDescription* config = nullptr) {
+    if (ConfigDescription::parse(input, config)) {
+        return ::testing::AssertionSuccess() << input << " was successfully parsed";
+    }
+    return ::testing::AssertionFailure() << input << " could not be parsed";
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreOutOfOrder) {
+    EXPECT_FALSE(TestParse("en-sw600dp-ldrtl"));
+    EXPECT_FALSE(TestParse("land-en"));
+    EXPECT_FALSE(TestParse("hdpi-320dpi"));
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersAreNotMatched) {
+    EXPECT_FALSE(TestParse("en-sw600dp-ILLEGAL"));
+}
+
+TEST(ConfigDescriptionTest, ParseFailWhenQualifiersHaveTrailingDash) {
+    EXPECT_FALSE(TestParse("en-sw600dp-land-"));
+}
+
+TEST(ConfigDescriptionTest, ParseBasicQualifiers) {
+    ConfigDescription config;
+    EXPECT_TRUE(TestParse("", &config));
+    EXPECT_EQ(std::string(""), config.toString().string());
+
+    EXPECT_TRUE(TestParse("fr-land", &config));
+    EXPECT_EQ(std::string("fr-land"), config.toString().string());
+
+    EXPECT_TRUE(TestParse("mcc310-pl-sw720dp-normal-long-port-night-"
+                "xhdpi-keyssoft-qwerty-navexposed-nonav", &config));
+    EXPECT_EQ(std::string("mcc310-pl-sw720dp-normal-long-port-night-"
+                "xhdpi-keyssoft-qwerty-navexposed-nonav-v13"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseLocales) {
+    ConfigDescription config;
+    EXPECT_TRUE(TestParse("en-rUS", &config));
+    EXPECT_EQ(std::string("en-rUS"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseQualifierAddedInApi13) {
+    ConfigDescription config;
+    EXPECT_TRUE(TestParse("sw600dp", &config));
+    EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+
+    EXPECT_TRUE(TestParse("sw600dp-v8", &config));
+    EXPECT_EQ(std::string("sw600dp-v13"), config.toString().string());
+}
+
+TEST(ConfigDescriptionTest, ParseCarAttribute) {
+    ConfigDescription config;
+    EXPECT_TRUE(TestParse("car", &config));
+    EXPECT_EQ(android::ResTable_config::UI_MODE_TYPE_CAR, config.uiMode);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Files.cpp b/tools/aapt2/Files.cpp
new file mode 100644
index 0000000..c910c81
--- /dev/null
+++ b/tools/aapt2/Files.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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 "Files.h"
+#include "Util.h"
+
+#include <cerrno>
+#include <dirent.h>
+#include <string>
+#include <sys/stat.h>
+
+namespace aapt {
+
+FileType getFileType(const StringPiece& path) {
+    struct stat sb;
+    if (stat(path.data(), &sb) < 0) {
+        if (errno == ENOENT || errno == ENOTDIR) {
+            return FileType::kNonexistant;
+        }
+        return FileType::kUnknown;
+    }
+
+    if (S_ISREG(sb.st_mode)) {
+        return FileType::kRegular;
+    } else if (S_ISDIR(sb.st_mode)) {
+        return FileType::kDirectory;
+    } else if (S_ISCHR(sb.st_mode)) {
+        return FileType::kCharDev;
+    } else if (S_ISBLK(sb.st_mode)) {
+        return FileType::kBlockDev;
+    } else if (S_ISFIFO(sb.st_mode)) {
+        return FileType::kFifo;
+    } else if (S_ISLNK(sb.st_mode)) {
+        return FileType::kSymlink;
+    } else if (S_ISSOCK(sb.st_mode)) {
+        return FileType::kSocket;
+    } else {
+        return FileType::kUnknown;
+    }
+}
+
+std::vector<std::string> listFiles(const StringPiece& root) {
+    DIR* dir = opendir(root.data());
+    if (dir == nullptr) {
+        Logger::error(Source{ root.toString() })
+            << "unable to open file: "
+            << strerror(errno)
+            << "."
+            << std::endl;
+        return {};
+    }
+
+    std::vector<std::string> files;
+    dirent* entry;
+    while ((entry = readdir(dir))) {
+        files.emplace_back(entry->d_name);
+    }
+
+    closedir(dir);
+    return files;
+}
+
+inline static int mkdirImpl(const StringPiece& path) {
+#ifdef HAVE_MS_C_RUNTIME
+    return _mkdir(path.toString().c_str());
+#else
+    return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+#endif
+}
+
+bool mkdirs(const StringPiece& path) {
+    const char* start = path.begin();
+    const char* end = path.end();
+    for (const char* current = start; current != end; ++current) {
+        if (*current == sDirSep) {
+            StringPiece parentPath(start, current - start);
+            int result = mkdirImpl(parentPath);
+            if (result < 0 && errno != EEXIST) {
+                return false;
+            }
+        }
+    }
+    return mkdirImpl(path) == 0 || errno == EEXIST;
+}
+
+bool FileFilter::setPattern(const StringPiece& pattern) {
+    mPatternTokens = util::splitAndLowercase(pattern, ':');
+    return true;
+}
+
+bool FileFilter::operator()(const std::string& filename, FileType type) const {
+    if (filename == "." || filename == "..") {
+        return false;
+    }
+
+    const char kDir[] = "dir";
+    const char kFile[] = "file";
+    const size_t filenameLen = filename.length();
+    bool chatty = true;
+    for (const std::string& token : mPatternTokens) {
+        const char* tokenStr = token.c_str();
+        if (*tokenStr == '!') {
+            chatty = false;
+            tokenStr++;
+        }
+
+        if (strncasecmp(tokenStr, kDir, sizeof(kDir)) == 0) {
+            if (type != FileType::kDirectory) {
+                continue;
+            }
+            tokenStr += sizeof(kDir);
+        }
+
+        if (strncasecmp(tokenStr, kFile, sizeof(kFile)) == 0) {
+            if (type != FileType::kRegular) {
+                continue;
+            }
+            tokenStr += sizeof(kFile);
+        }
+
+        bool ignore = false;
+        size_t n = strlen(tokenStr);
+        if (*tokenStr == '*') {
+            // Math suffix.
+            tokenStr++;
+            n--;
+            if (n <= filenameLen) {
+                ignore = strncasecmp(tokenStr, filename.c_str() + filenameLen - n, n) == 0;
+            }
+        } else if (n > 1 && tokenStr[n - 1] == '*') {
+            // Match prefix.
+            ignore = strncasecmp(tokenStr, filename.c_str(), n - 1) == 0;
+        } else {
+            ignore = strcasecmp(tokenStr, filename.c_str()) == 0;
+        }
+
+        if (ignore) {
+            if (chatty) {
+                Logger::warn()
+                    << "skipping " <<
+                    (type == FileType::kDirectory ? "dir '" : "file '")
+                    << filename
+                    << "' due to ignore pattern '"
+                    << token
+                    << "'."
+                    << std::endl;
+            }
+            return false;
+        }
+    }
+    return true;
+}
+
+
+} // namespace aapt
diff --git a/tools/aapt2/Files.h b/tools/aapt2/Files.h
new file mode 100644
index 0000000..e5e196e
--- /dev/null
+++ b/tools/aapt2/Files.h
@@ -0,0 +1,122 @@
+/*
+ * 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_FILES_H
+#define AAPT_FILES_H
+
+#include "Logger.h"
+#include "Source.h"
+#include "StringPiece.h"
+
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+#ifdef _WIN32
+constexpr const char sDirSep = '\\';
+#else
+constexpr const char sDirSep = '/';
+#endif
+
+enum class FileType {
+    kUnknown = 0,
+    kNonexistant,
+    kRegular,
+    kDirectory,
+    kCharDev,
+    kBlockDev,
+    kFifo,
+    kSymlink,
+    kSocket,
+};
+
+FileType getFileType(const StringPiece& path);
+
+/*
+ * Lists files under the directory `root`. Files are listed
+ * with just their leaf (filename) names.
+ */
+std::vector<std::string> listFiles(const StringPiece& root);
+
+/*
+ * Appends a path to `base`, separated by the directory separator.
+ */
+void appendPath(std::string* base, const StringPiece& part);
+
+/*
+ * Appends a series of paths to `base`, separated by the
+ * system directory separator.
+ */
+template <typename... Ts >
+void appendPath(std::string* base, const StringPiece& part, const Ts&... parts);
+
+/*
+ * Makes all the directories in `path`. The last element in the path
+ * is interpreted as a directory.
+ */
+bool mkdirs(const StringPiece& path);
+
+/*
+ * Filter that determines which resource files/directories are
+ * processed by AAPT. Takes a pattern string supplied by the user.
+ * Pattern format is specified in the
+ * FileFilter::setPattern(const std::string&) method.
+ */
+class FileFilter {
+public:
+    /*
+     * Patterns syntax:
+     * - Delimiter is :
+     * - Entry can start with the flag ! to avoid printing a warning
+     *   about the file being ignored.
+     * - Entry can have the flag "<dir>" to match only directories
+     *   or <file> to match only files. Default is to match both.
+     * - Entry can be a simplified glob "<prefix>*" or "*<suffix>"
+     *   where prefix/suffix must have at least 1 character (so that
+     *   we don't match a '*' catch-all pattern.)
+     * - The special filenames "." and ".." are always ignored.
+     * - Otherwise the full string is matched.
+     * - match is not case-sensitive.
+     */
+    bool setPattern(const StringPiece& pattern);
+
+    /**
+     * Applies the filter, returning true for pass, false for fail.
+     */
+    bool operator()(const std::string& filename, FileType type) const;
+
+private:
+    std::vector<std::string> mPatternTokens;
+};
+
+inline void appendPath(std::string* base, const StringPiece& part) {
+    assert(base);
+    *base += sDirSep;
+    base->append(part.data(), part.size());
+}
+
+template <typename... Ts >
+void appendPath(std::string* base, const StringPiece& part, const Ts&... parts) {
+    assert(base);
+    *base += sDirSep;
+    base->append(part.data(), part.size());
+    appendPath(base, parts...);
+}
+
+} // namespace aapt
+
+#endif // AAPT_FILES_H
diff --git a/tools/aapt2/JavaClassGenerator.cpp b/tools/aapt2/JavaClassGenerator.cpp
new file mode 100644
index 0000000..7ec2848
--- /dev/null
+++ b/tools/aapt2/JavaClassGenerator.cpp
@@ -0,0 +1,189 @@
+/*
+ * 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 "JavaClassGenerator.h"
+#include "Resource.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "StringPiece.h"
+
+#include <ostream>
+#include <set>
+#include <sstream>
+#include <tuple>
+
+namespace aapt {
+
+// The number of attributes to emit per line in a Styleable array.
+constexpr size_t kAttribsPerLine = 4;
+
+JavaClassGenerator::JavaClassGenerator(std::shared_ptr<const ResourceTable> table,
+                                       Options options) :
+        mTable(table), mOptions(options) {
+}
+
+static void generateHeader(std::ostream& out, const StringPiece16& package) {
+    out << "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"
+           " *\n"
+           " * This class was automatically generated by the\n"
+           " * aapt tool from the resource data it found. It\n"
+           " * should not be modified by hand.\n"
+           " */\n\n";
+    out << "package " << package << ";"
+        << std::endl
+        << std::endl;
+}
+
+static const std::set<StringPiece16> sJavaIdentifiers = {
+    u"abstract", u"assert", u"boolean", u"break", u"byte",
+    u"case", u"catch", u"char", u"class", u"const", u"continue",
+    u"default", u"do", u"double", u"else", u"enum", u"extends",
+    u"final", u"finally", u"float", u"for", u"goto", u"if",
+    u"implements", u"import", u"instanceof", u"int", u"interface",
+    u"long", u"native", u"new", u"package", u"private", u"protected",
+    u"public", u"return", u"short", u"static", u"strictfp", u"super",
+    u"switch", u"synchronized", u"this", u"throw", u"throws",
+    u"transient", u"try", u"void", u"volatile", u"while", u"true",
+    u"false", u"null"
+};
+
+static bool isValidSymbol(const StringPiece16& symbol) {
+    return sJavaIdentifiers.find(symbol) == sJavaIdentifiers.end();
+}
+
+/*
+ * Java symbols can not contain . or -, but those are valid in a resource name.
+ * Replace those with '_'.
+ */
+static std::u16string transform(const StringPiece16& symbol) {
+    std::u16string output = symbol.toString();
+    for (char16_t& c : output) {
+        if (c == u'.' || c == u'-') {
+            c = u'_';
+        }
+    }
+    return output;
+}
+
+bool JavaClassGenerator::generateType(std::ostream& out, const ResourceTableType& type,
+                                      size_t packageId) {
+    const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
+
+    for (const auto& entry : type.entries) {
+        ResourceId id = { packageId, type.typeId, entry->entryId };
+        assert(id.isValid());
+
+        if (!isValidSymbol(entry->name)) {
+            mError = (std::stringstream()
+                    << "invalid symbol name '"
+                    << StringPiece16(entry->name)
+                    << "'").str();
+            return false;
+        }
+
+        out << "        "
+            << "public static" << finalModifier
+            << " int " << transform(entry->name) << " = " << id << ";" << std::endl;
+    }
+    return true;
+}
+
+struct GenArgs : ValueVisitorArgs {
+    GenArgs(std::ostream& o, const ResourceEntry& e) : out(o), entry(e) {
+    }
+
+    std::ostream& out;
+    const ResourceEntry& entry;
+};
+
+void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a) {
+    const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
+    std::ostream& out = static_cast<GenArgs&>(a).out;
+    const ResourceEntry& entry = static_cast<GenArgs&>(a).entry;
+
+    // This must be sorted by resource ID.
+    std::vector<std::pair<ResourceId, StringPiece16>> sortedAttributes;
+    sortedAttributes.reserve(styleable.entries.size());
+    for (const auto& attr : styleable.entries) {
+        assert(attr.id.isValid() && "no ID set for Styleable entry");
+        assert(attr.name.isValid() && "no name set for Styleable entry");
+        sortedAttributes.emplace_back(attr.id, attr.name.entry);
+    }
+    std::sort(sortedAttributes.begin(), sortedAttributes.end());
+
+    // First we emit the array containing the IDs of each attribute.
+    out << "        "
+        << "public static final int[] " << transform(entry.name) << " = {";
+
+    const size_t attrCount = sortedAttributes.size();
+    for (size_t i = 0; i < attrCount; i++) {
+        if (i % kAttribsPerLine == 0) {
+            out << std::endl << "            ";
+        }
+
+        out << sortedAttributes[i].first;
+        if (i != attrCount - 1) {
+            out << ", ";
+        }
+    }
+    out << std::endl << "        };" << std::endl;
+
+    // Now we emit the indices into the array.
+    for (size_t i = 0; i < attrCount; i++) {
+        out << "        "
+            << "public static" << finalModifier
+            << " int " << transform(entry.name) << "_" << transform(sortedAttributes[i].second)
+            << " = " << i << ";" << std::endl;
+    }
+}
+
+bool JavaClassGenerator::generate(std::ostream& out) {
+    const size_t packageId = mTable->getPackageId();
+
+    generateHeader(out, mTable->getPackage());
+
+    out << "public final class R {" << std::endl;
+
+    for (const auto& type : *mTable) {
+        out << "    public static final class " << type->type << " {" << std::endl;
+        bool result;
+        if (type->type == ResourceType::kStyleable) {
+            for (const auto& entry : type->entries) {
+                assert(!entry->values.empty());
+                if (!isValidSymbol(entry->name)) {
+                    mError = (std::stringstream()
+                            << "invalid symbol name '"
+                            << StringPiece16(entry->name)
+                            << "'").str();
+                    return false;
+                }
+                entry->values.front().value->accept(*this, GenArgs{ out, *entry });
+            }
+        } else {
+            result = generateType(out, *type, packageId);
+        }
+
+        if (!result) {
+            return false;
+        }
+        out << "    }" << std::endl;
+    }
+
+    out << "}" << std::endl;
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/JavaClassGenerator.h b/tools/aapt2/JavaClassGenerator.h
new file mode 100644
index 0000000..5b8e500
--- /dev/null
+++ b/tools/aapt2/JavaClassGenerator.h
@@ -0,0 +1,72 @@
+/*
+ * 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_JAVA_CLASS_GENERATOR_H
+#define AAPT_JAVA_CLASS_GENERATOR_H
+
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+
+#include <ostream>
+#include <string>
+
+namespace aapt {
+
+/*
+ * Generates the R.java file for a resource table.
+ */
+class JavaClassGenerator : ConstValueVisitor {
+public:
+    /*
+     * A set of options for this JavaClassGenerator.
+     */
+    struct Options {
+        /*
+         * Specifies whether to use the 'final' modifier
+         * on resource entries. Default is true.
+         */
+        bool useFinal = true;
+    };
+
+    JavaClassGenerator(std::shared_ptr<const ResourceTable> table, Options options);
+
+    /*
+     * Writes the R.java file to `out`. Returns true on success.
+     */
+    bool generate(std::ostream& out);
+
+    /*
+     * ConstValueVisitor implementation.
+     */
+    void visit(const Styleable& styleable, ValueVisitorArgs& args);
+
+    const std::string& getError() const;
+
+private:
+    bool generateType(std::ostream& out, const ResourceTableType& type, size_t packageId);
+
+    std::shared_ptr<const ResourceTable> mTable;
+    Options mOptions;
+    std::string mError;
+};
+
+inline const std::string& JavaClassGenerator::getError() const {
+    return mError;
+}
+
+} // namespace aapt
+
+#endif // AAPT_JAVA_CLASS_GENERATOR_H
diff --git a/tools/aapt2/JavaClassGenerator_test.cpp b/tools/aapt2/JavaClassGenerator_test.cpp
new file mode 100644
index 0000000..32050e3
--- /dev/null
+++ b/tools/aapt2/JavaClassGenerator_test.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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 "JavaClassGenerator.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+struct JavaClassGeneratorTest : public ::testing::Test {
+    virtual void SetUp() override {
+        mTable = std::make_shared<ResourceTable>();
+        mTable->setPackage(u"android");
+        mTable->setPackageId(0x01);
+    }
+
+    bool addResource(const ResourceNameRef& name, ResourceId id) {
+        return mTable->addResource(name, id, {}, SourceLine{ "test.xml", 21 },
+                                   util::make_unique<Id>());
+    }
+
+    std::shared_ptr<ResourceTable> mTable;
+};
+
+TEST_F(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) {
+    ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kId, u"class" },
+                            ResourceId{ 0x01, 0x02, 0x0000 }));
+
+    JavaClassGenerator generator(mTable, {});
+
+    std::stringstream out;
+    EXPECT_FALSE(generator.generate(out));
+}
+
+TEST_F(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) {
+    ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kId, u"hey-man" },
+                            ResourceId{ 0x01, 0x02, 0x0000 }));
+
+    ASSERT_TRUE(addResource(ResourceName{ {}, ResourceType::kAttr, u"cool.attr" },
+                            ResourceId{ 0x01, 0x01, 0x0000 }));
+
+    std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
+    Reference ref(ResourceName{ u"android", ResourceType::kAttr, u"cool.attr"});
+    ref.id = ResourceId{ 0x01, 0x01, 0x0000 };
+    styleable->entries.emplace_back(ref);
+
+    ASSERT_TRUE(mTable->addResource(ResourceName{ {}, ResourceType::kStyleable, u"hey.dude" },
+                                    ResourceId{ 0x01, 0x03, 0x0000 }, {},
+                                    SourceLine{ "test.xml", 21 }, std::move(styleable)));
+
+    JavaClassGenerator generator(mTable, {});
+
+    std::stringstream out;
+    EXPECT_TRUE(generator.generate(out));
+    std::string output = out.str();
+
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int hey_man = 0x01020000;"));
+
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int[] hey_dude = {"));
+
+    EXPECT_NE(std::string::npos,
+              output.find("public static final int hey_dude_cool_attr = 0;"));
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Linker.cpp b/tools/aapt2/Linker.cpp
new file mode 100644
index 0000000..a863197
--- /dev/null
+++ b/tools/aapt2/Linker.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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 "Linker.h"
+#include "Logger.h"
+#include "ResourceParser.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "StringPiece.h"
+#include "Util.h"
+
+#include <androidfw/AssetManager.h>
+#include <array>
+#include <iostream>
+#include <map>
+#include <ostream>
+#include <set>
+#include <sstream>
+#include <tuple>
+#include <vector>
+
+namespace aapt {
+
+Linker::Args::Args(const ResourceNameRef& r, const SourceLine& s) : referrer(r), source(s) {
+}
+
+Linker::Linker(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver) :
+        mTable(table), mResolver(resolver), mError(false) {
+}
+
+bool Linker::linkAndValidate() {
+    std::bitset<256> usedTypeIds;
+    std::array<std::set<uint16_t>, 256> usedIds;
+    usedTypeIds.set(0);
+
+    // First build the graph of references.
+    for (auto& type : *mTable) {
+        if (type->typeId != ResourceTableType::kUnsetTypeId) {
+            // The ID for this type has already been set. We
+            // mark this ID as taken so we don't re-assign it
+            // later.
+            usedTypeIds.set(type->typeId);
+        }
+
+        for (auto& entry : type->entries) {
+            if (type->typeId != ResourceTableType::kUnsetTypeId &&
+                    entry->entryId != ResourceEntry::kUnsetEntryId) {
+                // The ID for this entry has already been set. We
+                // mark this ID as taken so we don't re-assign it
+                // later.
+                usedIds[type->typeId].insert(entry->entryId);
+            }
+
+            for (auto& valueConfig : entry->values) {
+                // Dispatch to the right method of this linker
+                // based on the value's type.
+                valueConfig.value->accept(*this, Args{
+                        ResourceNameRef{ mTable->getPackage(), type->type, entry->name },
+                        valueConfig.source
+                });
+            }
+        }
+    }
+
+    /*
+     * Assign resource IDs that are available.
+     */
+    size_t nextTypeIndex = 0;
+    for (auto& type : *mTable) {
+        if (type->typeId == ResourceTableType::kUnsetTypeId) {
+            while (nextTypeIndex < usedTypeIds.size() && usedTypeIds[nextTypeIndex]) {
+                nextTypeIndex++;
+            }
+            type->typeId = nextTypeIndex++;
+        }
+
+        const auto endEntryIter = std::end(usedIds[type->typeId]);
+        auto nextEntryIter = std::begin(usedIds[type->typeId]);
+        size_t nextIndex = 0;
+        for (auto& entry : type->entries) {
+            if (entry->entryId == ResourceTableType::kUnsetTypeId) {
+                while (nextEntryIter != endEntryIter &&
+                        nextIndex == *nextEntryIter) {
+                    nextIndex++;
+                    ++nextEntryIter;
+                }
+                entry->entryId = nextIndex++;
+
+                // Update callers of this resource with the right ID.
+                auto callersIter = mGraph.find(ResourceNameRef{
+                        mTable->getPackage(),
+                        type->type,
+                        entry->name
+                });
+
+                if (callersIter != std::end(mGraph)) {
+                    for (Node& caller : callersIter->second) {
+                        caller.reference->id = ResourceId(mTable->getPackageId(),
+                                                          type->typeId,
+                                                          entry->entryId);
+                    }
+                }
+            }
+        }
+    }
+
+    return !mError;
+}
+
+const Linker::ResourceNameToSourceMap& Linker::getUnresolvedReferences() const {
+    return mUnresolvedSymbols;
+}
+
+void Linker::visit(Reference& reference, ValueVisitorArgs& a) {
+    Args& args = static_cast<Args&>(a);
+
+    Maybe<ResourceId> result = mResolver->findId(reference.name);
+    if (!result) {
+        addUnresolvedSymbol(reference.name, args.source);
+        return;
+    }
+
+    const ResourceId& id = result.value();
+    if (id.isValid()) {
+        reference.id = id;
+    } else {
+        // We need to update the ID when it is set, so add it
+        // to the graph.
+        mGraph[reference.name].push_back(Node{
+                args.referrer,
+                args.source.path,
+                args.source.line,
+                &reference
+        });
+    }
+
+    // TODO(adamlesinski): Verify the referencedType is another reference
+    // or a compatible primitive.
+}
+
+void Linker::processAttributeValue(const ResourceNameRef& name, const SourceLine& source,
+        const Attribute& attr, std::unique_ptr<Item>& value) {
+    std::unique_ptr<Item> convertedValue;
+    visitFunc<RawString>(*value, [&](RawString& str) {
+        // This is a raw string, so check if it can be converted to anything.
+        // We can NOT swap value with the converted value in here, since
+        // we called through the original value.
+
+        auto onCreateReference = [&](const ResourceName& name) {
+            mTable->addResource(name, ConfigDescription{},
+                    source, util::make_unique<Id>());
+        };
+
+        convertedValue = ResourceParser::parseItemForAttribute(
+                *str.value, attr, mResolver->getDefaultPackage(),
+                onCreateReference);
+        if (!convertedValue && attr.typeMask & android::ResTable_map::TYPE_STRING) {
+            // Last effort is to parse as a string.
+            util::StringBuilder builder;
+            builder.append(*str.value);
+            if (builder) {
+                convertedValue = util::make_unique<String>(
+                        mTable->getValueStringPool().makeRef(builder.str()));
+            }
+        }
+    });
+
+    if (convertedValue) {
+        value = std::move(convertedValue);
+    }
+
+    // Process this new or old value (it can be a reference!).
+    value->accept(*this, Args{ name, source });
+
+    // Flatten the value to see what resource type it is.
+    android::Res_value resValue;
+    value->flatten(resValue);
+
+    // Always allow references.
+    const uint32_t typeMask = attr.typeMask | android::ResTable_map::TYPE_REFERENCE;
+    if (!(typeMask & ResourceParser::androidTypeToAttributeTypeMask(resValue.dataType))) {
+        Logger::error(source)
+                << *value
+                << " is not compatible with attribute "
+                << attr
+                << "."
+                << std::endl;
+        mError = true;
+    }
+}
+
+void Linker::visit(Style& style, ValueVisitorArgs& a) {
+    Args& args = static_cast<Args&>(a);
+
+    if (style.parent.name.isValid()) {
+        visit(style.parent, a);
+    }
+
+    for (Style::Entry& styleEntry : style.entries) {
+        Maybe<Resolver::Entry> result = mResolver->findAttribute(styleEntry.key.name);
+        if (!result || !result.value().attr) {
+            addUnresolvedSymbol(styleEntry.key.name, args.source);
+            continue;
+        }
+
+        const Resolver::Entry& entry = result.value();
+        if (entry.id.isValid()) {
+            styleEntry.key.id = entry.id;
+        } else {
+            // Create a dependency for the style on this attribute.
+            mGraph[styleEntry.key.name].push_back(Node{
+                    args.referrer,
+                    args.source.path,
+                    args.source.line,
+                    &styleEntry.key
+            });
+        }
+        processAttributeValue(args.referrer, args.source, *entry.attr, styleEntry.value);
+    }
+}
+
+void Linker::visit(Attribute& attr, ValueVisitorArgs& a) {
+    static constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM |
+            android::ResTable_map::TYPE_FLAGS;
+    if (attr.typeMask & kMask) {
+        for (auto& symbol : attr.symbols) {
+            visit(symbol.symbol, a);
+        }
+    }
+}
+
+void Linker::visit(Styleable& styleable, ValueVisitorArgs& a) {
+    for (auto& attrRef : styleable.entries) {
+        visit(attrRef, a);
+    }
+}
+
+void Linker::visit(Sentinel& sentinel, ValueVisitorArgs& a) {
+    Args& args = static_cast<Args&>(a);
+    addUnresolvedSymbol(args.referrer, args.source);
+}
+
+void Linker::visit(Array& array, ValueVisitorArgs& a) {
+    Args& args = static_cast<Args&>(a);
+
+    for (auto& item : array.items) {
+        item->accept(*this, Args{ args.referrer, args.source });
+    }
+}
+
+void Linker::visit(Plural& plural, ValueVisitorArgs& a) {
+    Args& args = static_cast<Args&>(a);
+
+    for (auto& item : plural.values) {
+        if (item) {
+            item->accept(*this, Args{ args.referrer, args.source });
+        }
+    }
+}
+
+void Linker::addUnresolvedSymbol(const ResourceNameRef& name, const SourceLine& source) {
+    mUnresolvedSymbols[name.toResourceName()].push_back(source);
+}
+
+::std::ostream& operator<<(::std::ostream& out, const Linker::Node& node) {
+    return out << node.name << "(" << node.source << ":" << node.line << ")";
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Linker.h b/tools/aapt2/Linker.h
new file mode 100644
index 0000000..9b911b7
--- /dev/null
+++ b/tools/aapt2/Linker.h
@@ -0,0 +1,128 @@
+/*
+ * 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_LINKER_H
+#define AAPT_LINKER_H
+
+#include "Resolver.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Source.h"
+#include "StringPiece.h"
+
+#include <androidfw/AssetManager.h>
+#include <map>
+#include <memory>
+#include <ostream>
+#include <set>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * The Linker has two jobs. It follows resource references
+ * and verifies that their targert exists and that their
+ * types are compatible. The Linker will also assign resource
+ * IDs and fill in all the dependent references with the newly
+ * assigned resource IDs.
+ *
+ * To do this, the Linker builds a graph of references. This
+ * can be useful to do other analysis, like building a
+ * dependency graph of source files. The hope is to be able to
+ * add functionality that operates on the graph without
+ * overcomplicating the Linker.
+ *
+ * TODO(adamlesinski): Build the graph first then run the separate
+ * steps over the graph.
+ */
+class Linker : ValueVisitor {
+public:
+    /**
+     * Create a Linker for the given resource table with the sources available in
+     * Resolver. Resolver should contain the ResourceTable as a source too.
+     */
+    Linker(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver);
+
+    Linker(const Linker&) = delete;
+
+    /**
+     * Entry point to the linker. Assigns resource IDs, follows references,
+     * and validates types. Returns true if all references to defined values
+     * are type-compatible. Missing resource references are recorded but do
+     * not cause this method to fail.
+     */
+    bool linkAndValidate();
+
+    /**
+     * Returns any references to resources that were not defined in any of the
+     * sources.
+     */
+    using ResourceNameToSourceMap = std::map<ResourceName, std::vector<SourceLine>>;
+    const ResourceNameToSourceMap& getUnresolvedReferences() const;
+
+private:
+    struct Args : public ValueVisitorArgs {
+        Args(const ResourceNameRef& r, const SourceLine& s);
+
+        const ResourceNameRef& referrer;
+        const SourceLine& source;
+    };
+
+    //
+    // Overrides of ValueVisitor
+    //
+    void visit(Reference& reference, ValueVisitorArgs& args) override;
+    void visit(Attribute& attribute, ValueVisitorArgs& args) override;
+    void visit(Styleable& styleable, ValueVisitorArgs& args) override;
+    void visit(Style& style, ValueVisitorArgs& args) override;
+    void visit(Sentinel& sentinel, ValueVisitorArgs& args) override;
+    void visit(Array& array, ValueVisitorArgs& args) override;
+    void visit(Plural& plural, ValueVisitorArgs& args) override;
+
+    void processAttributeValue(const ResourceNameRef& name, const SourceLine& source,
+            const Attribute& attr, std::unique_ptr<Item>& value);
+
+    void addUnresolvedSymbol(const ResourceNameRef& name, const SourceLine& source);
+
+    /**
+     * Node of the resource table graph.
+     */
+    struct Node {
+        // We use ResourceNameRef and StringPiece, which are safe so long as the ResourceTable
+        // that defines the data isn't modified.
+        ResourceNameRef name;
+        StringPiece source;
+        size_t line;
+
+        // The reference object that points to name.
+        Reference* reference;
+
+        bool operator<(const Node& rhs) const;
+        bool operator==(const Node& rhs) const;
+        bool operator!=(const Node& rhs) const;
+    };
+    friend ::std::ostream& operator<<(::std::ostream&, const Node&);
+
+    std::shared_ptr<ResourceTable> mTable;
+    std::shared_ptr<Resolver> mResolver;
+    std::map<ResourceNameRef, std::vector<Node>> mGraph;
+    std::map<ResourceName, std::vector<SourceLine>> mUnresolvedSymbols;
+    bool mError;
+};
+
+} // namespace aapt
+
+#endif // AAPT_LINKER_H
diff --git a/tools/aapt2/Linker_test.cpp b/tools/aapt2/Linker_test.cpp
new file mode 100644
index 0000000..b1e201b
--- /dev/null
+++ b/tools/aapt2/Linker_test.cpp
@@ -0,0 +1,143 @@
+/*
+ * 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 "Linker.h"
+#include "Resolver.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <androidfw/AssetManager.h>
+#include <gtest/gtest.h>
+#include <string>
+
+namespace aapt {
+
+struct LinkerTest : public ::testing::Test {
+    virtual void SetUp() override {
+        mTable = std::make_shared<ResourceTable>();
+        mTable->setPackage(u"android");
+        mLinker = std::make_shared<Linker>(mTable, std::make_shared<Resolver>(
+                mTable, std::make_shared<android::AssetManager>()));
+
+        // Create a few attributes for use in the tests.
+
+        addResource(ResourceName{ {}, ResourceType::kAttr, u"integer" },
+                    util::make_unique<Attribute>(false, android::ResTable_map::TYPE_INTEGER));
+
+        addResource(ResourceName{ {}, ResourceType::kAttr, u"string" },
+                    util::make_unique<Attribute>(false, android::ResTable_map::TYPE_STRING));
+
+        addResource(ResourceName{ {}, ResourceType::kId, u"apple" }, util::make_unique<Id>());
+
+        addResource(ResourceName{ {}, ResourceType::kId, u"banana" }, util::make_unique<Id>());
+
+        std::unique_ptr<Attribute> flagAttr = util::make_unique<Attribute>(
+                false, android::ResTable_map::TYPE_FLAGS);
+        flagAttr->symbols.push_back(Attribute::Symbol{
+                ResourceNameRef{ u"android", ResourceType::kId, u"apple" }, 1 });
+        flagAttr->symbols.push_back(Attribute::Symbol{
+                ResourceNameRef{ u"android", ResourceType::kId, u"banana" }, 2 });
+        addResource(ResourceName{ {}, ResourceType::kAttr, u"flags" }, std::move(flagAttr));
+    }
+
+    /*
+     * Convenience method for adding resources with the default configuration and some
+     * bogus source line.
+     */
+    bool addResource(const ResourceNameRef& name, std::unique_ptr<Value> value) {
+        return mTable->addResource(name, {}, SourceLine{ "test.xml", 21 }, std::move(value));
+    }
+
+    std::shared_ptr<ResourceTable> mTable;
+    std::shared_ptr<Linker> mLinker;
+};
+
+TEST_F(LinkerTest, DoNotInterpretEscapedStringAsReference) {
+    ASSERT_TRUE(addResource(ResourceName{ u"android", ResourceType::kString, u"foo" },
+                util::make_unique<String>(mTable->getValueStringPool().makeRef(u"?123"))));
+
+    ASSERT_TRUE(mLinker->linkAndValidate());
+    EXPECT_TRUE(mLinker->getUnresolvedReferences().empty());
+}
+
+TEST_F(LinkerTest, EscapeAndConvertRawString) {
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+    style->entries.push_back(Style::Entry{
+            ResourceNameRef{ u"android", ResourceType::kAttr, u"integer" },
+            util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u"  123"))
+    });
+    const Style* result = style.get();
+    ASSERT_TRUE(addResource(ResourceName{ u"android", ResourceType::kStyle, u"foo" },
+                std::move(style)));
+
+    ASSERT_TRUE(mLinker->linkAndValidate());
+    EXPECT_TRUE(mLinker->getUnresolvedReferences().empty());
+
+    EXPECT_NE(nullptr, dynamic_cast<BinaryPrimitive*>(result->entries.front().value.get()));
+}
+
+TEST_F(LinkerTest, FailToConvertRawString) {
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+    style->entries.push_back(Style::Entry{
+            ResourceNameRef{ u"android", ResourceType::kAttr, u"integer" },
+            util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u"yo what is up?"))
+    });
+    ASSERT_TRUE(addResource(ResourceName{ u"android", ResourceType::kStyle, u"foo" },
+                std::move(style)));
+
+    ASSERT_FALSE(mLinker->linkAndValidate());
+}
+
+TEST_F(LinkerTest, ConvertRawStringToString) {
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+    style->entries.push_back(Style::Entry{
+            ResourceNameRef{ u"android", ResourceType::kAttr, u"string" },
+            util::make_unique<RawString>(
+                    mTable->getValueStringPool().makeRef(u"  \"this  is  \\u00fa\"."))
+    });
+    const Style* result = style.get();
+    ASSERT_TRUE(addResource(ResourceName{ u"android", ResourceType::kStyle, u"foo" },
+                std::move(style)));
+
+    ASSERT_TRUE(mLinker->linkAndValidate());
+    EXPECT_TRUE(mLinker->getUnresolvedReferences().empty());
+
+    const String* str = dynamic_cast<const String*>(result->entries.front().value.get());
+    ASSERT_NE(nullptr, str);
+    EXPECT_EQ(*str->value, u"this  is  \u00fa.");
+}
+
+TEST_F(LinkerTest, ConvertRawStringToFlags) {
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+    style->entries.push_back(Style::Entry{
+            ResourceNameRef{ u"android", ResourceType::kAttr, u"flags" },
+            util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u"banana | apple"))
+    });
+    const Style* result = style.get();
+    ASSERT_TRUE(addResource(ResourceName{ u"android", ResourceType::kStyle, u"foo" },
+                std::move(style)));
+
+    ASSERT_TRUE(mLinker->linkAndValidate());
+    EXPECT_TRUE(mLinker->getUnresolvedReferences().empty());
+
+    const BinaryPrimitive* bin = dynamic_cast<const BinaryPrimitive*>(
+            result->entries.front().value.get());
+    ASSERT_NE(nullptr, bin);
+    EXPECT_EQ(bin->value.data, 1u | 2u);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
new file mode 100644
index 0000000..eed0ea7
--- /dev/null
+++ b/tools/aapt2/Locale.cpp
@@ -0,0 +1,274 @@
+/*
+ * 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 "Locale.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <ctype.h>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+using android::ResTable_config;
+
+void LocaleValue::setLanguage(const char* languageChars) {
+     size_t i = 0;
+     while ((*languageChars) != '\0') {
+          language[i++] = ::tolower(*languageChars);
+          languageChars++;
+     }
+}
+
+void LocaleValue::setRegion(const char* regionChars) {
+    size_t i = 0;
+    while ((*regionChars) != '\0') {
+         region[i++] = ::toupper(*regionChars);
+         regionChars++;
+    }
+}
+
+void LocaleValue::setScript(const char* scriptChars) {
+    size_t i = 0;
+    while ((*scriptChars) != '\0') {
+         if (i == 0) {
+             script[i++] = ::toupper(*scriptChars);
+         } else {
+             script[i++] = ::tolower(*scriptChars);
+         }
+         scriptChars++;
+    }
+}
+
+void LocaleValue::setVariant(const char* variantChars) {
+     size_t i = 0;
+     while ((*variantChars) != '\0') {
+          variant[i++] = *variantChars;
+          variantChars++;
+     }
+}
+
+static inline bool isAlpha(const std::string& str) {
+    return std::all_of(std::begin(str), std::end(str), ::isalpha);
+}
+
+static inline bool isNumber(const std::string& str) {
+    return std::all_of(std::begin(str), std::end(str), ::isdigit);
+}
+
+bool LocaleValue::initFromFilterString(const std::string& str) {
+     // A locale (as specified in the filter) is an underscore separated name such
+     // as "en_US", "en_Latn_US", or "en_US_POSIX".
+     std::vector<std::string> parts = util::splitAndLowercase(str, '_');
+
+     const int numTags = parts.size();
+     bool valid = false;
+     if (numTags >= 1) {
+         const std::string& lang = parts[0];
+         if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) {
+             setLanguage(lang.c_str());
+             valid = true;
+         }
+     }
+
+     if (!valid || numTags == 1) {
+         return valid;
+     }
+
+     // At this point, valid == true && numTags > 1.
+     const std::string& part2 = parts[1];
+     if ((part2.length() == 2 && isAlpha(part2)) ||
+         (part2.length() == 3 && isNumber(part2))) {
+         setRegion(part2.c_str());
+     } else if (part2.length() == 4 && isAlpha(part2)) {
+         setScript(part2.c_str());
+     } else if (part2.length() >= 5 && part2.length() <= 8) {
+         setVariant(part2.c_str());
+     } else {
+         valid = false;
+     }
+
+     if (!valid || numTags == 2) {
+         return valid;
+     }
+
+     // At this point, valid == true && numTags > 1.
+     const std::string& part3 = parts[2];
+     if (((part3.length() == 2 && isAlpha(part3)) ||
+         (part3.length() == 3 && isNumber(part3))) && script[0]) {
+         setRegion(part3.c_str());
+     } else if (part3.length() >= 5 && part3.length() <= 8) {
+         setVariant(part3.c_str());
+     } else {
+         valid = false;
+     }
+
+     if (!valid || numTags == 3) {
+         return valid;
+     }
+
+     const std::string& part4 = parts[3];
+     if (part4.length() >= 5 && part4.length() <= 8) {
+         setVariant(part4.c_str());
+     } else {
+         valid = false;
+     }
+
+     if (!valid || numTags > 4) {
+         return false;
+     }
+
+     return true;
+}
+
+ssize_t LocaleValue::initFromParts(std::vector<std::string>::iterator iter,
+        std::vector<std::string>::iterator end) {
+    const std::vector<std::string>::iterator startIter = iter;
+
+    std::string& part = *iter;
+    if (part[0] == 'b' && part[1] == '+') {
+        // This is a "modified" BCP-47 language tag. Same semantics as BCP-47 tags,
+        // except that the separator is "+" and not "-".
+        std::vector<std::string> subtags = util::splitAndLowercase(part, '+');
+        subtags.erase(subtags.begin());
+        if (subtags.size() == 1) {
+            setLanguage(subtags[0].c_str());
+        } else if (subtags.size() == 2) {
+            setLanguage(subtags[0].c_str());
+
+            // The second tag can either be a region, a variant or a script.
+            switch (subtags[1].size()) {
+                case 2:
+                case 3:
+                    setRegion(subtags[1].c_str());
+                    break;
+                case 4:
+                    setScript(subtags[1].c_str());
+                    break;
+                case 5:
+                case 6:
+                case 7:
+                case 8:
+                    setVariant(subtags[1].c_str());
+                    break;
+                default:
+                    return -1;
+            }
+        } else if (subtags.size() == 3) {
+            // The language is always the first subtag.
+            setLanguage(subtags[0].c_str());
+
+            // The second subtag can either be a script or a region code.
+            // If its size is 4, it's a script code, else it's a region code.
+            if (subtags[1].size() == 4) {
+                setScript(subtags[1].c_str());
+            } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
+                setRegion(subtags[1].c_str());
+            } else {
+                return -1;
+            }
+
+            // The third tag can either be a region code (if the second tag was
+            // a script), else a variant code.
+            if (subtags[2].size() > 4) {
+                setVariant(subtags[2].c_str());
+            } else {
+                setRegion(subtags[2].c_str());
+            }
+        } else if (subtags.size() == 4) {
+            setLanguage(subtags[0].c_str());
+            setScript(subtags[1].c_str());
+            setRegion(subtags[2].c_str());
+            setVariant(subtags[3].c_str());
+        } else {
+            return -1;
+        }
+
+        ++iter;
+
+    } else {
+        if ((part.length() == 2 || part.length() == 3)
+                && isAlpha(part) && part != "car") {
+            setLanguage(part.c_str());
+            ++iter;
+
+            if (iter != end) {
+                const std::string& regionPart = *iter;
+                if (regionPart.c_str()[0] == 'r' && regionPart.length() == 3) {
+                    setRegion(regionPart.c_str() + 1);
+                    ++iter;
+                }
+            }
+        }
+    }
+
+    return static_cast<ssize_t>(iter - startIter);
+}
+
+
+std::string LocaleValue::toDirName() const {
+    std::string dirName;
+    if (language[0]) {
+        dirName += language;
+    } else {
+        return dirName;
+    }
+
+    if (script[0]) {
+        dirName += "-s";
+        dirName += script;
+    }
+
+    if (region[0]) {
+        dirName += "-r";
+        dirName += region;
+    }
+
+    if (variant[0]) {
+        dirName += "-v";
+        dirName += variant;
+    }
+
+    return dirName;
+}
+
+void LocaleValue::initFromResTable(const ResTable_config& config) {
+    config.unpackLanguage(language);
+    config.unpackRegion(region);
+    if (config.localeScript[0]) {
+        memcpy(script, config.localeScript, sizeof(config.localeScript));
+    }
+
+    if (config.localeVariant[0]) {
+        memcpy(variant, config.localeVariant, sizeof(config.localeVariant));
+    }
+}
+
+void LocaleValue::writeTo(ResTable_config* out) const {
+    out->packLanguage(language);
+    out->packRegion(region);
+
+    if (script[0]) {
+        memcpy(out->localeScript, script, sizeof(out->localeScript));
+    }
+
+    if (variant[0]) {
+        memcpy(out->localeVariant, variant, sizeof(out->localeVariant));
+    }
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Locale.h b/tools/aapt2/Locale.h
new file mode 100644
index 0000000..ceec764
--- /dev/null
+++ b/tools/aapt2/Locale.h
@@ -0,0 +1,114 @@
+/*
+ * 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_LOCALE_VALUE_H
+#define AAPT_LOCALE_VALUE_H
+
+#include <androidfw/ResourceTypes.h>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * A convenience class to build and parse locales.
+ */
+struct LocaleValue {
+    char language[4];
+    char region[4];
+    char script[4];
+    char variant[8];
+
+    inline LocaleValue();
+
+    /**
+     * Initialize this LocaleValue from a config string.
+     */
+    bool initFromFilterString(const std::string& config);
+
+    /**
+     * Initialize this LocaleValue from parts of a vector.
+     */
+    ssize_t initFromParts(std::vector<std::string>::iterator iter,
+            std::vector<std::string>::iterator end);
+
+    /**
+     * Initialize this LocaleValue from a ResTable_config.
+     */
+    void initFromResTable(const android::ResTable_config& config);
+
+    /**
+     * Set the locale in a ResTable_config from this LocaleValue.
+     */
+    void writeTo(android::ResTable_config* out) const;
+
+    std::string toDirName() const;
+
+    inline int compare(const LocaleValue& other) const;
+
+    inline bool operator<(const LocaleValue& o) const;
+    inline bool operator<=(const LocaleValue& o) const;
+    inline bool operator==(const LocaleValue& o) const;
+    inline bool operator!=(const LocaleValue& o) const;
+    inline bool operator>=(const LocaleValue& o) const;
+    inline bool operator>(const LocaleValue& o) const;
+
+private:
+     void setLanguage(const char* language);
+     void setRegion(const char* language);
+     void setScript(const char* script);
+     void setVariant(const char* variant);
+};
+
+//
+// Implementation
+//
+
+LocaleValue::LocaleValue() {
+    memset(this, 0, sizeof(LocaleValue));
+}
+
+int LocaleValue::compare(const LocaleValue& other) const {
+    return memcmp(this, &other, sizeof(LocaleValue));
+}
+
+bool LocaleValue::operator<(const LocaleValue& o) const {
+    return compare(o) < 0;
+}
+
+bool LocaleValue::operator<=(const LocaleValue& o) const {
+    return compare(o) <= 0;
+}
+
+bool LocaleValue::operator==(const LocaleValue& o) const {
+    return compare(o) == 0;
+}
+
+bool LocaleValue::operator!=(const LocaleValue& o) const {
+    return compare(o) != 0;
+}
+
+bool LocaleValue::operator>=(const LocaleValue& o) const {
+    return compare(o) >= 0;
+}
+
+bool LocaleValue::operator>(const LocaleValue& o) const {
+    return compare(o) > 0;
+}
+
+} // namespace aapt
+
+#endif // AAPT_LOCALE_VALUE_H
diff --git a/tools/aapt2/Locale_test.cpp b/tools/aapt2/Locale_test.cpp
new file mode 100644
index 0000000..4e154d6
--- /dev/null
+++ b/tools/aapt2/Locale_test.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 "Locale.h"
+#include "Util.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+namespace aapt {
+
+static ::testing::AssertionResult TestLanguage(const char* input, const char* lang) {
+    std::vector<std::string> parts = util::splitAndLowercase(std::string(input), '-');
+    LocaleValue lv;
+    ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts));
+    if (count < 0) {
+        return ::testing::AssertionFailure() << " failed to parse '" << input << "'.";
+    }
+
+    if (count != 1) {
+        return ::testing::AssertionFailure() << count
+            << " parts were consumed parsing '" << input << "' but expected 1.";
+    }
+
+    if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) != 0) {
+        return ::testing::AssertionFailure() << "expected " << lang << " but got "
+            << std::string(lv.language, sizeof(lv.language)) << ".";
+    }
+
+    return ::testing::AssertionSuccess();
+}
+
+static ::testing::AssertionResult TestLanguageRegion(const char* input, const char* lang,
+                                                     const char* region) {
+    std::vector<std::string> parts = util::splitAndLowercase(std::string(input), '-');
+    LocaleValue lv;
+    ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts));
+    if (count < 0) {
+        return ::testing::AssertionFailure() << " failed to parse '" << input << "'.";
+    }
+
+    if (count != 2) {
+        return ::testing::AssertionFailure() << count
+            << " parts were consumed parsing '" << input << "' but expected 2.";
+    }
+
+    if (memcmp(lv.language, lang, std::min(strlen(lang), sizeof(lv.language))) != 0) {
+        return ::testing::AssertionFailure() << "expected " << input << " but got "
+            << std::string(lv.language, sizeof(lv.language)) << ".";
+    }
+
+    if (memcmp(lv.region, region, std::min(strlen(region), sizeof(lv.region))) != 0) {
+        return ::testing::AssertionFailure() << "expected " << region << " but got "
+            << std::string(lv.region, sizeof(lv.region)) << ".";
+    }
+
+    return ::testing::AssertionSuccess();
+}
+
+TEST(ConfigDescriptionTest, ParseLanguage) {
+    EXPECT_TRUE(TestLanguage("en", "en"));
+    EXPECT_TRUE(TestLanguage("fr", "fr"));
+    EXPECT_FALSE(TestLanguage("land", ""));
+    EXPECT_TRUE(TestLanguage("fr-land", "fr"));
+
+    EXPECT_TRUE(TestLanguageRegion("fr-rCA", "fr", "CA"));
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Logger.cpp b/tools/aapt2/Logger.cpp
new file mode 100644
index 0000000..3847185
--- /dev/null
+++ b/tools/aapt2/Logger.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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 "Source.h"
+
+#include <memory>
+#include <iostream>
+
+namespace aapt {
+
+Log::Log(std::ostream& _out, std::ostream& _err) : out(_out), err(_err) {
+}
+
+std::shared_ptr<Log> Logger::sLog(std::make_shared<Log>(std::cerr, std::cerr));
+
+void Logger::setLog(const std::shared_ptr<Log>& log) {
+    sLog = log;
+}
+
+std::ostream& Logger::error() {
+    return sLog->err << "error: ";
+}
+
+std::ostream& Logger::error(const Source& source) {
+    return sLog->err << source << ": error: ";
+}
+
+std::ostream& Logger::error(const SourceLine& source) {
+    return sLog->err << source << ": error: ";
+}
+
+std::ostream& Logger::warn() {
+    return sLog->err << "warning: ";
+}
+
+std::ostream& Logger::warn(const Source& source) {
+    return sLog->err << source << ": warning: ";
+}
+
+std::ostream& Logger::warn(const SourceLine& source) {
+    return sLog->err << source << ": warning: ";
+}
+
+std::ostream& Logger::note() {
+    return sLog->out << "note: ";
+}
+
+std::ostream& Logger::note(const Source& source) {
+    return sLog->err << source << ": note: ";
+}
+
+std::ostream& Logger::note(const SourceLine& source) {
+    return sLog->err << source << ": note: ";
+}
+
+SourceLogger::SourceLogger(const Source& source)
+: mSource(source) {
+}
+
+std::ostream& SourceLogger::error() {
+    return Logger::error(mSource);
+}
+
+std::ostream& SourceLogger::error(size_t line) {
+    return Logger::error(SourceLine{ mSource.path, line });
+}
+
+std::ostream& SourceLogger::warn() {
+    return Logger::warn(mSource);
+}
+
+std::ostream& SourceLogger::warn(size_t line) {
+    return Logger::warn(SourceLine{ mSource.path, line });
+}
+
+std::ostream& SourceLogger::note() {
+    return Logger::note(mSource);
+}
+
+std::ostream& SourceLogger::note(size_t line) {
+    return Logger::note(SourceLine{ mSource.path, line });
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Logger.h b/tools/aapt2/Logger.h
new file mode 100644
index 0000000..1d437eb
--- /dev/null
+++ b/tools/aapt2/Logger.h
@@ -0,0 +1,81 @@
+/*
+ * 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_LOGGER_H
+#define AAPT_LOGGER_H
+
+#include "Source.h"
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utils/String8.h>
+
+namespace aapt {
+
+struct Log {
+    Log(std::ostream& out, std::ostream& err);
+    Log(const Log& rhs) = delete;
+
+    std::ostream& out;
+    std::ostream& err;
+};
+
+class Logger {
+public:
+    static void setLog(const std::shared_ptr<Log>& log);
+
+    static std::ostream& error();
+    static std::ostream& error(const Source& source);
+    static std::ostream& error(const SourceLine& sourceLine);
+
+    static std::ostream& warn();
+    static std::ostream& warn(const Source& source);
+    static std::ostream& warn(const SourceLine& sourceLine);
+
+    static std::ostream& note();
+    static std::ostream& note(const Source& source);
+    static std::ostream& note(const SourceLine& sourceLine);
+
+private:
+    static std::shared_ptr<Log> sLog;
+};
+
+class SourceLogger {
+public:
+    SourceLogger(const Source& source);
+
+    std::ostream& error();
+    std::ostream& error(size_t line);
+
+    std::ostream& warn();
+    std::ostream& warn(size_t line);
+
+    std::ostream& note();
+    std::ostream& note(size_t line);
+
+private:
+    Source mSource;
+};
+
+inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) {
+    android::String8 utf8(str.data(), str.size());
+    return out.write(utf8.string(), utf8.size());
+}
+
+} // namespace aapt
+
+#endif // AAPT_LOGGER_H
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
new file mode 100644
index 0000000..f4e80c5
--- /dev/null
+++ b/tools/aapt2/Main.cpp
@@ -0,0 +1,1421 @@
+/*
+ * 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 "AppInfo.h"
+#include "BigBuffer.h"
+#include "BinaryResourceParser.h"
+#include "Files.h"
+#include "JavaClassGenerator.h"
+#include "Linker.h"
+#include "ManifestParser.h"
+#include "ManifestValidator.h"
+#include "ResourceParser.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "SdkConstants.h"
+#include "SourceXmlPullParser.h"
+#include "StringPiece.h"
+#include "TableFlattener.h"
+#include "Util.h"
+#include "XmlFlattener.h"
+
+#include <algorithm>
+#include <androidfw/AssetManager.h>
+#include <cstdlib>
+#include <dirent.h>
+#include <errno.h>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <sys/stat.h>
+
+using namespace aapt;
+
+void printTable(const ResourceTable& table) {
+    std::cout << "ResourceTable package=" << table.getPackage();
+    if (table.getPackageId() != ResourceTable::kUnsetPackageId) {
+        std::cout << " id=" << std::hex << table.getPackageId() << std::dec;
+    }
+    std::cout << std::endl
+         << "---------------------------------------------------------" << std::endl;
+
+    for (const auto& type : table) {
+        std::cout << "Type " << type->type;
+        if (type->typeId != ResourceTableType::kUnsetTypeId) {
+            std::cout << " [" << type->typeId << "]";
+        }
+        std::cout << " (" << type->entries.size() << " entries)" << std::endl;
+        for (const auto& entry : type->entries) {
+            std::cout << "  " << entry->name;
+            if (entry->entryId != ResourceEntry::kUnsetEntryId) {
+                std::cout << " [" << entry->entryId << "]";
+            }
+            std::cout << " (" << entry->values.size() << " configurations)";
+            if (entry->publicStatus.isPublic) {
+                std::cout << " PUBLIC";
+            }
+            std::cout << std::endl;
+            for (const auto& value : entry->values) {
+                std::cout << "    " << value.config << " (" << value.source << ") : ";
+                value.value->print(std::cout);
+                std::cout << std::endl;
+            }
+        }
+    }
+}
+
+void printStringPool(const StringPool& pool) {
+    std::cout << "String pool of length " << pool.size() << std::endl
+         << "---------------------------------------------------------" << std::endl;
+
+    size_t i = 0;
+    for (const auto& entry : pool) {
+        std::cout << "[" << i << "]: "
+             << entry->value
+             << " (Priority " << entry->context.priority
+             << ", Config '" << entry->context.config << "')"
+             << std::endl;
+        i++;
+    }
+}
+
+std::unique_ptr<FileReference> makeFileReference(StringPool& pool, const StringPiece& filename,
+        ResourceType type, const ConfigDescription& config) {
+    std::stringstream path;
+    path << "res/" << type;
+    if (config != ConfigDescription{}) {
+        path << "-" << config;
+    }
+    path << "/" << filename;
+    return util::make_unique<FileReference>(pool.makeRef(util::utf8ToUtf16(path.str())));
+}
+
+/**
+ * Collect files from 'root', filtering out any files that do not
+ * match the FileFilter 'filter'.
+ */
+bool walkTree(const StringPiece& root, const FileFilter& filter,
+        std::vector<Source>& outEntries) {
+    bool error = false;
+
+    for (const std::string& dirName : listFiles(root)) {
+        std::string dir(root.toString());
+        appendPath(&dir, dirName);
+
+        FileType ft = getFileType(dir);
+        if (!filter(dirName, ft)) {
+            continue;
+        }
+
+        if (ft != FileType::kDirectory) {
+            continue;
+        }
+
+        for (const std::string& fileName : listFiles(dir)) {
+            std::string file(dir);
+            appendPath(&file, fileName);
+
+            FileType ft = getFileType(file);
+            if (!filter(fileName, ft)) {
+                continue;
+            }
+
+            if (ft != FileType::kRegular) {
+                Logger::error(Source{ file })
+                    << "not a regular file."
+                    << std::endl;
+                error = true;
+                continue;
+            }
+            outEntries.emplace_back(Source{ file });
+        }
+    }
+    return !error;
+}
+
+bool loadBinaryResourceTable(std::shared_ptr<ResourceTable> table, const Source& source) {
+    std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary);
+    if (!ifs) {
+        Logger::error(source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    std::streampos fsize = ifs.tellg();
+    ifs.seekg(0, std::ios::end);
+    fsize = ifs.tellg() - fsize;
+    ifs.seekg(0, std::ios::beg);
+
+    assert(fsize >= 0);
+    size_t dataSize = static_cast<size_t>(fsize);
+    char* buf = new char[dataSize];
+    ifs.read(buf, dataSize);
+
+    BinaryResourceParser parser(table, source, buf, dataSize);
+    bool result = parser.parse();
+
+    delete [] buf;
+    return result;
+}
+
+bool loadResTable(android::ResTable* table, const Source& source) {
+    std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary);
+    if (!ifs) {
+        Logger::error(source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    std::streampos fsize = ifs.tellg();
+    ifs.seekg(0, std::ios::end);
+    fsize = ifs.tellg() - fsize;
+    ifs.seekg(0, std::ios::beg);
+
+    assert(fsize >= 0);
+    size_t dataSize = static_cast<size_t>(fsize);
+    char* buf = new char[dataSize];
+    ifs.read(buf, dataSize);
+
+    bool result = table->add(buf, dataSize, -1, true) == android::NO_ERROR;
+
+    delete [] buf;
+    return result;
+}
+
+void versionStylesForCompat(std::shared_ptr<ResourceTable> table) {
+    for (auto& type : *table) {
+        if (type->type != ResourceType::kStyle) {
+            continue;
+        }
+
+        for (auto& entry : type->entries) {
+            // Add the versioned styles we want to create
+            // here. They are added to the table after
+            // iterating over the original set of styles.
+            //
+            // A stack is used since auto-generated styles
+            // from later versions should override
+            // auto-generated styles from earlier versions.
+            // Iterating over the styles is done in order,
+            // so we will always visit sdkVersions from smallest
+            // to largest.
+            std::stack<ResourceConfigValue> addStack;
+
+            for (ResourceConfigValue& configValue : entry->values) {
+                visitFunc<Style>(*configValue.value, [&](Style& style) {
+                    // Collect which entries we've stripped and the smallest
+                    // SDK level which was stripped.
+                    size_t minSdkStripped = std::numeric_limits<size_t>::max();
+                    std::vector<Style::Entry> stripped;
+
+                    // Iterate over the style's entries and erase/record the
+                    // attributes whose SDK level exceeds the config's sdkVersion.
+                    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);
+                            if (sdkLevel > 1 && sdkLevel > configValue.config.sdkVersion) {
+                                // Record that we are about to strip this.
+                                stripped.emplace_back(std::move(*iter));
+                                minSdkStripped = std::min(minSdkStripped, sdkLevel);
+
+                                // Erase this from this style.
+                                iter = style.entries.erase(iter);
+                                continue;
+                            }
+                        }
+                        ++iter;
+                    }
+
+                    if (!stripped.empty()) {
+                        // We have stripped attributes, so let's create a new style to hold them.
+                        ConfigDescription versionConfig(configValue.config);
+                        versionConfig.sdkVersion = minSdkStripped;
+
+                        ResourceConfigValue value = {
+                                versionConfig,
+                                configValue.source,
+                                {},
+
+                                // Create a copy of the original style.
+                                std::unique_ptr<Value>(configValue.value->clone())
+                        };
+
+                        Style& newStyle = static_cast<Style&>(*value.value);
+
+                        // Move the recorded stripped attributes into this new style.
+                        std::move(stripped.begin(), stripped.end(),
+                                  std::back_inserter(newStyle.entries));
+
+                        // We will add this style to the table later. If we do it now, we will
+                        // mess up iteration.
+                        addStack.push(std::move(value));
+                    }
+                });
+            }
+
+            auto comparator =
+                    [](const ResourceConfigValue& lhs, const ConfigDescription& rhs) -> bool {
+                        return lhs.config < rhs;
+                    };
+
+            while (!addStack.empty()) {
+                ResourceConfigValue& value = addStack.top();
+                auto iter = std::lower_bound(entry->values.begin(), entry->values.end(),
+                                             value.config, comparator);
+                if (iter == entry->values.end() || iter->config != value.config) {
+                    entry->values.insert(iter, std::move(value));
+                }
+                addStack.pop();
+            }
+        }
+    }
+}
+
+bool collectXml(std::shared_ptr<ResourceTable> table, const Source& source,
+                const ResourceName& name,
+                const ConfigDescription& config) {
+    std::ifstream in(source.path, std::ifstream::binary);
+    if (!in) {
+        Logger::error(source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    std::set<size_t> sdkLevels;
+
+    SourceXmlPullParser pullParser(in);
+    while (XmlPullParser::isGoodEvent(pullParser.next())) {
+        if (pullParser.getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        const auto endIter = pullParser.endAttributes();
+        for (auto iter = pullParser.beginAttributes(); iter != endIter; ++iter) {
+            if (iter->namespaceUri == u"http://schemas.android.com/apk/res/android") {
+                size_t sdkLevel = findAttributeSdkLevel(iter->name);
+                if (sdkLevel > 1) {
+                    sdkLevels.insert(sdkLevel);
+                }
+            }
+
+            ResourceNameRef refName;
+            bool create = false;
+            bool privateRef = false;
+            if (ResourceParser::tryParseReference(iter->value, &refName, &create, &privateRef) &&
+                    create) {
+                table->addResource(refName, {}, source.line(pullParser.getLineNumber()),
+                                   util::make_unique<Id>());
+            }
+        }
+    }
+
+    std::unique_ptr<FileReference> fileResource = makeFileReference(
+            table->getValueStringPool(),
+            util::utf16ToUtf8(name.entry) + ".xml",
+            name.type,
+            config);
+    table->addResource(name, config, source.line(0), std::move(fileResource));
+
+    for (size_t level : sdkLevels) {
+        Logger::note(source)
+                << "creating v" << level << " versioned file."
+                << std::endl;
+        ConfigDescription newConfig = config;
+        newConfig.sdkVersion = level;
+
+        std::unique_ptr<FileReference> fileResource = makeFileReference(
+                table->getValueStringPool(),
+                util::utf16ToUtf8(name.entry) + ".xml",
+                name.type,
+                newConfig);
+        table->addResource(name, newConfig, source.line(0), std::move(fileResource));
+    }
+    return true;
+}
+
+struct CompileXml {
+    Source source;
+    ResourceName name;
+    ConfigDescription config;
+};
+
+bool compileXml(std::shared_ptr<Resolver> resolver, const CompileXml& item,
+                const Source& outputSource, std::queue<CompileXml>* queue) {
+    std::ifstream in(item.source.path, std::ifstream::binary);
+    if (!in) {
+        Logger::error(item.source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    BigBuffer outBuffer(1024);
+    std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(in);
+    XmlFlattener flattener(resolver);
+
+    // We strip attributes that do not belong in this version of the resource.
+    // Non-version qualified resources have an implicit version 1 requirement.
+    XmlFlattener::Options options = { item.config.sdkVersion ? item.config.sdkVersion : 1 };
+    Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, xmlParser, &outBuffer, options);
+    if (!minStrippedSdk) {
+        return false;
+    }
+
+    if (minStrippedSdk.value() > 0) {
+        // Something was stripped, so let's generate a new file
+        // with the version of the smallest SDK version stripped.
+        CompileXml newWork = item;
+        newWork.config.sdkVersion = minStrippedSdk.value();
+        queue->push(newWork);
+    }
+
+    std::ofstream out(outputSource.path, std::ofstream::binary);
+    if (!out) {
+        Logger::error(outputSource) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    if (!util::writeAll(out, outBuffer)) {
+        Logger::error(outputSource) << strerror(errno) << std::endl;
+        return false;
+    }
+    return true;
+}
+
+struct AaptOptions {
+    enum class Phase {
+        LegacyFull,
+        Collect,
+        Link,
+        Compile,
+    };
+
+    // The phase to process.
+    Phase phase;
+
+    // Details about the app.
+    AppInfo appInfo;
+
+    // The location of the manifest file.
+    Source manifest;
+
+    // The files to process.
+    std::vector<Source> sources;
+
+    // The libraries these files may reference.
+    std::vector<Source> libraries;
+
+    // Output directory.
+    Source output;
+
+    // Whether to generate a Java Class.
+    Maybe<Source> generateJavaClass;
+
+    // Whether to output verbose details about
+    // compilation.
+    bool verbose = false;
+};
+
+bool compileAndroidManifest(std::shared_ptr<Resolver> resolver, const AaptOptions& options) {
+    Source outSource = options.output;
+    appendPath(&outSource.path, "AndroidManifest.xml");
+
+    if (options.verbose) {
+        Logger::note(outSource) << "compiling AndroidManifest.xml." << std::endl;
+    }
+
+    std::ifstream in(options.manifest.path, std::ifstream::binary);
+    if (!in) {
+        Logger::error(options.manifest) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    BigBuffer outBuffer(1024);
+    std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(in);
+    XmlFlattener flattener(resolver);
+
+    Maybe<size_t> result = flattener.flatten(options.manifest, xmlParser, &outBuffer,
+                                             XmlFlattener::Options{});
+    if (!result) {
+        return false;
+    }
+
+    std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[outBuffer.size()]);
+    uint8_t* p = data.get();
+    for (const auto& b : outBuffer) {
+        memcpy(p, b.buffer.get(), b.size);
+        p += b.size;
+    }
+
+    android::ResXMLTree tree;
+    if (tree.setTo(data.get(), outBuffer.size()) != android::NO_ERROR) {
+        return false;
+    }
+
+    ManifestValidator validator(resolver->getResTable());
+    if (!validator.validate(options.manifest, &tree)) {
+        return false;
+    }
+
+    std::ofstream out(outSource.path, std::ofstream::binary);
+    if (!out) {
+        Logger::error(outSource) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    if (!util::writeAll(out, outBuffer)) {
+        Logger::error(outSource) << strerror(errno) << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool loadAppInfo(const Source& source, AppInfo* outInfo) {
+    std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary);
+    if (!ifs) {
+        Logger::error(source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    ManifestParser parser;
+    std::shared_ptr<XmlPullParser> pullParser = std::make_shared<SourceXmlPullParser>(ifs);
+    return parser.parse(source, pullParser, outInfo);
+}
+
+/**
+ * Parses legacy options and walks the source directories collecting
+ * files to process.
+ */
+bool prepareLegacy(std::vector<StringPiece>::const_iterator argsIter,
+        const std::vector<StringPiece>::const_iterator argsEndIter,
+        AaptOptions &options) {
+    options.phase = AaptOptions::Phase::LegacyFull;
+
+    std::vector<StringPiece> sourceDirs;
+    while (argsIter != argsEndIter) {
+        if (*argsIter == "-S") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-S missing argument." << std::endl;
+                return false;
+            }
+            sourceDirs.push_back(*argsIter);
+        } else if (*argsIter == "-I") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-I missing argument." << std::endl;
+                return false;
+            }
+            options.libraries.push_back(Source{ argsIter->toString() });
+        } else if (*argsIter == "-M") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-M missing argument." << std::endl;
+                return false;
+            }
+
+            if (!options.manifest.path.empty()) {
+                Logger::error() << "multiple -M flags are not allowed." << std::endl;
+                return false;
+            }
+            options.manifest.path = argsIter->toString();
+        } else if (*argsIter == "-o") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-o missing argument." << std::endl;
+                return false;
+            }
+            options.output = Source{ argsIter->toString() };
+        } else if (*argsIter == "-J") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-J missing argument." << std::endl;
+                return false;
+            }
+            options.generateJavaClass = make_value<Source>(Source{ argsIter->toString() });
+        } else if (*argsIter == "-v") {
+            options.verbose = true;
+        } else {
+            Logger::error() << "unrecognized option '" << *argsIter << "'." << std::endl;
+            return false;
+        }
+
+        ++argsIter;
+    }
+
+    if (options.manifest.path.empty()) {
+        Logger::error() << "must specify manifest file with -M." << std::endl;
+        return false;
+    }
+
+    // Load the App's package name, etc.
+    if (!loadAppInfo(options.manifest, &options.appInfo)) {
+        return false;
+    }
+
+    /**
+     * Set up the file filter to ignore certain files.
+     */
+    const char* customIgnore = getenv("ANDROID_AAPT_IGNORE");
+    FileFilter fileFilter;
+    if (customIgnore && customIgnore[0]) {
+        fileFilter.setPattern(customIgnore);
+    } else {
+        fileFilter.setPattern(
+                "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~");
+    }
+
+    /*
+     * Enumerate the files in each source directory.
+     */
+    for (const StringPiece& source : sourceDirs) {
+        if (!walkTree(source, fileFilter, options.sources)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool prepareCollect(std::vector<StringPiece>::const_iterator argsIter,
+        const std::vector<StringPiece>::const_iterator argsEndIter,
+        AaptOptions& options) {
+    options.phase = AaptOptions::Phase::Collect;
+
+    while (argsIter != argsEndIter) {
+        if (*argsIter == "--package") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "--package missing argument." << std::endl;
+                return false;
+            }
+            options.appInfo.package = util::utf8ToUtf16(*argsIter);
+        } else if (*argsIter == "-o") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-o missing argument." << std::endl;
+                return false;
+            }
+            options.output = Source{ argsIter->toString() };
+        } else if (*argsIter == "-v") {
+            options.verbose = true;
+        } else if (argsIter->data()[0] != '-') {
+            options.sources.push_back(Source{ argsIter->toString() });
+        } else {
+            Logger::error()
+                    << "unknown option '"
+                    << *argsIter
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+        ++argsIter;
+    }
+    return true;
+}
+
+bool prepareLink(std::vector<StringPiece>::const_iterator argsIter,
+        const std::vector<StringPiece>::const_iterator argsEndIter,
+        AaptOptions& options) {
+    options.phase = AaptOptions::Phase::Link;
+
+    while (argsIter != argsEndIter) {
+        if (*argsIter == "--package") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "--package missing argument." << std::endl;
+                return false;
+            }
+            options.appInfo.package = util::utf8ToUtf16(*argsIter);
+        } else if (*argsIter == "-o") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-o missing argument." << std::endl;
+                return false;
+            }
+            options.output = Source{ argsIter->toString() };
+        } else if (*argsIter == "-I") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-I missing argument." << std::endl;
+                return false;
+            }
+            options.libraries.push_back(Source{ argsIter->toString() });
+        } else if (*argsIter == "--java") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "--java missing argument." << std::endl;
+                return false;
+            }
+            options.generateJavaClass = make_value<Source>(Source{ argsIter->toString() });
+        } else if (*argsIter == "-v") {
+            options.verbose = true;
+        } else if (argsIter->data()[0] != '-') {
+            options.sources.push_back(Source{ argsIter->toString() });
+        } else {
+            Logger::error()
+                    << "unknown option '"
+                    << *argsIter
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+        ++argsIter;
+    }
+    return true;
+}
+
+bool prepareCompile(std::vector<StringPiece>::const_iterator argsIter,
+        const std::vector<StringPiece>::const_iterator argsEndIter,
+        AaptOptions& options) {
+    options.phase = AaptOptions::Phase::Compile;
+
+    while (argsIter != argsEndIter) {
+        if (*argsIter == "--package") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "--package missing argument." << std::endl;
+                return false;
+            }
+            options.appInfo.package = util::utf8ToUtf16(*argsIter);
+        } else if (*argsIter == "-o") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-o missing argument." << std::endl;
+                return false;
+            }
+            options.output = Source{ argsIter->toString() };
+        } else if (*argsIter == "-I") {
+            ++argsIter;
+            if (argsIter == argsEndIter) {
+                Logger::error() << "-I missing argument." << std::endl;
+                return false;
+            }
+            options.libraries.push_back(Source{ argsIter->toString() });
+        } else if (*argsIter == "-v") {
+            options.verbose = true;
+        } else if (argsIter->data()[0] != '-') {
+            options.sources.push_back(Source{ argsIter->toString() });
+        } else {
+            Logger::error()
+                    << "unknown option '"
+                    << *argsIter
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+        ++argsIter;
+    }
+    return true;
+}
+
+struct CollectValuesItem {
+    Source source;
+    ConfigDescription config;
+};
+
+bool collectValues(std::shared_ptr<ResourceTable> table, const CollectValuesItem& item) {
+    std::ifstream in(item.source.path, std::ifstream::binary);
+    if (!in) {
+        Logger::error(item.source) << strerror(errno) << std::endl;
+        return false;
+    }
+
+    std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(in);
+    ResourceParser parser(table, item.source, item.config, xmlParser);
+    return parser.parse();
+}
+
+struct ResourcePathData {
+    std::u16string resourceDir;
+    std::u16string name;
+    std::string extension;
+    ConfigDescription config;
+};
+
+/**
+ * Resource file paths are expected to look like:
+ * [--/res/]type[-config]/name
+ */
+Maybe<ResourcePathData> extractResourcePathData(const Source& source) {
+    std::vector<std::string> parts = util::splitAndLowercase(source.path, '/');
+    if (parts.size() < 2) {
+        Logger::error(source) << "bad resource path." << std::endl;
+        return {};
+    }
+
+    std::string& dir = parts[parts.size() - 2];
+    StringPiece dirStr = dir;
+
+    ConfigDescription config;
+    size_t dashPos = dir.find('-');
+    if (dashPos != std::string::npos) {
+        StringPiece configStr = dirStr.substr(dashPos + 1, dir.size() - (dashPos + 1));
+        if (!ConfigDescription::parse(configStr, &config)) {
+            Logger::error(source)
+                    << "invalid configuration '"
+                    << configStr
+                    << "'."
+                    << std::endl;
+            return {};
+        }
+        dirStr = dirStr.substr(0, dashPos);
+    }
+
+    std::string& filename = parts[parts.size() - 1];
+    StringPiece name = filename;
+    StringPiece extension;
+    size_t dotPos = filename.find('.');
+    if (dotPos != std::string::npos) {
+        extension = name.substr(dotPos + 1, filename.size() - (dotPos + 1));
+        name = name.substr(0, dotPos);
+    }
+
+    return ResourcePathData{
+            util::utf8ToUtf16(dirStr),
+            util::utf8ToUtf16(name),
+            extension.toString(),
+            config
+    };
+}
+
+static bool doLegacy(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver,
+                     const AaptOptions& options) {
+    bool error = false;
+    std::queue<CompileXml> xmlCompileQueue;
+
+    //
+    // Read values XML files and XML/PNG files.
+    // Need to parse the resource type/config/filename.
+    //
+    for (const Source& source : options.sources) {
+        Maybe<ResourcePathData> maybePathData = extractResourcePathData(source);
+        if (!maybePathData) {
+            return false;
+        }
+
+        const ResourcePathData& pathData = maybePathData.value();
+        if (pathData.resourceDir == u"values") {
+            if (options.verbose) {
+                Logger::note(source) << "collecting values..." << std::endl;
+            }
+
+            error |= !collectValues(table, CollectValuesItem{ source, pathData.config });
+            continue;
+        }
+
+        const ResourceType* type = parseResourceType(pathData.resourceDir);
+        if (!type) {
+            Logger::error(source)
+                    << "invalid resource type '"
+                    << pathData.resourceDir
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+
+        ResourceName resourceName = { table->getPackage(), *type, pathData.name };
+        if (pathData.extension == "xml") {
+            if (options.verbose) {
+                Logger::note(source) << "collecting XML..." << std::endl;
+            }
+
+            error |= !collectXml(table, source, resourceName, pathData.config);
+            xmlCompileQueue.push(CompileXml{
+                    source,
+                    resourceName,
+                    pathData.config
+            });
+        } else {
+            std::unique_ptr<FileReference> fileReference = makeFileReference(
+                    table->getValueStringPool(),
+                    util::utf16ToUtf8(pathData.name) + "." + pathData.extension,
+                    *type, pathData.config);
+
+            error |= !table->addResource(resourceName, pathData.config, source.line(0),
+                                         std::move(fileReference));
+        }
+    }
+
+    if (error) {
+        return false;
+    }
+
+    versionStylesForCompat(table);
+
+    //
+    // Verify all references and data types.
+    //
+    Linker linker(table, resolver);
+    if (!linker.linkAndValidate()) {
+        Logger::error()
+                << "linking failed."
+                << std::endl;
+        return false;
+    }
+
+    const auto& unresolvedRefs = linker.getUnresolvedReferences();
+    if (!unresolvedRefs.empty()) {
+        for (const auto& entry : unresolvedRefs) {
+            for (const auto& source : entry.second) {
+                Logger::error(source)
+                        << "unresolved symbol '"
+                        << entry.first
+                        << "'."
+                        << std::endl;
+            }
+        }
+        return false;
+    }
+
+    //
+    // Compile the XML files.
+    //
+    while (!xmlCompileQueue.empty()) {
+        const CompileXml& item = xmlCompileQueue.front();
+
+        // Create the output path from the resource name.
+        std::stringstream outputPath;
+        outputPath << item.name.type;
+        if (item.config != ConfigDescription{}) {
+            outputPath << "-" << item.config.toString();
+        }
+
+        Source outSource = options.output;
+        appendPath(&outSource.path, "res");
+        appendPath(&outSource.path, outputPath.str());
+
+        if (!mkdirs(outSource.path)) {
+            Logger::error(outSource) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        appendPath(&outSource.path, util::utf16ToUtf8(item.name.entry) + ".xml");
+
+        if (options.verbose) {
+            Logger::note(outSource) << "compiling XML file." << std::endl;
+        }
+
+        error |= !compileXml(resolver, item, outSource, &xmlCompileQueue);
+        xmlCompileQueue.pop();
+    }
+
+    if (error) {
+        return false;
+    }
+
+    //
+    // Compile the AndroidManifest.xml file.
+    //
+    if (!compileAndroidManifest(resolver, options)) {
+        return false;
+    }
+
+    //
+    // Generate the Java R class.
+    //
+    if (options.generateJavaClass) {
+        Source outPath = options.generateJavaClass.value();
+        if (options.verbose) {
+            Logger::note()
+                    << "writing symbols to "
+                    << outPath
+                    << "."
+                    << std::endl;
+        }
+
+        for (std::string& part : util::split(util::utf16ToUtf8(table->getPackage()), '.')) {
+            appendPath(&outPath.path, part);
+        }
+
+        if (!mkdirs(outPath.path)) {
+            Logger::error(outPath) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        appendPath(&outPath.path, "R.java");
+
+        std::ofstream fout(outPath.path);
+        if (!fout) {
+            Logger::error(outPath) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        JavaClassGenerator generator(table, JavaClassGenerator::Options{});
+        if (!generator.generate(fout)) {
+            Logger::error(outPath)
+                    << generator.getError()
+                    << "."
+                    << std::endl;
+            return false;
+        }
+    }
+
+    //
+    // Flatten resource table.
+    //
+    if (table->begin() != table->end()) {
+        BigBuffer buffer(1024);
+        TableFlattener::Options tableOptions;
+        tableOptions.useExtendedChunks = false;
+        TableFlattener flattener(tableOptions);
+        if (!flattener.flatten(&buffer, *table)) {
+            Logger::error()
+                    << "failed to flatten resource table->"
+                    << std::endl;
+            return false;
+        }
+
+        if (options.verbose) {
+            Logger::note()
+                    << "Final resource table size="
+                    << util::formatSize(buffer.size())
+                    << std::endl;
+        }
+
+        std::string outTable(options.output.path);
+        appendPath(&outTable, "resources.arsc");
+
+        std::ofstream fout(outTable, std::ofstream::binary);
+        if (!fout) {
+            Logger::error(Source{outTable})
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+
+        if (!util::writeAll(fout, buffer)) {
+            Logger::error(Source{outTable})
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+        fout.flush();
+    }
+    return true;
+}
+
+static bool doCollect(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver,
+                      const AaptOptions& options) {
+    bool error = false;
+
+    //
+    // Read values XML files and XML/PNG files.
+    // Need to parse the resource type/config/filename.
+    //
+    for (const Source& source : options.sources) {
+        Maybe<ResourcePathData> maybePathData = extractResourcePathData(source);
+        if (!maybePathData) {
+            return false;
+        }
+
+        const ResourcePathData& pathData = maybePathData.value();
+        if (pathData.resourceDir == u"values") {
+            if (options.verbose) {
+                Logger::note(source) << "collecting values..." << std::endl;
+            }
+
+            error |= !collectValues(table, CollectValuesItem{ source, pathData.config });
+            continue;
+        }
+
+        const ResourceType* type = parseResourceType(pathData.resourceDir);
+        if (!type) {
+            Logger::error(source)
+                    << "invalid resource type '"
+                    << pathData.resourceDir
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+
+        ResourceName resourceName = { table->getPackage(), *type, pathData.name };
+        if (pathData.extension == "xml") {
+            if (options.verbose) {
+                Logger::note(source) << "collecting XML..." << std::endl;
+            }
+
+            error |= !collectXml(table, source, resourceName, pathData.config);
+        } else {
+            std::unique_ptr<FileReference> fileReference = makeFileReference(
+                    table->getValueStringPool(),
+                    util::utf16ToUtf8(pathData.name) + "." + pathData.extension,
+                    *type,
+                    pathData.config);
+            error |= !table->addResource(resourceName, pathData.config, source.line(0),
+                                         std::move(fileReference));
+        }
+    }
+
+    if (error) {
+        return false;
+    }
+
+    Linker linker(table, resolver);
+    if (!linker.linkAndValidate()) {
+        return false;
+    }
+
+    //
+    // Flatten resource table->
+    //
+    if (table->begin() != table->end()) {
+        BigBuffer buffer(1024);
+        TableFlattener::Options tableOptions;
+        tableOptions.useExtendedChunks = true;
+        TableFlattener flattener(tableOptions);
+        if (!flattener.flatten(&buffer, *table)) {
+            Logger::error()
+                    << "failed to flatten resource table->"
+                    << std::endl;
+            return false;
+        }
+
+        std::ofstream fout(options.output.path, std::ofstream::binary);
+        if (!fout) {
+            Logger::error(options.output)
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+
+        if (!util::writeAll(fout, buffer)) {
+            Logger::error(options.output)
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+        fout.flush();
+    }
+    return true;
+}
+
+static bool doLink(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver,
+                   const AaptOptions& options) {
+    bool error = false;
+
+    for (const Source& source : options.sources) {
+        error |= !loadBinaryResourceTable(table, source);
+    }
+
+    if (error) {
+        return false;
+    }
+
+    versionStylesForCompat(table);
+
+    Linker linker(table, resolver);
+    if (!linker.linkAndValidate()) {
+        return false;
+    }
+
+    const auto& unresolvedRefs = linker.getUnresolvedReferences();
+    if (!unresolvedRefs.empty()) {
+        for (const auto& entry : unresolvedRefs) {
+            for (const auto& source : entry.second) {
+                Logger::error(source)
+                        << "unresolved symbol '"
+                        << entry.first
+                        << "'."
+                        << std::endl;
+            }
+        }
+        return false;
+    }
+
+    //
+    // Generate the Java R class.
+    //
+    if (options.generateJavaClass) {
+        Source outPath = options.generateJavaClass.value();
+        if (options.verbose) {
+            Logger::note()
+                    << "writing symbols to "
+                    << outPath
+                    << "."
+                    << std::endl;
+        }
+
+        for (std::string& part : util::split(util::utf16ToUtf8(table->getPackage()), '.')) {
+            appendPath(&outPath.path, part);
+        }
+
+        if (!mkdirs(outPath.path)) {
+            Logger::error(outPath) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        appendPath(&outPath.path, "R.java");
+
+        std::ofstream fout(outPath.path);
+        if (!fout) {
+            Logger::error(outPath) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        JavaClassGenerator generator(table, JavaClassGenerator::Options{});
+        if (!generator.generate(fout)) {
+            Logger::error(outPath)
+                    << generator.getError()
+                    << "."
+                    << std::endl;
+            return false;
+        }
+    }
+
+    //
+    // Flatten resource table.
+    //
+    if (table->begin() != table->end()) {
+        BigBuffer buffer(1024);
+        TableFlattener::Options tableOptions;
+        tableOptions.useExtendedChunks = false;
+        TableFlattener flattener(tableOptions);
+        if (!flattener.flatten(&buffer, *table)) {
+            Logger::error()
+                    << "failed to flatten resource table->"
+                    << std::endl;
+            return false;
+        }
+
+        if (options.verbose) {
+            Logger::note()
+                    << "Final resource table size="
+                    << util::formatSize(buffer.size())
+                    << std::endl;
+        }
+
+        std::ofstream fout(options.output.path, std::ofstream::binary);
+        if (!fout) {
+            Logger::error(options.output)
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+
+        if (!util::writeAll(fout, buffer)) {
+            Logger::error(options.output)
+                    << strerror(errno)
+                    << "."
+                    << std::endl;
+            return false;
+        }
+        fout.flush();
+    }
+    return true;
+}
+
+static bool doCompile(std::shared_ptr<ResourceTable> table, std::shared_ptr<Resolver> resolver,
+                      const AaptOptions& options) {
+    std::queue<CompileXml> xmlCompileQueue;
+
+    for (const Source& source : options.sources) {
+        Maybe<ResourcePathData> maybePathData = extractResourcePathData(source);
+        if (!maybePathData) {
+            return false;
+        }
+
+        ResourcePathData& pathData = maybePathData.value();
+        const ResourceType* type = parseResourceType(pathData.resourceDir);
+        if (!type) {
+            Logger::error(source)
+                    << "invalid resource type '"
+                    << pathData.resourceDir
+                    << "'."
+                    << std::endl;
+            return false;
+        }
+
+        ResourceName resourceName = { table->getPackage(), *type, pathData.name };
+        if (pathData.extension == "xml") {
+            xmlCompileQueue.push(CompileXml{
+                    source,
+                    resourceName,
+                    pathData.config
+            });
+        } else {
+            // TODO(adamlesinski): Handle images here.
+        }
+    }
+
+    bool error = false;
+    while (!xmlCompileQueue.empty()) {
+        const CompileXml& item = xmlCompileQueue.front();
+
+        // Create the output path from the resource name.
+        std::stringstream outputPath;
+        outputPath << item.name.type;
+        if (item.config != ConfigDescription{}) {
+            outputPath << "-" << item.config.toString();
+        }
+
+        Source outSource = options.output;
+        appendPath(&outSource.path, "res");
+        appendPath(&outSource.path, outputPath.str());
+
+        if (!mkdirs(outSource.path)) {
+            Logger::error(outSource) << strerror(errno) << std::endl;
+            return false;
+        }
+
+        appendPath(&outSource.path, util::utf16ToUtf8(item.name.entry) + ".xml");
+
+        if (options.verbose) {
+            Logger::note(outSource) << "compiling XML file." << std::endl;
+        }
+
+        error |= !compileXml(resolver, item, outSource, &xmlCompileQueue);
+        xmlCompileQueue.pop();
+    }
+    return !error;
+}
+
+int main(int argc, char** argv) {
+    Logger::setLog(std::make_shared<Log>(std::cerr, std::cerr));
+
+    std::vector<StringPiece> args;
+    args.reserve(argc - 1);
+    for (int i = 1; i < argc; i++) {
+        args.emplace_back(argv[i], strlen(argv[i]));
+    }
+
+    if (args.empty()) {
+        Logger::error() << "no command specified." << std::endl;
+        return 1;
+    }
+
+    AaptOptions options;
+
+    // Check the command we're running.
+    const StringPiece& command = args.front();
+    if (command == "package") {
+        if (!prepareLegacy(std::begin(args) + 1, std::end(args), options)) {
+            return 1;
+        }
+    } else if (command == "collect") {
+        if (!prepareCollect(std::begin(args) + 1, std::end(args), options)) {
+            return 1;
+        }
+    } else if (command == "link") {
+        if (!prepareLink(std::begin(args) + 1, std::end(args), options)) {
+            return 1;
+        }
+    } else if (command == "compile") {
+        if (!prepareCompile(std::begin(args) + 1, std::end(args), options)) {
+            return 1;
+        }
+    } else {
+        Logger::error() << "unknown command '" << command << "'." << std::endl;
+        return 1;
+    }
+
+    //
+    // Verify we have some common options set.
+    //
+
+    if (options.sources.empty()) {
+        Logger::error() << "no sources specified." << std::endl;
+        return false;
+    }
+
+    if (options.output.path.empty()) {
+        Logger::error() << "no output directory specified." << std::endl;
+        return false;
+    }
+
+    if (options.appInfo.package.empty()) {
+        Logger::error() << "no package name specified." << std::endl;
+        return false;
+    }
+
+
+    //
+    // Every phase needs a resource table and a resolver/linker.
+    //
+
+    std::shared_ptr<ResourceTable> table = std::make_shared<ResourceTable>();
+    table->setPackage(options.appInfo.package);
+    if (options.appInfo.package == u"android") {
+        table->setPackageId(0x01);
+    } else {
+        table->setPackageId(0x7f);
+    }
+
+    //
+    // Load the included libraries.
+    //
+    std::shared_ptr<android::AssetManager> libraries = std::make_shared<android::AssetManager>();
+    for (const Source& source : options.libraries) {
+        if (util::stringEndsWith(source.path, ".arsc")) {
+            // We'll process these last so as to avoid a cookie issue.
+            continue;
+        }
+
+        int32_t cookie;
+        if (!libraries->addAssetPath(android::String8(source.path.data()), &cookie)) {
+            Logger::error(source) << "failed to load library." << std::endl;
+            return false;
+        }
+    }
+
+    for (const Source& source : options.libraries) {
+        if (!util::stringEndsWith(source.path, ".arsc")) {
+            // We've already processed this.
+            continue;
+        }
+
+        // Dirty hack but there is no other way to get a
+        // writeable ResTable.
+        if (!loadResTable(const_cast<android::ResTable*>(&libraries->getResources(false)),
+                          source)) {
+            return false;
+        }
+    }
+
+    // Make the resolver that will cache IDs for us.
+    std::shared_ptr<Resolver> resolver = std::make_shared<Resolver>(table, libraries);
+
+    //
+    // Dispatch to the real phase here.
+    //
+
+    bool result = true;
+    switch (options.phase) {
+        case AaptOptions::Phase::LegacyFull:
+            result = doLegacy(table, resolver, options);
+            break;
+
+        case AaptOptions::Phase::Collect:
+            result = doCollect(table, resolver, options);
+            break;
+
+        case AaptOptions::Phase::Link:
+            result = doLink(table, resolver, options);
+            break;
+
+        case AaptOptions::Phase::Compile:
+            result = doCompile(table, resolver, options);
+            break;
+    }
+
+    if (!result) {
+        Logger::error()
+                << "aapt exiting with failures."
+                << std::endl;
+        return 1;
+    }
+    return 0;
+}
diff --git a/tools/aapt2/ManifestParser.cpp b/tools/aapt2/ManifestParser.cpp
new file mode 100644
index 0000000..b8f0a43
--- /dev/null
+++ b/tools/aapt2/ManifestParser.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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 "AppInfo.h"
+#include "Logger.h"
+#include "ManifestParser.h"
+#include "Source.h"
+#include "XmlPullParser.h"
+
+#include <string>
+
+namespace aapt {
+
+bool ManifestParser::parse(const Source& source, std::shared_ptr<XmlPullParser> parser,
+                           AppInfo* outInfo) {
+    SourceLogger logger = { source };
+
+    int depth = 0;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        XmlPullParser::Event event = parser->getEvent();
+        if (event == XmlPullParser::Event::kEndElement) {
+            depth--;
+            continue;
+        } else if (event != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        depth++;
+
+        const std::u16string& element = parser->getElementName();
+        if (depth == 1) {
+            if (element == u"manifest") {
+                if (!parseManifest(logger, parser, outInfo)) {
+                    return false;
+                }
+            } else {
+                logger.error()
+                        << "unexpected top-level element '"
+                        << element
+                        << "'."
+                        << std::endl;
+                return false;
+            }
+        } else {
+            XmlPullParser::skipCurrentElement(parser.get());
+        }
+    }
+
+    if (parser->getEvent() == XmlPullParser::Event::kBadDocument) {
+            logger.error(parser->getLineNumber())
+                << "failed to parse manifest: "
+                << parser->getLastError()
+                << "."
+                << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool ManifestParser::parseManifest(SourceLogger& logger, std::shared_ptr<XmlPullParser> parser,
+                                   AppInfo* outInfo) {
+    auto attrIter = parser->findAttribute(u"", u"package");
+    if (attrIter == parser->endAttributes() || attrIter->value.empty()) {
+        logger.error() << "no 'package' attribute found for element <manifest>." << std::endl;
+        return false;
+    }
+    outInfo->package = attrIter->value;
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ManifestParser.h b/tools/aapt2/ManifestParser.h
new file mode 100644
index 0000000..f2e43d4
--- /dev/null
+++ b/tools/aapt2/ManifestParser.h
@@ -0,0 +1,45 @@
+/*
+ * 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_MANIFEST_PARSER_H
+#define AAPT_MANIFEST_PARSER_H
+
+#include "AppInfo.h"
+#include "Logger.h"
+#include "Source.h"
+#include "XmlPullParser.h"
+
+namespace aapt {
+
+/*
+ * Parses an AndroidManifest.xml file and fills in an AppInfo structure with
+ * app data.
+ */
+class ManifestParser {
+public:
+    ManifestParser() = default;
+    ManifestParser(const ManifestParser&) = delete;
+
+    bool parse(const Source& source, std::shared_ptr<XmlPullParser> parser, AppInfo* outInfo);
+
+private:
+    bool parseManifest(SourceLogger& logger, std::shared_ptr<XmlPullParser> parser,
+                       AppInfo* outInfo);
+};
+
+} // namespace aapt
+
+#endif // AAPT_MANIFEST_PARSER_H
diff --git a/tools/aapt2/ManifestParser_test.cpp b/tools/aapt2/ManifestParser_test.cpp
new file mode 100644
index 0000000..be3a6fb
--- /dev/null
+++ b/tools/aapt2/ManifestParser_test.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "AppInfo.h"
+#include "ManifestParser.h"
+#include "SourceXmlPullParser.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+TEST(ManifestParserTest, FindPackage) {
+    std::stringstream input;
+    input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+             "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+             "package=\"android\">\n"
+             "</manifest>\n";
+
+    ManifestParser parser;
+    AppInfo info;
+    std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(input);
+    ASSERT_TRUE(parser.parse(Source{ "AndroidManifest.xml" }, xmlParser, &info));
+
+    EXPECT_EQ(std::u16string(u"android"), info.package);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ManifestValidator.cpp b/tools/aapt2/ManifestValidator.cpp
new file mode 100644
index 0000000..596c758
--- /dev/null
+++ b/tools/aapt2/ManifestValidator.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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 "ManifestValidator.h"
+#include "Maybe.h"
+#include "Source.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+
+namespace aapt {
+
+ManifestValidator::ManifestValidator(const android::ResTable& table)
+: mTable(table) {
+}
+
+bool ManifestValidator::validate(const Source& source, android::ResXMLParser* parser) {
+    SourceLogger logger(source);
+
+    android::ResXMLParser::event_code_t code;
+    while ((code = parser->next()) != android::ResXMLParser::END_DOCUMENT &&
+            code != android::ResXMLParser::BAD_DOCUMENT) {
+        if (code != android::ResXMLParser::START_TAG) {
+            continue;
+        }
+
+        size_t len = 0;
+        const StringPiece16 namespaceUri(parser->getElementNamespace(&len), len);
+        if (!namespaceUri.empty()) {
+            continue;
+        }
+
+        const StringPiece16 name(parser->getElementName(&len), len);
+        if (name.empty()) {
+            logger.error(parser->getLineNumber())
+                    << "failed to get the element name."
+                    << std::endl;
+            return false;
+        }
+
+        if (name == u"manifest") {
+            if (!validateManifest(source, parser)) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+Maybe<StringPiece16> ManifestValidator::getAttributeValue(android::ResXMLParser* parser,
+                                                          size_t idx) {
+    android::Res_value value;
+    if (parser->getAttributeValue(idx, &value) < 0) {
+        return StringPiece16();
+    }
+
+    const android::ResStringPool* pool = &parser->getStrings();
+    if (value.dataType == android::Res_value::TYPE_REFERENCE) {
+        ssize_t strIdx = mTable.resolveReference(&value, 0x10000000u);
+        if (strIdx < 0) {
+            return {};
+        }
+        pool = mTable.getTableStringBlock(strIdx);
+    }
+
+    if (value.dataType != android::Res_value::TYPE_STRING || !pool) {
+        return {};
+    }
+    return util::getString(*pool, value.data);
+}
+
+Maybe<StringPiece16> ManifestValidator::getAttributeInlineValue(android::ResXMLParser* parser,
+                                                                size_t idx) {
+    android::Res_value value;
+    if (parser->getAttributeValue(idx, &value) < 0) {
+        return StringPiece16();
+    }
+
+    if (value.dataType != android::Res_value::TYPE_STRING) {
+        return {};
+    }
+    return util::getString(parser->getStrings(), value.data);
+}
+
+bool ManifestValidator::validateInlineAttribute(android::ResXMLParser* parser, size_t idx,
+                                                SourceLogger& logger,
+                                                const StringPiece16& charSet) {
+    size_t len = 0;
+    StringPiece16 element(parser->getElementName(&len), len);
+    StringPiece16 attributeName(parser->getAttributeName(idx, &len), len);
+    Maybe<StringPiece16> result = getAttributeInlineValue(parser, idx);
+    if (!result) {
+        logger.error(parser->getLineNumber())
+                << "<"
+                << element
+                << "> must have a '"
+                << attributeName
+                << "' attribute with a string literal value."
+                << std::endl;
+        return false;
+    }
+    return validateAttributeImpl(element, attributeName, result.value(), charSet,
+                                 parser->getLineNumber(), logger);
+}
+
+bool ManifestValidator::validateAttribute(android::ResXMLParser* parser, size_t idx,
+                                          SourceLogger& logger, const StringPiece16& charSet) {
+    size_t len = 0;
+    StringPiece16 element(parser->getElementName(&len), len);
+    StringPiece16 attributeName(parser->getAttributeName(idx, &len), len);
+    Maybe<StringPiece16> result = getAttributeValue(parser, idx);
+    if (!result) {
+        logger.error(parser->getLineNumber())
+                << "<"
+                << element
+                << "> must have a '"
+                << attributeName
+                << "' attribute that points to a string."
+                << std::endl;
+        return false;
+    }
+    return validateAttributeImpl(element, attributeName, result.value(), charSet,
+                                 parser->getLineNumber(), logger);
+}
+
+bool ManifestValidator::validateAttributeImpl(const StringPiece16& element,
+                                              const StringPiece16& attributeName,
+                                              const StringPiece16& attributeValue,
+                                              const StringPiece16& charSet, size_t lineNumber,
+                                              SourceLogger& logger) {
+    StringPiece16::const_iterator badIter =
+            util::findNonAlphaNumericAndNotInSet(attributeValue, charSet);
+    if (badIter != attributeValue.end()) {
+        logger.error(lineNumber)
+                << "tag <"
+                << element
+                << "> attribute '"
+                << attributeName
+                << "' has invalid character '"
+                << *badIter
+                << "'."
+                << std::endl;
+        return false;
+    }
+
+    if (!attributeValue.empty()) {
+        StringPiece16 trimmed = util::trimWhitespace(attributeValue);
+        if (attributeValue.begin() != trimmed.begin()) {
+            logger.error(lineNumber)
+                    << "tag <"
+                    << element
+                    << "> attribute '"
+                    << attributeName
+                    << "' can not start with whitespace."
+                    << std::endl;
+            return false;
+        }
+
+        if (attributeValue.end() != trimmed.end()) {
+            logger.error(lineNumber)
+                    << "tag <"
+                    << element
+                    << "> attribute '"
+                    << attributeName
+                    << "' can not end with whitespace."
+                    << std::endl;
+            return false;
+        }
+    }
+    return true;
+}
+
+constexpr const char16_t* kPackageIdentSet = u"._";
+
+bool ManifestValidator::validateManifest(const Source& source, android::ResXMLParser* parser) {
+    bool error = false;
+    SourceLogger logger(source);
+
+    const size_t attrCount = parser->getAttributeCount();
+    for (size_t i = 0; i < attrCount; i++) {
+        size_t len = 0;
+        StringPiece16 attrNamespace(parser->getAttributeNamespace(i, &len), len);
+        StringPiece16 attrName(parser->getAttributeName(i, &len), len);
+        if (attrNamespace.empty() && attrName == u"package") {
+            error |= !validateInlineAttribute(parser, i, logger, kPackageIdentSet);
+        } else if (attrNamespace == u"android") {
+            if (attrName == u"sharedUserId") {
+                error |= !validateInlineAttribute(parser, i, logger, kPackageIdentSet);
+            }
+        }
+    }
+    return !error;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ManifestValidator.h b/tools/aapt2/ManifestValidator.h
new file mode 100644
index 0000000..3188784
--- /dev/null
+++ b/tools/aapt2/ManifestValidator.h
@@ -0,0 +1,55 @@
+/*
+ * 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_MANIFEST_VALIDATOR_H
+#define AAPT_MANIFEST_VALIDATOR_H
+
+#include "Logger.h"
+#include "Maybe.h"
+#include "Source.h"
+#include "StringPiece.h"
+
+#include <androidfw/ResourceTypes.h>
+
+namespace aapt {
+
+class ManifestValidator {
+public:
+    ManifestValidator(const android::ResTable& table);
+    ManifestValidator(const ManifestValidator&) = delete;
+
+    bool validate(const Source& source, android::ResXMLParser* parser);
+
+private:
+    bool validateManifest(const Source& source, android::ResXMLParser* parser);
+
+    Maybe<StringPiece16> getAttributeInlineValue(android::ResXMLParser* parser, size_t idx);
+    Maybe<StringPiece16> getAttributeValue(android::ResXMLParser* parser, size_t idx);
+
+    bool validateInlineAttribute(android::ResXMLParser* parser, size_t idx,
+                                 SourceLogger& logger, const StringPiece16& charSet);
+    bool validateAttribute(android::ResXMLParser* parser, size_t idx, SourceLogger& logger,
+                           const StringPiece16& charSet);
+    bool validateAttributeImpl(const StringPiece16& element, const StringPiece16& attributeName,
+                               const StringPiece16& attributeValue, const StringPiece16& charSet,
+                               size_t lineNumber, SourceLogger& logger);
+
+    const android::ResTable& mTable;
+};
+
+} // namespace aapt
+
+#endif // AAPT_MANIFEST_VALIDATOR_H
diff --git a/tools/aapt2/Maybe.h b/tools/aapt2/Maybe.h
new file mode 100644
index 0000000..f6a396d
--- /dev/null
+++ b/tools/aapt2/Maybe.h
@@ -0,0 +1,224 @@
+/*
+ * 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_MAYBE_H
+#define AAPT_MAYBE_H
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+namespace aapt {
+
+/**
+ * Either holds a valid value of type T, or holds Nothing.
+ * The value is stored inline in this structure, so no
+ * heap memory is used when creating a Maybe<T> object.
+ */
+template <typename T>
+class Maybe {
+public:
+    /**
+     * Construct Nothing.
+     */
+    inline Maybe();
+
+    inline ~Maybe();
+
+    template <typename U>
+    inline Maybe(const Maybe<U>& rhs);
+
+    template <typename U>
+    inline Maybe(Maybe<U>&& rhs);
+
+    template <typename U>
+    inline Maybe& operator=(const Maybe<U>& rhs);
+
+    template <typename U>
+    inline Maybe& operator=(Maybe<U>&& rhs);
+
+    /**
+     * Construct a Maybe holding a value.
+     */
+    inline Maybe(const T& value);
+
+    /**
+     * Construct a Maybe holding a value.
+     */
+    inline Maybe(T&& value);
+
+    /**
+     * True if this holds a value, false if
+     * it holds Nothing.
+     */
+    inline operator bool() const;
+
+    /**
+     * Gets the value if one exists, or else
+     * panics.
+     */
+    inline T& value();
+
+    /**
+     * Gets the value if one exists, or else
+     * panics.
+     */
+    inline const T& value() const;
+
+private:
+    template <typename U>
+    friend class Maybe;
+
+    void destroy();
+
+    bool mNothing;
+
+    typename std::aligned_storage<sizeof(T), alignof(T)>::type mStorage;
+};
+
+template <typename T>
+Maybe<T>::Maybe()
+: mNothing(true) {
+}
+
+template <typename T>
+Maybe<T>::~Maybe() {
+    if (!mNothing) {
+        destroy();
+    }
+}
+
+template <typename T>
+template <typename U>
+Maybe<T>::Maybe(const Maybe<U>& rhs)
+: mNothing(rhs.mNothing) {
+    if (!rhs.mNothing) {
+        new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
+    }
+}
+
+template <typename T>
+template <typename U>
+Maybe<T>::Maybe(Maybe<U>&& rhs)
+: mNothing(rhs.mNothing) {
+    if (!rhs.mNothing) {
+        rhs.mNothing = true;
+
+        // Move the value from rhs.
+        new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));
+
+        // Since the value in rhs is now Nothing,
+        // run the destructor for the value.
+        rhs.destroy();
+    }
+}
+
+template <typename T>
+template <typename U>
+Maybe<T>& Maybe<T>::operator=(const Maybe<U>& rhs) {
+    if (mNothing && rhs.mNothing) {
+        // Both are nothing, nothing to do.
+        return *this;
+    } else if  (!mNothing && !rhs.mNothing) {
+        // We both are something, so assign rhs to us.
+        reinterpret_cast<T&>(mStorage) = reinterpret_cast<const U&>(rhs.mStorage);
+    } else if (mNothing) {
+        // We are nothing but rhs is something.
+        mNothing = rhs.mNothing;
+
+        // Copy the value from rhs.
+        new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage));
+    } else {
+        // We are something but rhs is nothing, so destroy our value.
+        mNothing = rhs.mNothing;
+        destroy();
+    }
+    return *this;
+}
+
+template <typename T>
+template <typename U>
+Maybe<T>& Maybe<T>::operator=(Maybe<U>&& rhs) {
+    if (mNothing && rhs.mNothing) {
+        // Both are nothing, nothing to do.
+        return *this;
+    } else if  (!mNothing && !rhs.mNothing) {
+        // We both are something, so move assign rhs to us.
+        rhs.mNothing = true;
+        reinterpret_cast<T&>(mStorage) = std::move(reinterpret_cast<U&>(rhs.mStorage));
+        rhs.destroy();
+    } else if (mNothing) {
+        // We are nothing but rhs is something.
+        mNothing = rhs.mNothing;
+
+        // Move the value from rhs.
+        new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage)));
+        rhs.destroy();
+    } else {
+        // We are something but rhs is nothing, so destroy our value.
+        mNothing = rhs.mNothing;
+        destroy();
+    }
+    return *this;
+}
+
+template <typename T>
+Maybe<T>::Maybe(const T& value)
+: mNothing(false) {
+    new (&mStorage) T(value);
+}
+
+template <typename T>
+Maybe<T>::Maybe(T&& value)
+: mNothing(false) {
+    new (&mStorage) T(std::forward<T>(value));
+}
+
+template <typename T>
+Maybe<T>::operator bool() const {
+    return !mNothing;
+}
+
+template <typename T>
+T& Maybe<T>::value() {
+    assert(!mNothing && "Maybe<T>::value() called on Nothing");
+    return reinterpret_cast<T&>(mStorage);
+}
+
+template <typename T>
+const T& Maybe<T>::value() const {
+    assert(!mNothing && "Maybe<T>::value() called on Nothing");
+    return reinterpret_cast<const T&>(mStorage);
+}
+
+template <typename T>
+void Maybe<T>::destroy() {
+    reinterpret_cast<T&>(mStorage).~T();
+}
+
+template <typename T>
+inline Maybe<typename std::remove_reference<T>::type> make_value(T&& value) {
+    return Maybe<typename std::remove_reference<T>::type>(std::forward<T>(value));
+}
+
+template <typename T>
+inline Maybe<T> make_nothing() {
+    return Maybe<T>();
+}
+
+} // namespace aapt
+
+#endif // AAPT_MAYBE_H
diff --git a/tools/aapt2/Maybe_test.cpp b/tools/aapt2/Maybe_test.cpp
new file mode 100644
index 0000000..348d7dd
--- /dev/null
+++ b/tools/aapt2/Maybe_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <string>
+
+#include "Maybe.h"
+
+namespace aapt {
+
+struct Dummy {
+    Dummy() {
+        std::cerr << "Constructing Dummy " << (void *) this << std::endl;
+    }
+
+    Dummy(const Dummy& rhs) {
+        std::cerr << "Copying Dummy " << (void *) this << " from " << (const void*) &rhs << std::endl;
+    }
+
+    Dummy(Dummy&& rhs) {
+        std::cerr << "Moving Dummy " << (void *) this << " from " << (void*) &rhs << std::endl;
+    }
+
+    ~Dummy() {
+        std::cerr << "Destroying Dummy " << (void *) this << std::endl;
+    }
+};
+
+TEST(MaybeTest, MakeNothing) {
+    Maybe<int> val = make_nothing<int>();
+    EXPECT_FALSE(val);
+
+    Maybe<std::string> val2 = make_nothing<std::string>();
+    EXPECT_FALSE(val2);
+
+    val2 = make_nothing<std::string>();
+    EXPECT_FALSE(val2);
+}
+
+TEST(MaybeTest, MakeSomething) {
+    Maybe<int> val = make_value(23);
+    ASSERT_TRUE(val);
+    EXPECT_EQ(23, val.value());
+
+    Maybe<std::string> val2 = make_value(std::string("hey"));
+    ASSERT_TRUE(val2);
+    EXPECT_EQ(std::string("hey"), val2.value());
+}
+
+TEST(MaybeTest, Lifecycle) {
+    Maybe<Dummy> val = make_nothing<Dummy>();
+
+    Maybe<Dummy> val2 = make_value(Dummy());
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResChunkPullParser.cpp b/tools/aapt2/ResChunkPullParser.cpp
new file mode 100644
index 0000000..78ea60e
--- /dev/null
+++ b/tools/aapt2/ResChunkPullParser.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "ResChunkPullParser.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <cstddef>
+
+namespace aapt {
+
+using android::ResChunk_header;
+
+ResChunkPullParser::Event ResChunkPullParser::next() {
+    if (!isGoodEvent(mEvent)) {
+        return mEvent;
+    }
+
+    if (mEvent == Event::StartDocument) {
+        mCurrentChunk = mData;
+    } else {
+        mCurrentChunk = reinterpret_cast<const ResChunk_header*>(
+                reinterpret_cast<const char*>(mCurrentChunk) + mCurrentChunk->size);
+    }
+
+    const std::ptrdiff_t diff = reinterpret_cast<const char*>(mCurrentChunk)
+            - reinterpret_cast<const char*>(mData);
+    assert(diff >= 0 && "diff is negative");
+    const size_t offset = static_cast<const size_t>(diff);
+
+    if (offset == mLen) {
+        mCurrentChunk = nullptr;
+        return (mEvent = Event::EndDocument);
+    } else if (offset + sizeof(ResChunk_header) > mLen) {
+        mLastError = "chunk is past the end of the document";
+        mCurrentChunk = nullptr;
+        return (mEvent = Event::BadDocument);
+    }
+
+    if (mCurrentChunk->headerSize < sizeof(ResChunk_header)) {
+        mLastError = "chunk has too small header";
+        mCurrentChunk = nullptr;
+        return (mEvent = Event::BadDocument);
+    } else if (mCurrentChunk->size < mCurrentChunk->headerSize) {
+        mLastError = "chunk's total size is smaller than header";
+        mCurrentChunk = nullptr;
+        return (mEvent = Event::BadDocument);
+    } else if (offset + mCurrentChunk->size > mLen) {
+        mLastError = "chunk's data extends past the end of the document";
+        mCurrentChunk = nullptr;
+        return (mEvent = Event::BadDocument);
+    }
+    return (mEvent = Event::Chunk);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResChunkPullParser.h b/tools/aapt2/ResChunkPullParser.h
new file mode 100644
index 0000000..7366c89
--- /dev/null
+++ b/tools/aapt2/ResChunkPullParser.h
@@ -0,0 +1,106 @@
+/*
+ * 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_RES_CHUNK_PULL_PARSER_H
+#define AAPT_RES_CHUNK_PULL_PARSER_H
+
+#include <androidfw/ResourceTypes.h>
+#include <string>
+
+namespace aapt {
+
+/**
+ * A pull parser, modeled after XmlPullParser, that reads
+ * android::ResChunk_header structs from a block of data.
+ *
+ * An android::ResChunk_header specifies a type, headerSize,
+ * and size. The pull parser will verify that the chunk's size
+ * doesn't extend beyond the available data, and will iterate
+ * over each chunk in the given block of data.
+ *
+ * Processing nested chunks is done by creating a new ResChunkPullParser
+ * pointing to the data portion of a chunk.
+ */
+class ResChunkPullParser {
+public:
+    enum class Event {
+        StartDocument,
+        EndDocument,
+        BadDocument,
+
+        Chunk,
+    };
+
+    /**
+     * Returns false if the event is EndDocument or BadDocument.
+     */
+    static bool isGoodEvent(Event event);
+
+    /**
+     * Create a ResChunkPullParser to read android::ResChunk_headers
+     * from the memory pointed to by data, of len bytes.
+     */
+    ResChunkPullParser(const void* data, size_t len);
+
+    ResChunkPullParser(const ResChunkPullParser&) = delete;
+
+    Event getEvent() const;
+    const std::string& getLastError() const;
+    const android::ResChunk_header* getChunk() const;
+
+    /**
+     * Move to the next android::ResChunk_header.
+     */
+    Event next();
+
+private:
+    Event mEvent;
+    const android::ResChunk_header* mData;
+    size_t mLen;
+    const android::ResChunk_header* mCurrentChunk;
+    std::string mLastError;
+};
+
+//
+// Implementation
+//
+
+inline bool ResChunkPullParser::isGoodEvent(ResChunkPullParser::Event event) {
+    return event != Event::EndDocument && event != Event::BadDocument;
+}
+
+inline ResChunkPullParser::ResChunkPullParser(const void* data, size_t len) :
+        mEvent(Event::StartDocument),
+        mData(reinterpret_cast<const android::ResChunk_header*>(data)),
+        mLen(len),
+        mCurrentChunk(nullptr) {
+}
+
+inline ResChunkPullParser::Event ResChunkPullParser::getEvent() const {
+    return mEvent;
+}
+
+inline const std::string& ResChunkPullParser::getLastError() const {
+    return mLastError;
+}
+
+inline const android::ResChunk_header* ResChunkPullParser::getChunk() const {
+    return mCurrentChunk;
+}
+
+} // namespace aapt
+
+#endif // AAPT_RES_CHUNK_PULL_PARSER_H
diff --git a/tools/aapt2/Resolver.cpp b/tools/aapt2/Resolver.cpp
new file mode 100644
index 0000000..93b5e98
--- /dev/null
+++ b/tools/aapt2/Resolver.cpp
@@ -0,0 +1,151 @@
+/*
+ * 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 "Maybe.h"
+#include "Resolver.h"
+#include "Resource.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <memory>
+#include <vector>
+
+namespace aapt {
+
+Resolver::Resolver(std::shared_ptr<const ResourceTable> table,
+                   std::shared_ptr<const android::AssetManager> sources) :
+        mTable(table), mSources(sources) {
+}
+
+Maybe<ResourceId> Resolver::findId(const ResourceName& name) {
+    Maybe<Entry> result = findAttribute(name);
+    if (result) {
+        return result.value().id;
+    }
+    return {};
+}
+
+Maybe<Resolver::Entry> Resolver::findAttribute(const ResourceName& name) {
+    auto cacheIter = mCache.find(name);
+    if (cacheIter != std::end(mCache)) {
+        return Entry{ cacheIter->second.id, cacheIter->second.attr.get() };
+    }
+
+    const ResourceTableType* type;
+    const ResourceEntry* entry;
+    std::tie(type, entry) = mTable->findResource(name);
+    if (type && entry) {
+        Entry result = {};
+        if (mTable->getPackageId() != ResourceTable::kUnsetPackageId &&
+                type->typeId != ResourceTableType::kUnsetTypeId &&
+                entry->entryId != ResourceEntry::kUnsetEntryId) {
+            result.id = ResourceId(mTable->getPackageId(), type->typeId, entry->entryId);
+        }
+
+        if (!entry->values.empty()) {
+            visitFunc<Attribute>(*entry->values.front().value, [&result](Attribute& attr) {
+                    result.attr = &attr;
+            });
+        }
+        return result;
+    }
+
+    const CacheEntry* cacheEntry = buildCacheEntry(name);
+    if (cacheEntry) {
+        return Entry{ cacheEntry->id, cacheEntry->attr.get() };
+    }
+    return {};
+}
+
+/**
+ * This is called when we need to lookup a resource name in the AssetManager.
+ * Since the values in the AssetManager are not parsed like in a ResourceTable,
+ * we must create Attribute objects here if we find them.
+ */
+const Resolver::CacheEntry* Resolver::buildCacheEntry(const ResourceName& name) {
+    const android::ResTable& table = mSources->getResources(false);
+
+    const StringPiece16 type16 = toString(name.type);
+    ResourceId resId {
+        table.identifierForName(
+                name.entry.data(), name.entry.size(),
+                type16.data(), type16.size(),
+                name.package.data(), name.package.size())
+    };
+
+    if (!resId.isValid()) {
+        return nullptr;
+    }
+
+    CacheEntry& entry = mCache[name];
+    entry.id = resId;
+
+    //
+    // Now check to see if this resource is an Attribute.
+    //
+
+    const android::ResTable::bag_entry* bagBegin;
+    ssize_t bags = table.lockBag(resId.id, &bagBegin);
+    if (bags < 1) {
+        table.unlockBag(bagBegin);
+        return &entry;
+    }
+
+    // Look for the ATTR_TYPE key in the bag and check the types it supports.
+    uint32_t attrTypeMask = 0;
+    for (ssize_t i = 0; i < bags; i++) {
+        if (bagBegin[i].map.name.ident == android::ResTable_map::ATTR_TYPE) {
+            attrTypeMask = bagBegin[i].map.value.data;
+        }
+    }
+
+    entry.attr = util::make_unique<Attribute>(false);
+
+    if (attrTypeMask & android::ResTable_map::TYPE_ENUM ||
+            attrTypeMask & android::ResTable_map::TYPE_FLAGS) {
+        for (ssize_t i = 0; i < bags; i++) {
+            if (Res_INTERNALID(bagBegin[i].map.name.ident)) {
+                // Internal IDs are special keys, which are not enum/flag symbols, so skip.
+                continue;
+            }
+
+            android::ResTable::resource_name symbolName;
+            bool result = table.getResourceName(bagBegin[i].map.name.ident, false,
+                    &symbolName);
+            assert(result);
+            const ResourceType* type = parseResourceType(
+                    StringPiece16(symbolName.type, symbolName.typeLen));
+            assert(type);
+
+            entry.attr->symbols.push_back(Attribute::Symbol{
+                    Reference(ResourceNameRef(
+                                StringPiece16(symbolName.package, symbolName.packageLen),
+                                *type,
+                                StringPiece16(symbolName.name, symbolName.nameLen))),
+                            bagBegin[i].map.value.data
+            });
+        }
+    }
+
+    entry.attr->typeMask |= attrTypeMask;
+    table.unlockBag(bagBegin);
+    return &entry;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Resolver.h b/tools/aapt2/Resolver.h
new file mode 100644
index 0000000..90a8cd9
--- /dev/null
+++ b/tools/aapt2/Resolver.h
@@ -0,0 +1,109 @@
+/*
+ * 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_RESOLVER_H
+#define AAPT_RESOLVER_H
+
+#include "Maybe.h"
+#include "Resource.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <memory>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * Resolves symbolic references (package:type/entry) into resource IDs/objects.
+ * Encapsulates the search of library sources as well as the local ResourceTable.
+ */
+class Resolver {
+public:
+    /**
+     * Creates a resolver with a local ResourceTable and an AssetManager
+     * loaded with library packages.
+     */
+    Resolver(std::shared_ptr<const ResourceTable> table,
+             std::shared_ptr<const android::AssetManager> sources);
+
+    Resolver(const Resolver&) = delete; // Not copyable.
+
+    /**
+     * Holds the result of a resource name lookup.
+     */
+    struct Entry {
+        /**
+         * The ID of the resource. ResourceId::isValid() may
+         * return false if the resource has not been assigned
+         * an ID.
+         */
+        ResourceId id;
+
+        /**
+         * If the resource is an attribute, this will point
+         * to a valid Attribute object, or else it will be
+         * nullptr.
+         */
+        const Attribute* attr;
+    };
+
+    /**
+     * Return the package to use when none is specified. This
+     * is the package name of the app being built.
+     */
+    const std::u16string& getDefaultPackage() const;
+
+    /**
+     * Returns a ResourceID if the name is found. The ResourceID
+     * may not be valid if the resource was not assigned an ID.
+     */
+    Maybe<ResourceId> findId(const ResourceName& name);
+
+    /**
+     * Returns an Entry if the name is found. Entry::attr
+     * may be nullptr if the resource is not an attribute.
+     */
+    Maybe<Entry> findAttribute(const ResourceName& name);
+
+    const android::ResTable& getResTable() const;
+
+private:
+    struct CacheEntry {
+        ResourceId id;
+        std::unique_ptr<Attribute> attr;
+    };
+
+    const CacheEntry* buildCacheEntry(const ResourceName& name);
+
+    std::shared_ptr<const ResourceTable> mTable;
+    std::shared_ptr<const android::AssetManager> mSources;
+    std::map<ResourceName, CacheEntry> mCache;
+};
+
+inline const std::u16string& Resolver::getDefaultPackage() const {
+    return mTable->getPackage();
+}
+
+inline const android::ResTable& Resolver::getResTable() const {
+    return mSources->getResources(false);
+}
+
+} // namespace aapt
+
+#endif // AAPT_RESOLVER_H
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
new file mode 100644
index 0000000..287d8de
--- /dev/null
+++ b/tools/aapt2/Resource.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "Resource.h"
+#include "StringPiece.h"
+
+#include <map>
+#include <string>
+
+namespace aapt {
+
+StringPiece16 toString(ResourceType type) {
+    switch (type) {
+        case ResourceType::kAnim:          return u"anim";
+        case ResourceType::kAnimator:      return u"animator";
+        case ResourceType::kArray:         return u"array";
+        case ResourceType::kAttr:          return u"attr";
+        case ResourceType::kAttrPrivate:   return u"attr";
+        case ResourceType::kBool:          return u"bool";
+        case ResourceType::kColor:         return u"color";
+        case ResourceType::kDimen:         return u"dimen";
+        case ResourceType::kDrawable:      return u"drawable";
+        case ResourceType::kFraction:      return u"fraction";
+        case ResourceType::kId:            return u"id";
+        case ResourceType::kInteger:       return u"integer";
+        case ResourceType::kIntegerArray:  return u"integer-array";
+        case ResourceType::kInterpolator:  return u"interpolator";
+        case ResourceType::kLayout:        return u"layout";
+        case ResourceType::kMenu:          return u"menu";
+        case ResourceType::kMipmap:        return u"mipmap";
+        case ResourceType::kPlurals:       return u"plurals";
+        case ResourceType::kRaw:           return u"raw";
+        case ResourceType::kString:        return u"string";
+        case ResourceType::kStyle:         return u"style";
+        case ResourceType::kStyleable:     return u"styleable";
+        case ResourceType::kTransition:    return u"transition";
+        case ResourceType::kXml:           return u"xml";
+    }
+    return {};
+}
+
+static const std::map<StringPiece16, ResourceType> sResourceTypeMap {
+        { u"anim", ResourceType::kAnim },
+        { u"animator", ResourceType::kAnimator },
+        { u"array", ResourceType::kArray },
+        { u"attr", ResourceType::kAttr },
+        { u"^attr-private", ResourceType::kAttrPrivate },
+        { u"bool", ResourceType::kBool },
+        { u"color", ResourceType::kColor },
+        { u"dimen", ResourceType::kDimen },
+        { u"drawable", ResourceType::kDrawable },
+        { u"fraction", ResourceType::kFraction },
+        { u"id", ResourceType::kId },
+        { u"integer", ResourceType::kInteger },
+        { u"integer-array", ResourceType::kIntegerArray },
+        { u"interpolator", ResourceType::kInterpolator },
+        { u"layout", ResourceType::kLayout },
+        { u"menu", ResourceType::kMenu },
+        { u"mipmap", ResourceType::kMipmap },
+        { u"plurals", ResourceType::kPlurals },
+        { u"raw", ResourceType::kRaw },
+        { u"string", ResourceType::kString },
+        { u"style", ResourceType::kStyle },
+        { u"styleable", ResourceType::kStyleable },
+        { u"transition", ResourceType::kTransition },
+        { u"xml", ResourceType::kXml },
+};
+
+const ResourceType* parseResourceType(const StringPiece16& str) {
+    auto iter = sResourceTypeMap.find(str);
+    if (iter == std::end(sResourceTypeMap)) {
+        return nullptr;
+    }
+    return &iter->second;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
new file mode 100644
index 0000000..3fd678e
--- /dev/null
+++ b/tools/aapt2/Resource.h
@@ -0,0 +1,276 @@
+/*
+ * 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_RESOURCE_H
+#define AAPT_RESOURCE_H
+
+#include "StringPiece.h"
+
+#include <iomanip>
+#include <string>
+#include <tuple>
+
+namespace aapt {
+
+/**
+ * The various types of resource types available. Corresponds
+ * to the 'type' in package:type/entry.
+ */
+enum class ResourceType {
+    kAnim,
+    kAnimator,
+    kArray,
+    kAttr,
+    kAttrPrivate,
+    kBool,
+    kColor,
+    kDimen,
+    kDrawable,
+    kFraction,
+    kId,
+    kInteger,
+    kIntegerArray,
+    kInterpolator,
+    kLayout,
+    kMenu,
+    kMipmap,
+    kPlurals,
+    kRaw,
+    kString,
+    kStyle,
+    kStyleable,
+    kTransition,
+    kXml,
+};
+
+StringPiece16 toString(ResourceType type);
+
+/**
+ * Returns a pointer to a valid ResourceType, or nullptr if
+ * the string was invalid.
+ */
+const ResourceType* parseResourceType(const StringPiece16& str);
+
+/**
+ * A resource's name. This can uniquely identify
+ * a resource in the ResourceTable.
+ */
+struct ResourceName {
+    std::u16string package;
+    ResourceType type;
+    std::u16string entry;
+
+    bool isValid() const;
+    bool operator<(const ResourceName& rhs) const;
+    bool operator==(const ResourceName& rhs) const;
+    bool operator!=(const ResourceName& rhs) const;
+};
+
+/**
+ * Same as ResourceName, but uses StringPieces instead.
+ * Use this if you need to avoid copying and know that
+ * the lifetime of this object is shorter than that
+ * of the original string.
+ */
+struct ResourceNameRef {
+    StringPiece16 package;
+    ResourceType type;
+    StringPiece16 entry;
+
+    ResourceNameRef() = default;
+    ResourceNameRef(const ResourceNameRef&) = default;
+    ResourceNameRef(ResourceNameRef&&) = default;
+    ResourceNameRef(const ResourceName& rhs);
+    ResourceNameRef(const StringPiece16& p, ResourceType t, const StringPiece16& e);
+    ResourceNameRef& operator=(const ResourceName& rhs);
+
+    ResourceName toResourceName() const;
+    bool isValid() const;
+
+    bool operator<(const ResourceNameRef& rhs) const;
+    bool operator==(const ResourceNameRef& rhs) const;
+    bool operator!=(const ResourceNameRef& rhs) const;
+};
+
+/**
+ * A binary identifier representing a resource. Internally it
+ * is a 32bit integer split as follows:
+ *
+ * 0xPPTTEEEE
+ *
+ * PP: 8 bit package identifier. 0x01 is reserved for system
+ *     and 0x7f is reserved for the running app.
+ * TT: 8 bit type identifier. 0x00 is invalid.
+ * EEEE: 16 bit entry identifier.
+ */
+struct ResourceId {
+    uint32_t id;
+
+    ResourceId();
+    ResourceId(const ResourceId& rhs);
+    ResourceId(uint32_t resId);
+    ResourceId(size_t p, size_t t, size_t e);
+
+    bool isValid() const;
+    uint8_t packageId() const;
+    uint8_t typeId() const;
+    uint16_t entryId() const;
+    bool operator<(const ResourceId& rhs) const;
+};
+
+//
+// ResourceId implementation.
+//
+
+inline ResourceId::ResourceId() : id(0) {
+}
+
+inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {
+}
+
+inline ResourceId::ResourceId(uint32_t resId) : id(resId) {
+}
+
+inline ResourceId::ResourceId(size_t p, size_t t, size_t e) : id(0) {
+    if (p > std::numeric_limits<uint8_t>::max() ||
+            t > std::numeric_limits<uint8_t>::max() ||
+            e > std::numeric_limits<uint16_t>::max()) {
+        // This will leave the ResourceId in an invalid state.
+        return;
+    }
+
+    id = (static_cast<uint8_t>(p) << 24) |
+         (static_cast<uint8_t>(t) << 16) |
+         static_cast<uint16_t>(e);
+}
+
+inline bool ResourceId::isValid() const {
+    return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
+}
+
+inline uint8_t ResourceId::packageId() const {
+    return static_cast<uint8_t>(id >> 24);
+}
+
+inline uint8_t ResourceId::typeId() const {
+    return static_cast<uint8_t>(id >> 16);
+}
+
+inline uint16_t ResourceId::entryId() const {
+    return static_cast<uint16_t>(id);
+}
+
+inline bool ResourceId::operator<(const ResourceId& rhs) const {
+    return id < rhs.id;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceId& resId) {
+    std::ios_base::fmtflags oldFlags = out.flags();
+    char oldFill = out.fill();
+    out << "0x" << std::internal << std::setfill('0') << std::setw(8)
+        << std::hex << resId.id;
+    out.flags(oldFlags);
+    out.fill(oldFill);
+    return out;
+}
+
+//
+// ResourceType implementation.
+//
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceType& val) {
+    return out << toString(val);
+}
+
+//
+// ResourceName implementation.
+//
+
+inline bool ResourceName::isValid() const {
+    return !package.empty() && !entry.empty();
+}
+
+inline bool ResourceName::operator<(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            < std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceName::operator==(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            == std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceName::operator!=(const ResourceName& rhs) const {
+    return std::tie(package, type, entry)
+            != std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+//
+// ResourceNameRef implementation.
+//
+
+inline ResourceNameRef::ResourceNameRef(const ResourceName& rhs) :
+        package(rhs.package), type(rhs.type), entry(rhs.entry) {
+}
+
+inline ResourceNameRef::ResourceNameRef(const StringPiece16& p, ResourceType t,
+                                        const StringPiece16& e) :
+        package(p), type(t), entry(e) {
+}
+
+inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) {
+    package = rhs.package;
+    type = rhs.type;
+    entry = rhs.entry;
+    return *this;
+}
+
+inline ResourceName ResourceNameRef::toResourceName() const {
+    return { package.toString(), type, entry.toString() };
+}
+
+inline bool ResourceNameRef::isValid() const {
+    return !package.empty() && !entry.empty();
+}
+
+inline bool ResourceNameRef::operator<(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            < std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceNameRef::operator==(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            == std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline bool ResourceNameRef::operator!=(const ResourceNameRef& rhs) const {
+    return std::tie(package, type, entry)
+            != std::tie(rhs.package, rhs.type, rhs.entry);
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out,
+        const ResourceNameRef& name) {
+    if (!name.package.empty()) {
+        out << name.package << ":";
+    }
+    return out << name.type << "/" << name.entry;
+}
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_H
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
new file mode 100644
index 0000000..d3720c4
--- /dev/null
+++ b/tools/aapt2/ResourceParser.cpp
@@ -0,0 +1,1317 @@
+/*
+ * 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 "ResourceParser.h"
+#include "ResourceValues.h"
+#include "ScopedXmlPullParser.h"
+#include "SourceXmlPullParser.h"
+#include "Util.h"
+#include "XliffXmlPullParser.h"
+
+namespace aapt {
+
+void ResourceParser::extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
+                                         StringPiece16* outType, StringPiece16* outEntry) {
+    const char16_t* start = str.data();
+    const char16_t* end = start + str.size();
+    const char16_t* current = start;
+    while (current != end) {
+        if (outType->size() == 0 && *current == u'/') {
+            outType->assign(start, current - start);
+            start = current + 1;
+        } else if (outPackage->size() == 0 && *current == u':') {
+            outPackage->assign(start, current - start);
+            start = current + 1;
+        }
+        current++;
+    }
+    outEntry->assign(start, end - start);
+}
+
+bool ResourceParser::tryParseReference(const StringPiece16& str, ResourceNameRef* outRef,
+                                       bool* outCreate, bool* outPrivate) {
+    StringPiece16 trimmedStr(util::trimWhitespace(str));
+    if (trimmedStr.empty()) {
+        return false;
+    }
+
+    if (trimmedStr.data()[0] == u'@') {
+        size_t offset = 1;
+        *outCreate = false;
+        if (trimmedStr.data()[1] == u'+') {
+            *outCreate = true;
+            offset += 1;
+        } else if (trimmedStr.data()[1] == u'*') {
+            *outPrivate = true;
+            offset += 1;
+        }
+        StringPiece16 package;
+        StringPiece16 type;
+        StringPiece16 entry;
+        extractResourceName(trimmedStr.substr(offset, trimmedStr.size() - offset),
+                            &package, &type, &entry);
+
+        const ResourceType* parsedType = parseResourceType(type);
+        if (!parsedType) {
+            return false;
+        }
+
+        if (*outCreate && *parsedType != ResourceType::kId) {
+            return false;
+        }
+
+        outRef->package = package;
+        outRef->type = *parsedType;
+        outRef->entry = entry;
+        return true;
+    }
+    return false;
+}
+
+bool ResourceParser::tryParseAttributeReference(const StringPiece16& str,
+                                                ResourceNameRef* outRef) {
+    StringPiece16 trimmedStr(util::trimWhitespace(str));
+    if (trimmedStr.empty()) {
+        return false;
+    }
+
+    if (*trimmedStr.data() == u'?') {
+        StringPiece16 package;
+        StringPiece16 type;
+        StringPiece16 entry;
+        extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1), &package, &type, &entry);
+
+        if (!type.empty() && type != u"attr") {
+            return false;
+        }
+
+        outRef->package = package;
+        outRef->type = ResourceType::kAttr;
+        outRef->entry = entry;
+        return true;
+    }
+    return false;
+}
+
+std::unique_ptr<Reference> ResourceParser::tryParseReference(const StringPiece16& str,
+                                                             const StringPiece16& defaultPackage,
+                                                             bool* outCreate) {
+    ResourceNameRef ref;
+    bool privateRef = false;
+    if (tryParseReference(str, &ref, outCreate, &privateRef)) {
+        if (ref.package.empty()) {
+            ref.package = defaultPackage;
+        }
+        std::unique_ptr<Reference> value = util::make_unique<Reference>(ref);
+        value->privateReference = privateRef;
+        return value;
+    }
+
+    if (tryParseAttributeReference(str, &ref)) {
+        if (ref.package.empty()) {
+            ref.package = defaultPackage;
+        }
+        *outCreate = false;
+        return util::make_unique<Reference>(ref, Reference::Type::kAttribute);
+    }
+    return {};
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseNullOrEmpty(const StringPiece16& str) {
+    StringPiece16 trimmedStr(util::trimWhitespace(str));
+    uint32_t data = 0;
+    if (trimmedStr == u"@null") {
+        data = android::Res_value::DATA_NULL_UNDEFINED;
+    } else if (trimmedStr == u"@empty") {
+        data = android::Res_value::DATA_NULL_EMPTY;
+    } else {
+        return {};
+    }
+
+    android::Res_value value = {};
+    value.dataType = android::Res_value::TYPE_NULL;
+    value.data = data;
+    return util::make_unique<BinaryPrimitive>(value);
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseEnumSymbol(const Attribute& enumAttr,
+                                                                    const StringPiece16& str) {
+    StringPiece16 trimmedStr(util::trimWhitespace(str));
+    for (const auto& entry : enumAttr.symbols) {
+        // Enum symbols are stored as @package:id/symbol resources,
+        // so we need to match against the 'entry' part of the identifier.
+        const ResourceName& enumSymbolResourceName = entry.symbol.name;
+        if (trimmedStr == enumSymbolResourceName.entry) {
+            android::Res_value value = {};
+            value.dataType = android::Res_value::TYPE_INT_DEC;
+            value.data = entry.value;
+            return util::make_unique<BinaryPrimitive>(value);
+        }
+    }
+    return {};
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseFlagSymbol(const Attribute& flagAttr,
+                                                                    const StringPiece16& str) {
+    android::Res_value flags = {};
+    flags.dataType = android::Res_value::TYPE_INT_DEC;
+
+    for (StringPiece16 part : util::tokenize(str, u'|')) {
+        StringPiece16 trimmedPart = util::trimWhitespace(part);
+
+        bool flagSet = false;
+        for (const auto& entry : flagAttr.symbols) {
+            // Flag symbols are stored as @package:id/symbol resources,
+            // so we need to match against the 'entry' part of the identifier.
+            const ResourceName& flagSymbolResourceName = entry.symbol.name;
+            if (trimmedPart == flagSymbolResourceName.entry) {
+                flags.data |= entry.value;
+                flagSet = true;
+                break;
+            }
+        }
+
+        if (!flagSet) {
+            return {};
+        }
+    }
+    return util::make_unique<BinaryPrimitive>(flags);
+}
+
+static uint32_t parseHex(char16_t c, bool* outError) {
+   if (c >= u'0' && c <= u'9') {
+        return c - u'0';
+    } else if (c >= u'a' && c <= u'f') {
+        return c - u'a' + 0xa;
+    } else if (c >= u'A' && c <= u'F') {
+        return c - u'A' + 0xa;
+    } else {
+        *outError = true;
+        return 0xffffffffu;
+    }
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseColor(const StringPiece16& str) {
+    StringPiece16 colorStr(util::trimWhitespace(str));
+    const char16_t* start = colorStr.data();
+    const size_t len = colorStr.size();
+    if (len == 0 || start[0] != u'#') {
+        return {};
+    }
+
+    android::Res_value value = {};
+    bool error = false;
+    if (len == 4) {
+        value.dataType = android::Res_value::TYPE_INT_COLOR_RGB4;
+        value.data = 0xff000000u;
+        value.data |= parseHex(start[1], &error) << 20;
+        value.data |= parseHex(start[1], &error) << 16;
+        value.data |= parseHex(start[2], &error) << 12;
+        value.data |= parseHex(start[2], &error) << 8;
+        value.data |= parseHex(start[3], &error) << 4;
+        value.data |= parseHex(start[3], &error);
+    } else if (len == 5) {
+        value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB4;
+        value.data |= parseHex(start[1], &error) << 28;
+        value.data |= parseHex(start[1], &error) << 24;
+        value.data |= parseHex(start[2], &error) << 20;
+        value.data |= parseHex(start[2], &error) << 16;
+        value.data |= parseHex(start[3], &error) << 12;
+        value.data |= parseHex(start[3], &error) << 8;
+        value.data |= parseHex(start[4], &error) << 4;
+        value.data |= parseHex(start[4], &error);
+    } else if (len == 7) {
+        value.dataType = android::Res_value::TYPE_INT_COLOR_RGB8;
+        value.data = 0xff000000u;
+        value.data |= parseHex(start[1], &error) << 20;
+        value.data |= parseHex(start[2], &error) << 16;
+        value.data |= parseHex(start[3], &error) << 12;
+        value.data |= parseHex(start[4], &error) << 8;
+        value.data |= parseHex(start[5], &error) << 4;
+        value.data |= parseHex(start[6], &error);
+    } else if (len == 9) {
+        value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB8;
+        value.data |= parseHex(start[1], &error) << 28;
+        value.data |= parseHex(start[2], &error) << 24;
+        value.data |= parseHex(start[3], &error) << 20;
+        value.data |= parseHex(start[4], &error) << 16;
+        value.data |= parseHex(start[5], &error) << 12;
+        value.data |= parseHex(start[6], &error) << 8;
+        value.data |= parseHex(start[7], &error) << 4;
+        value.data |= parseHex(start[8], &error);
+    } else {
+        return {};
+    }
+    return error ? std::unique_ptr<BinaryPrimitive>() : util::make_unique<BinaryPrimitive>(value);
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseBool(const StringPiece16& str) {
+    StringPiece16 trimmedStr(util::trimWhitespace(str));
+    uint32_t data = 0;
+    if (trimmedStr == u"true" || trimmedStr == u"TRUE") {
+        data = 1;
+    } else if (trimmedStr != u"false" && trimmedStr != u"FALSE") {
+        return {};
+    }
+    android::Res_value value = {};
+    value.dataType = android::Res_value::TYPE_INT_BOOLEAN;
+    value.data = data;
+    return util::make_unique<BinaryPrimitive>(value);
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseInt(const StringPiece16& str) {
+    android::Res_value value;
+    if (!android::ResTable::stringToInt(str.data(), str.size(), &value)) {
+        return {};
+    }
+    return util::make_unique<BinaryPrimitive>(value);
+}
+
+std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseFloat(const StringPiece16& str) {
+    android::Res_value value;
+    if (!android::ResTable::stringToFloat(str.data(), str.size(), &value)) {
+        return {};
+    }
+    return util::make_unique<BinaryPrimitive>(value);
+}
+
+uint32_t ResourceParser::androidTypeToAttributeTypeMask(uint16_t type) {
+    switch (type) {
+        case android::Res_value::TYPE_NULL:
+        case android::Res_value::TYPE_REFERENCE:
+        case android::Res_value::TYPE_ATTRIBUTE:
+        case android::Res_value::TYPE_DYNAMIC_REFERENCE:
+            return android::ResTable_map::TYPE_REFERENCE;
+
+        case android::Res_value::TYPE_STRING:
+            return android::ResTable_map::TYPE_STRING;
+
+        case android::Res_value::TYPE_FLOAT:
+            return android::ResTable_map::TYPE_FLOAT;
+
+        case android::Res_value::TYPE_DIMENSION:
+            return android::ResTable_map::TYPE_DIMENSION;
+
+        case android::Res_value::TYPE_FRACTION:
+            return android::ResTable_map::TYPE_FRACTION;
+
+        case android::Res_value::TYPE_INT_DEC:
+        case android::Res_value::TYPE_INT_HEX:
+            return android::ResTable_map::TYPE_INTEGER |
+                    android::ResTable_map::TYPE_ENUM |
+                    android::ResTable_map::TYPE_FLAGS;
+
+        case android::Res_value::TYPE_INT_BOOLEAN:
+            return android::ResTable_map::TYPE_BOOLEAN;
+
+        case android::Res_value::TYPE_INT_COLOR_ARGB8:
+        case android::Res_value::TYPE_INT_COLOR_RGB8:
+        case android::Res_value::TYPE_INT_COLOR_ARGB4:
+        case android::Res_value::TYPE_INT_COLOR_RGB4:
+            return android::ResTable_map::TYPE_COLOR;
+
+        default:
+            return 0;
+    };
+}
+
+std::unique_ptr<Item> ResourceParser::parseItemForAttribute(
+        const StringPiece16& value, uint32_t typeMask, const StringPiece16& defaultPackage,
+        std::function<void(const ResourceName&)> onCreateReference) {
+    std::unique_ptr<BinaryPrimitive> nullOrEmpty = tryParseNullOrEmpty(value);
+    if (nullOrEmpty) {
+        return std::move(nullOrEmpty);
+    }
+
+    bool create = false;
+    std::unique_ptr<Reference> reference = tryParseReference(value, defaultPackage, &create);
+    if (reference) {
+        if (create && onCreateReference) {
+            onCreateReference(reference->name);
+        }
+        return std::move(reference);
+    }
+
+    if (typeMask & android::ResTable_map::TYPE_COLOR) {
+        // Try parsing this as a color.
+        std::unique_ptr<BinaryPrimitive> color = tryParseColor(value);
+        if (color) {
+            return std::move(color);
+        }
+    }
+
+    if (typeMask & android::ResTable_map::TYPE_BOOLEAN) {
+        // Try parsing this as a boolean.
+        std::unique_ptr<BinaryPrimitive> boolean = tryParseBool(value);
+        if (boolean) {
+            return std::move(boolean);
+        }
+    }
+
+    if (typeMask & android::ResTable_map::TYPE_INTEGER) {
+        // Try parsing this as an integer.
+        std::unique_ptr<BinaryPrimitive> integer = tryParseInt(value);
+        if (integer) {
+            return std::move(integer);
+        }
+    }
+
+    const uint32_t floatMask = android::ResTable_map::TYPE_FLOAT |
+            android::ResTable_map::TYPE_DIMENSION |
+            android::ResTable_map::TYPE_FRACTION;
+    if (typeMask & floatMask) {
+        // Try parsing this as a float.
+        std::unique_ptr<BinaryPrimitive> floatingPoint = tryParseFloat(value);
+        if (floatingPoint) {
+            if (typeMask & androidTypeToAttributeTypeMask(floatingPoint->value.dataType)) {
+                return std::move(floatingPoint);
+            }
+        }
+    }
+    return {};
+}
+
+/**
+ * We successively try to parse the string as a resource type that the Attribute
+ * allows.
+ */
+std::unique_ptr<Item> ResourceParser::parseItemForAttribute(
+        const StringPiece16& str, const Attribute& attr, const StringPiece16& defaultPackage,
+        std::function<void(const ResourceName&)> onCreateReference) {
+    const uint32_t typeMask = attr.typeMask;
+    std::unique_ptr<Item> value = parseItemForAttribute(str, typeMask, defaultPackage,
+                                                        onCreateReference);
+    if (value) {
+        return value;
+    }
+
+    if (typeMask & android::ResTable_map::TYPE_ENUM) {
+        // Try parsing this as an enum.
+        std::unique_ptr<BinaryPrimitive> enumValue = tryParseEnumSymbol(attr, str);
+        if (enumValue) {
+            return std::move(enumValue);
+        }
+    }
+
+    if (typeMask & android::ResTable_map::TYPE_FLAGS) {
+        // Try parsing this as a flag.
+        std::unique_ptr<BinaryPrimitive> flagValue = tryParseFlagSymbol(attr, str);
+        if (flagValue) {
+            return std::move(flagValue);
+        }
+    }
+    return {};
+}
+
+ResourceParser::ResourceParser(const std::shared_ptr<ResourceTable>& table, const Source& source,
+                               const ConfigDescription& config,
+                               const std::shared_ptr<XmlPullParser>& parser) :
+        mTable(table), mSource(source), mConfig(config), mLogger(source),
+        mParser(std::make_shared<XliffXmlPullParser>(parser)) {
+}
+
+/**
+ * Build a string from XML that converts nested elements into Span objects.
+ */
+bool ResourceParser::flattenXmlSubtree(XmlPullParser* parser, std::u16string* outRawString,
+                                       StyleString* outStyleString) {
+    std::vector<Span> spanStack;
+
+    outRawString->clear();
+    outStyleString->spans.clear();
+    util::StringBuilder builder;
+    size_t depth = 1;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        const XmlPullParser::Event event = parser->getEvent();
+        if (event == XmlPullParser::Event::kEndElement) {
+            depth--;
+            if (depth == 0) {
+                break;
+            }
+
+            spanStack.back().lastChar = builder.str().size();
+            outStyleString->spans.push_back(spanStack.back());
+            spanStack.pop_back();
+
+        } else if (event == XmlPullParser::Event::kText) {
+            // TODO(adamlesinski): Verify format strings.
+            outRawString->append(parser->getText());
+            builder.append(parser->getText());
+
+        } else if (event == XmlPullParser::Event::kStartElement) {
+            if (parser->getElementNamespace().size() > 0) {
+                mLogger.warn(parser->getLineNumber())
+                        << "skipping element '"
+                        << parser->getElementName()
+                        << "' with unknown namespace '"
+                        << parser->getElementNamespace()
+                        << "'."
+                        << std::endl;
+                XmlPullParser::skipCurrentElement(parser);
+                continue;
+            }
+            depth++;
+
+            // Build a span object out of the nested element.
+            std::u16string spanName = parser->getElementName();
+            const auto endAttrIter = parser->endAttributes();
+            for (auto attrIter = parser->beginAttributes(); attrIter != endAttrIter; ++attrIter) {
+                spanName += u";";
+                spanName += attrIter->name;
+                spanName += u"=";
+                spanName += attrIter->value;
+            }
+
+            if (builder.str().size() > std::numeric_limits<uint32_t>::max()) {
+                mLogger.error(parser->getLineNumber())
+                        << "style string '"
+                        << builder.str()
+                        << "' is too long."
+                        << std::endl;
+                return false;
+            }
+            spanStack.push_back(Span{ spanName, static_cast<uint32_t>(builder.str().size()) });
+
+        } else if (event == XmlPullParser::Event::kComment) {
+            // Skip
+        } else {
+            mLogger.warn(parser->getLineNumber())
+                    << "unknown event "
+                    << event
+                    << "."
+                    << std::endl;
+        }
+    }
+    assert(spanStack.empty() && "spans haven't been fully processed");
+
+    outStyleString->str = builder.str();
+    return true;
+}
+
+bool ResourceParser::parse() {
+    while (XmlPullParser::isGoodEvent(mParser->next())) {
+        if (mParser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser parser(mParser.get());
+        if (!parser.getElementNamespace().empty() ||
+                parser.getElementName() != u"resources") {
+            mLogger.error(parser.getLineNumber())
+                    << "root element must be <resources> in the global namespace."
+                    << std::endl;
+            return false;
+        }
+
+        if (!parseResources(&parser)) {
+            return false;
+        }
+    }
+
+    if (mParser->getEvent() == XmlPullParser::Event::kBadDocument) {
+        mLogger.error(mParser->getLineNumber())
+                << mParser->getLastError()
+                << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool ResourceParser::parseResources(XmlPullParser* parser) {
+    bool success = true;
+
+    std::u16string comment;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        const XmlPullParser::Event event = parser->getEvent();
+        if (event == XmlPullParser::Event::kComment) {
+            comment = parser->getComment();
+            continue;
+        }
+
+        if (event == XmlPullParser::Event::kText) {
+            if (!util::trimWhitespace(parser->getText()).empty()) {
+                comment = u"";
+            }
+            continue;
+        }
+
+        if (event != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+
+        if (!childParser.getElementNamespace().empty()) {
+            // Skip unknown namespace.
+            continue;
+        }
+
+        StringPiece16 name = childParser.getElementName();
+        if (name == u"skip" || name == u"eat-comment") {
+            continue;
+        }
+
+        if (name == u"private-symbols") {
+            // Handle differently.
+            mLogger.note(childParser.getLineNumber())
+                    << "got a <private-symbols> tag."
+                    << std::endl;
+            continue;
+        }
+
+        const auto endAttrIter = childParser.endAttributes();
+        auto attrIter = childParser.findAttribute(u"", u"name");
+        if (attrIter == endAttrIter || attrIter->value.empty()) {
+            mLogger.error(childParser.getLineNumber())
+                    << "<" << name << "> tag must have a 'name' attribute."
+                    << std::endl;
+            success = false;
+            continue;
+        }
+
+        // Copy because our iterator will go out of scope when
+        // we parse more XML.
+        std::u16string attributeName = attrIter->value;
+
+        if (name == u"item") {
+            // Items simply have their type encoded in the type attribute.
+            auto typeIter = childParser.findAttribute(u"", u"type");
+            if (typeIter == endAttrIter || typeIter->value.empty()) {
+                mLogger.error(childParser.getLineNumber())
+                        << "<item> must have a 'type' attribute."
+                        << std::endl;
+                success = false;
+                continue;
+            }
+            name = typeIter->value;
+        }
+
+        if (name == u"id") {
+            success &= mTable->addResource(ResourceNameRef{ {}, ResourceType::kId, attributeName },
+                                           {}, mSource.line(childParser.getLineNumber()),
+                                           util::make_unique<Id>());
+        } else if (name == u"string") {
+            success &= parseString(&childParser,
+                                   ResourceNameRef{ {}, ResourceType::kString, attributeName });
+        } else if (name == u"color") {
+            success &= parseColor(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kColor, attributeName });
+        } else if (name == u"drawable") {
+            success &= parseColor(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kDrawable, attributeName });
+        } else if (name == u"bool") {
+            success &= parsePrimitive(&childParser,
+                                      ResourceNameRef{ {}, ResourceType::kBool, attributeName });
+        } else if (name == u"integer") {
+            success &= parsePrimitive(
+                    &childParser,
+                    ResourceNameRef{ {}, ResourceType::kInteger, attributeName });
+        } else if (name == u"dimen") {
+            success &= parsePrimitive(&childParser,
+                                      ResourceNameRef{ {}, ResourceType::kDimen, attributeName });
+        } else if (name == u"fraction") {
+//          success &= parsePrimitive(
+//                  &childParser,
+//                  ResourceNameRef{ {}, ResourceType::kFraction, attributeName });
+        } else if (name == u"style") {
+            success &= parseStyle(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kStyle, attributeName });
+        } else if (name == u"plurals") {
+            success &= parsePlural(&childParser,
+                                   ResourceNameRef{ {}, ResourceType::kPlurals, attributeName });
+        } else if (name == u"array") {
+            success &= parseArray(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kArray, attributeName },
+                                  android::ResTable_map::TYPE_ANY);
+        } else if (name == u"string-array") {
+            success &= parseArray(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kArray, attributeName },
+                                  android::ResTable_map::TYPE_STRING);
+        } else if (name == u"integer-array") {
+            success &= parseArray(&childParser,
+                                  ResourceNameRef{ {}, ResourceType::kArray, attributeName },
+                                  android::ResTable_map::TYPE_INTEGER);
+        } else if (name == u"public") {
+            success &= parsePublic(&childParser, attributeName);
+        } else if (name == u"declare-styleable") {
+            success &= parseDeclareStyleable(
+                    &childParser,
+                    ResourceNameRef{ {}, ResourceType::kStyleable, attributeName });
+        } else if (name == u"attr") {
+            success &= parseAttr(&childParser,
+                                 ResourceNameRef{ {}, ResourceType::kAttr, attributeName });
+        } else if (name == u"bag") {
+        } else if (name == u"public-padding") {
+        } else if (name == u"java-symbol") {
+        } else if (name == u"add-resource") {
+       }
+    }
+
+    if (parser->getEvent() == XmlPullParser::Event::kBadDocument) {
+        mLogger.error(parser->getLineNumber())
+                << parser->getLastError()
+                << std::endl;
+        return false;
+    }
+    return success;
+}
+
+
+
+enum {
+    kAllowRawString = true,
+    kNoRawString = false
+};
+
+/**
+ * Reads the entire XML subtree and attempts to parse it as some Item,
+ * with typeMask denoting which items it can be. If allowRawValue is
+ * true, a RawString is returned if the XML couldn't be parsed as
+ * an Item. If allowRawValue is false, nullptr is returned in this
+ * case.
+ */
+std::unique_ptr<Item> ResourceParser::parseXml(XmlPullParser* parser, uint32_t typeMask,
+                                               bool allowRawValue) {
+    const size_t beginXmlLine = parser->getLineNumber();
+
+    std::u16string rawValue;
+    StyleString styleString;
+    if (!flattenXmlSubtree(parser, &rawValue, &styleString)) {
+        return {};
+    }
+
+    StringPool& pool = mTable->getValueStringPool();
+
+    if (!styleString.spans.empty()) {
+        // This can only be a StyledString.
+        return util::make_unique<StyledString>(
+                pool.makeRef(styleString, StringPool::Context{ 1, mConfig }));
+    }
+
+    auto onCreateReference = [&](const ResourceName& name) {
+        mTable->addResource(name, {}, mSource.line(beginXmlLine), util::make_unique<Id>());
+    };
+
+    // Process the raw value.
+    std::unique_ptr<Item> processedItem = parseItemForAttribute(rawValue, typeMask,
+                                                                mTable->getPackage(),
+                                                                onCreateReference);
+    if (processedItem) {
+        return processedItem;
+    }
+
+    // Try making a regular string.
+    if (typeMask & android::ResTable_map::TYPE_STRING) {
+        // Use the trimmed, escaped string.
+        return util::make_unique<String>(
+                pool.makeRef(styleString.str, StringPool::Context{ 1, mConfig }));
+    }
+
+    // We can't parse this so return a RawString if we are allowed.
+    if (allowRawValue) {
+        return util::make_unique<RawString>(
+                pool.makeRef(rawValue, StringPool::Context{ 1, mConfig }));
+    }
+    return {};
+}
+
+bool ResourceParser::parseString(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+
+    // Mark the string as untranslateable if needed.
+    const auto endAttrIter = parser->endAttributes();
+    auto attrIter = parser->findAttribute(u"", u"untranslateable");
+    // bool untranslateable = attrIter != endAttrIter;
+    // TODO(adamlesinski): Do something with this (mark the string).
+
+    // Deal with the product.
+    attrIter = parser->findAttribute(u"", u"product");
+    if (attrIter != endAttrIter) {
+        if (attrIter->value != u"default" && attrIter->value != u"phone") {
+            // TODO(adamlesinski): Match products.
+            return true;
+        }
+    }
+
+    std::unique_ptr<Item> processedItem = parseXml(parser, android::ResTable_map::TYPE_STRING,
+                                                   kNoRawString);
+    if (!processedItem) {
+        mLogger.error(source.line)
+                << "not a valid string."
+                << std::endl;
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(processedItem));
+}
+
+bool ResourceParser::parseColor(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+
+    std::unique_ptr<Item> item = parseXml(parser, android::ResTable_map::TYPE_COLOR, kNoRawString);
+    if (!item) {
+        mLogger.error(source.line) << "invalid color." << std::endl;
+        return false;
+    }
+    return mTable->addResource(resourceName, mConfig, source, std::move(item));
+}
+
+bool ResourceParser::parsePrimitive(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+
+    uint32_t typeMask = 0;
+    switch (resourceName.type) {
+        case ResourceType::kInteger:
+            typeMask |= android::ResTable_map::TYPE_INTEGER;
+            break;
+
+        case ResourceType::kDimen:
+            typeMask |= android::ResTable_map::TYPE_DIMENSION
+                     | android::ResTable_map::TYPE_FLOAT
+                     | android::ResTable_map::TYPE_FRACTION;
+            break;
+
+        case ResourceType::kBool:
+            typeMask |= android::ResTable_map::TYPE_BOOLEAN;
+            break;
+
+        default:
+            assert(false);
+            break;
+    }
+
+    std::unique_ptr<Item> item = parseXml(parser, typeMask, kNoRawString);
+    if (!item) {
+        mLogger.error(source.line)
+                << "invalid "
+                << resourceName.type
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(item));
+}
+
+bool ResourceParser::parsePublic(XmlPullParser* parser, const StringPiece16& name) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+
+    const auto endAttrIter = parser->endAttributes();
+    const auto typeAttrIter = parser->findAttribute(u"", u"type");
+    if (typeAttrIter == endAttrIter || typeAttrIter->value.empty()) {
+        mLogger.error(source.line)
+                << "<public> must have a 'type' attribute."
+                << std::endl;
+        return false;
+    }
+
+    const ResourceType* parsedType = parseResourceType(typeAttrIter->value);
+    if (!parsedType) {
+        mLogger.error(source.line)
+                << "invalid resource type '"
+                << typeAttrIter->value
+                << "' in <public>."
+                << std::endl;
+        return false;
+    }
+
+    ResourceNameRef resourceName { {}, *parsedType, name };
+    ResourceId resourceId;
+
+    const auto idAttrIter = parser->findAttribute(u"", u"id");
+    if (idAttrIter != endAttrIter && !idAttrIter->value.empty()) {
+        android::Res_value val;
+        bool result = android::ResTable::stringToInt(idAttrIter->value.data(),
+                                                     idAttrIter->value.size(), &val);
+        resourceId.id = val.data;
+        if (!result || !resourceId.isValid()) {
+            mLogger.error(source.line)
+                    << "invalid resource ID '"
+                    << idAttrIter->value
+                    << "' in <public>."
+                    << std::endl;
+            return false;
+        }
+    }
+
+    if (*parsedType == ResourceType::kId) {
+        // An ID marked as public is also the definition of an ID.
+        mTable->addResource(resourceName, {}, source, util::make_unique<Id>());
+    }
+
+    return mTable->markPublic(resourceName, resourceId, source);
+}
+
+static uint32_t parseFormatType(const StringPiece16& piece) {
+    if (piece == u"reference")      return android::ResTable_map::TYPE_REFERENCE;
+    else if (piece == u"string")    return android::ResTable_map::TYPE_STRING;
+    else if (piece == u"integer")   return android::ResTable_map::TYPE_INTEGER;
+    else if (piece == u"boolean")   return android::ResTable_map::TYPE_BOOLEAN;
+    else if (piece == u"color")     return android::ResTable_map::TYPE_COLOR;
+    else if (piece == u"float")     return android::ResTable_map::TYPE_FLOAT;
+    else if (piece == u"dimension") return android::ResTable_map::TYPE_DIMENSION;
+    else if (piece == u"fraction")  return android::ResTable_map::TYPE_FRACTION;
+    else if (piece == u"enum")      return android::ResTable_map::TYPE_ENUM;
+    else if (piece == u"flags")     return android::ResTable_map::TYPE_FLAGS;
+    return 0;
+}
+
+static uint32_t parseFormatAttribute(const StringPiece16& str) {
+    uint32_t mask = 0;
+    for (StringPiece16 part : util::tokenize(str, u'|')) {
+        StringPiece16 trimmedPart = util::trimWhitespace(part);
+        uint32_t type = parseFormatType(trimmedPart);
+        if (type == 0) {
+            return 0;
+        }
+        mask |= type;
+    }
+    return mask;
+}
+
+bool ResourceParser::parseAttr(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+    std::unique_ptr<Attribute> attr = parseAttrImpl(parser, resourceName, false);
+    if (!attr) {
+        return false;
+    }
+    return mTable->addResource(resourceName, mConfig, source, std::move(attr));
+}
+
+std::unique_ptr<Attribute> ResourceParser::parseAttrImpl(XmlPullParser* parser,
+                                                         const ResourceNameRef& resourceName,
+                                                         bool weak) {
+    uint32_t typeMask = 0;
+
+    const auto endAttrIter = parser->endAttributes();
+    const auto formatAttrIter = parser->findAttribute(u"", u"format");
+    if (formatAttrIter != endAttrIter) {
+        typeMask = parseFormatAttribute(formatAttrIter->value);
+        if (typeMask == 0) {
+            mLogger.error(parser->getLineNumber())
+                    << "invalid attribute format '"
+                    << formatAttrIter->value
+                    << "'."
+                    << std::endl;
+            return {};
+        }
+    }
+
+    std::vector<Attribute::Symbol> items;
+
+    bool error = false;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+
+        const std::u16string& name = childParser.getElementName();
+        if (!childParser.getElementNamespace().empty()
+                || (name != u"flag" && name != u"enum")) {
+            mLogger.error(childParser.getLineNumber())
+                    << "unexpected tag <"
+                    << name
+                    << "> in <attr>."
+                    << std::endl;
+            error = true;
+            continue;
+        }
+
+        if (name == u"enum") {
+            if (typeMask & android::ResTable_map::TYPE_FLAGS) {
+                mLogger.error(childParser.getLineNumber())
+                        << "can not define an <enum>; already defined a <flag>."
+                        << std::endl;
+                error = true;
+                continue;
+            }
+            typeMask |= android::ResTable_map::TYPE_ENUM;
+        } else if (name == u"flag") {
+            if (typeMask & android::ResTable_map::TYPE_ENUM) {
+                mLogger.error(childParser.getLineNumber())
+                        << "can not define a <flag>; already defined an <enum>."
+                        << std::endl;
+                error = true;
+                continue;
+            }
+            typeMask |= android::ResTable_map::TYPE_FLAGS;
+        }
+
+        Attribute::Symbol item;
+        if (parseEnumOrFlagItem(&childParser, name, &item)) {
+            if (!mTable->addResource(item.symbol.name, mConfig,
+                                     mSource.line(childParser.getLineNumber()),
+                                     util::make_unique<Id>())) {
+                error = true;
+            } else {
+                items.push_back(std::move(item));
+            }
+        } else {
+            error = true;
+        }
+    }
+
+    if (error) {
+        return {};
+    }
+
+    std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak);
+    attr->symbols.swap(items);
+    attr->typeMask = typeMask ? typeMask : android::ResTable_map::TYPE_ANY;
+    return attr;
+}
+
+bool ResourceParser::parseEnumOrFlagItem(XmlPullParser* parser, const StringPiece16& tag,
+                                         Attribute::Symbol* outSymbol) {
+    const auto attrIterEnd = parser->endAttributes();
+    const auto nameAttrIter = parser->findAttribute(u"", u"name");
+    if (nameAttrIter == attrIterEnd || nameAttrIter->value.empty()) {
+        mLogger.error(parser->getLineNumber())
+                << "no attribute 'name' found for tag <" << tag << ">."
+                << std::endl;
+        return false;
+    }
+
+    const auto valueAttrIter = parser->findAttribute(u"", u"value");
+    if (valueAttrIter == attrIterEnd || valueAttrIter->value.empty()) {
+        mLogger.error(parser->getLineNumber())
+                << "no attribute 'value' found for tag <" << tag << ">."
+                << std::endl;
+        return false;
+    }
+
+    android::Res_value val;
+    if (!android::ResTable::stringToInt(valueAttrIter->value.data(),
+                                        valueAttrIter->value.size(), &val)) {
+        mLogger.error(parser->getLineNumber())
+                << "invalid value '"
+                << valueAttrIter->value
+                << "' for <" << tag << ">; must be an integer."
+                << std::endl;
+        return false;
+    }
+
+    outSymbol->symbol.name = ResourceName {
+            mTable->getPackage(), ResourceType::kId, nameAttrIter->value };
+    outSymbol->value = val.data;
+    return true;
+}
+
+static bool parseXmlAttributeName(StringPiece16 str, ResourceNameRef* outRef) {
+    str = util::trimWhitespace(str);
+    const char16_t* const start = str.data();
+    const char16_t* const end = start + str.size();
+    const char16_t* p = start;
+
+    StringPiece16 package;
+    StringPiece16 name;
+    while (p != end) {
+        if (*p == u':') {
+            package = StringPiece16(start, p - start);
+            name = StringPiece16(p + 1, end - (p + 1));
+            break;
+        }
+        p++;
+    }
+
+    outRef->package = package;
+    outRef->type = ResourceType::kAttr;
+    if (name.size() == 0) {
+        outRef->entry = str;
+    } else {
+        outRef->entry = name;
+    }
+    return true;
+}
+
+bool ResourceParser::parseUntypedItem(XmlPullParser* parser, Style& style) {
+    const auto endAttrIter = parser->endAttributes();
+    const auto nameAttrIter = parser->findAttribute(u"", u"name");
+    if (nameAttrIter == endAttrIter || nameAttrIter->value.empty()) {
+        mLogger.error(parser->getLineNumber())
+                << "<item> must have a 'name' attribute."
+                << std::endl;
+        return false;
+    }
+
+    ResourceNameRef keyRef;
+    if (!parseXmlAttributeName(nameAttrIter->value, &keyRef)) {
+        mLogger.error(parser->getLineNumber())
+                << "invalid attribute name '"
+                << nameAttrIter->value
+                << "'."
+                << std::endl;
+        return false;
+    }
+
+    if (keyRef.package.empty()) {
+        keyRef.package = mTable->getPackage();
+    }
+
+    // Create a copy instead of a reference because we
+    // are about to invalidate keyRef when advancing the parser.
+    ResourceName key = keyRef.toResourceName();
+
+    std::unique_ptr<Item> value = parseXml(parser, 0, kAllowRawString);
+    if (!value) {
+        return false;
+    }
+
+    style.entries.push_back(Style::Entry{ Reference(key), std::move(value) });
+    return true;
+}
+
+bool ResourceParser::parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+    std::unique_ptr<Style> style = util::make_unique<Style>();
+
+    const auto endAttrIter = parser->endAttributes();
+    const auto parentAttrIter = parser->findAttribute(u"", u"parent");
+    if (parentAttrIter != endAttrIter) {
+        ResourceNameRef ref;
+        bool create = false;
+        bool privateRef = false;
+        if (tryParseReference(parentAttrIter->value, &ref, &create, &privateRef)) {
+            if (create) {
+                mLogger.error(source.line)
+                        << "parent of style can not be an ID."
+                        << std::endl;
+                return false;
+            }
+            style->parent.name = ref.toResourceName();
+            style->parent.privateReference = privateRef;
+        } else if (tryParseAttributeReference(parentAttrIter->value, &ref)) {
+            style->parent.name = ref.toResourceName();
+        } else {
+            // TODO(adamlesinski): Try parsing without the '@' or '?'.
+            // Also, make sure to check the entry name for weird symbols.
+            style->parent.name = ResourceName {
+                {}, ResourceType::kStyle, parentAttrIter->value
+            };
+        }
+
+        if (style->parent.name.package.empty()) {
+            style->parent.name.package = mTable->getPackage();
+        }
+    }
+
+    bool success = true;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+        const std::u16string& name = childParser.getElementName();
+        if (name == u"item") {
+            success &= parseUntypedItem(&childParser, *style);
+        } else {
+            mLogger.error(childParser.getLineNumber())
+                    << "unexpected tag <"
+                    << name
+                    << "> in <style> resource."
+                    << std::endl;
+            success = false;
+        }
+    }
+
+    if (!success) {
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(style));
+}
+
+bool ResourceParser::parseArray(XmlPullParser* parser, const ResourceNameRef& resourceName,
+                                uint32_t typeMask) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+    std::unique_ptr<Array> array = util::make_unique<Array>();
+
+    bool error = false;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+
+        if (childParser.getElementName() != u"item") {
+            mLogger.error(childParser.getLineNumber())
+                    << "unexpected tag <"
+                    << childParser.getElementName()
+                    << "> in <array> resource."
+                    << std::endl;
+            error = true;
+            continue;
+        }
+
+        std::unique_ptr<Item> item = parseXml(&childParser, typeMask, kNoRawString);
+        if (!item) {
+            error = true;
+            continue;
+        }
+        array->items.emplace_back(std::move(item));
+    }
+
+    if (error) {
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(array));
+}
+
+bool ResourceParser::parsePlural(XmlPullParser* parser, const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+    std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+
+    bool success = true;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+
+        if (!childParser.getElementNamespace().empty() ||
+                childParser.getElementName() != u"item") {
+            success = false;
+            continue;
+        }
+
+        const auto endAttrIter = childParser.endAttributes();
+        auto attrIter = childParser.findAttribute(u"", u"quantity");
+        if (attrIter == endAttrIter || attrIter->value.empty()) {
+            mLogger.error(childParser.getLineNumber())
+                    << "<item> in <plurals> requires attribute 'quantity'."
+                    << std::endl;
+            success = false;
+            continue;
+        }
+
+        StringPiece16 trimmedQuantity = util::trimWhitespace(attrIter->value);
+        size_t index = 0;
+        if (trimmedQuantity == u"zero") {
+            index = Plural::Zero;
+        } else if (trimmedQuantity == u"one") {
+            index = Plural::One;
+        } else if (trimmedQuantity == u"two") {
+            index = Plural::Two;
+        } else if (trimmedQuantity == u"few") {
+            index = Plural::Few;
+        } else if (trimmedQuantity == u"many") {
+            index = Plural::Many;
+        } else if (trimmedQuantity == u"other") {
+            index = Plural::Other;
+        } else {
+            mLogger.error(childParser.getLineNumber())
+                    << "<item> in <plural> has invalid value '"
+                    << trimmedQuantity
+                    << "' for attribute 'quantity'."
+                    << std::endl;
+            success = false;
+            continue;
+        }
+
+        if (plural->values[index]) {
+            mLogger.error(childParser.getLineNumber())
+                    << "duplicate quantity '"
+                    << trimmedQuantity
+                    << "'."
+                    << std::endl;
+            success = false;
+            continue;
+        }
+
+        if (!(plural->values[index] = parseXml(&childParser, android::ResTable_map::TYPE_STRING,
+                                               kNoRawString))) {
+            success = false;
+        }
+    }
+
+    if (!success) {
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(plural));
+}
+
+bool ResourceParser::parseDeclareStyleable(XmlPullParser* parser,
+                                           const ResourceNameRef& resourceName) {
+    const SourceLine source = mSource.line(parser->getLineNumber());
+    std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
+
+    bool success = true;
+    while (XmlPullParser::isGoodEvent(parser->next())) {
+        if (parser->getEvent() != XmlPullParser::Event::kStartElement) {
+            continue;
+        }
+
+        ScopedXmlPullParser childParser(parser);
+
+        const std::u16string& elementName = childParser.getElementName();
+        if (elementName == u"attr") {
+            const auto endAttrIter = childParser.endAttributes();
+            auto attrIter = childParser.findAttribute(u"", u"name");
+            if (attrIter == endAttrIter || attrIter->value.empty()) {
+                mLogger.error(childParser.getLineNumber())
+                        << "<attr> tag must have a 'name' attribute."
+                        << std::endl;
+                success = false;
+                continue;
+            }
+
+            // Copy because our iterator will be invalidated.
+            std::u16string attrName = attrIter->value;
+
+            ResourceNameRef attrResourceName = {
+                    mTable->getPackage(),
+                    ResourceType::kAttr,
+                    attrName
+            };
+
+            std::unique_ptr<Attribute> attr = parseAttrImpl(&childParser, attrResourceName, true);
+            if (!attr) {
+                success = false;
+                continue;
+            }
+
+            styleable->entries.emplace_back(attrResourceName);
+
+            success &= mTable->addResource(attrResourceName, mConfig,
+                                           mSource.line(childParser.getLineNumber()),
+                                           std::move(attr));
+
+        } else if (elementName != u"eat-comment" && elementName != u"skip") {
+            mLogger.error(childParser.getLineNumber())
+                    << "<"
+                    << elementName
+                    << "> is not allowed inside <declare-styleable>."
+                    << std::endl;
+            success = false;
+        }
+    }
+
+    if (!success) {
+        return false;
+    }
+
+    return mTable->addResource(resourceName, mConfig, source, std::move(styleable));
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
new file mode 100644
index 0000000..96bba4f
--- /dev/null
+++ b/tools/aapt2/ResourceParser.h
@@ -0,0 +1,188 @@
+/*
+ * 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_RESOURCE_PARSER_H
+#define AAPT_RESOURCE_PARSER_H
+
+#include "ConfigDescription.h"
+#include "Logger.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "StringPiece.h"
+#include "StringPool.h"
+#include "XmlPullParser.h"
+
+#include <istream>
+#include <memory>
+
+namespace aapt {
+
+/*
+ * Parses an XML file for resources and adds them to a ResourceTable.
+ */
+class ResourceParser {
+public:
+    /*
+     * Extracts the package, type, and name from a string of the format:
+     *
+     *      [package:]type/name
+     *
+     * where the package can be empty. Validation must be performed on each
+     * individual extracted piece to verify that the pieces are valid.
+     */
+    static void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
+                                    StringPiece16* outType, StringPiece16* outEntry);
+
+    /*
+     * Returns true if the string was parsed as a reference (@[+][package:]type/name), with
+     * `outReference` set to the parsed reference.
+     *
+     * If '+' was present in the reference, `outCreate` is set to true.
+     * If '*' was present in the reference, `outPrivate` is set to true.
+     */
+    static bool tryParseReference(const StringPiece16& str, ResourceNameRef* outReference,
+                                  bool* outCreate, bool* outPrivate);
+
+    /*
+     * Returns true if the string was parsed as an attribute reference (?[package:]type/name),
+     * with `outReference` set to the parsed reference.
+     */
+    static bool tryParseAttributeReference(const StringPiece16& str,
+                                           ResourceNameRef* outReference);
+
+    /*
+     * Returns a Reference object if the string was parsed as a resource or attribute reference,
+     * ( @[+][package:]type/name | ?[package:]type/name )
+     * assigning defaultPackage if the package was not present in the string, and setting
+     * outCreate to true if the '+' was present in the string.
+     */
+    static std::unique_ptr<Reference> tryParseReference(const StringPiece16& str,
+                                                        const StringPiece16& defaultPackage,
+                                                        bool* outCreate);
+
+    /*
+     * Returns a BinaryPrimitve object representing @null or @empty if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing a color if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing a boolean if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing an integer if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing a floating point number
+     * (float, dimension, etc) if the string was parsed as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing an enum symbol if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute& enumAttr,
+                                                               const StringPiece16& str);
+
+    /*
+     * Returns a BinaryPrimitve object representing a flag symbol if the string was parsed
+     * as one.
+     */
+    static std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute& enumAttr,
+                                                               const StringPiece16& str);
+
+    /*
+     * Try to convert a string to an Item for the given attribute. The attribute will
+     * restrict what values the string can be converted to.
+     * The defaultPackage is used when the string is a reference with no defined package.
+     * The callback function onCreateReference is called when the parsed item is a
+     * reference to an ID that must be created (@+id/foo).
+     */
+    static std::unique_ptr<Item> parseItemForAttribute(
+            const StringPiece16& value, const Attribute& attr, const StringPiece16& defaultPackage,
+            std::function<void(const ResourceName&)> onCreateReference = {});
+
+    static std::unique_ptr<Item> parseItemForAttribute(
+            const StringPiece16& value, uint32_t typeMask, const StringPiece16& defaultPackage,
+            std::function<void(const ResourceName&)> onCreateReference = {});
+
+    static uint32_t androidTypeToAttributeTypeMask(uint16_t type);
+
+    ResourceParser(const std::shared_ptr<ResourceTable>& table, const Source& source,
+                   const ConfigDescription& config, const std::shared_ptr<XmlPullParser>& parser);
+
+    ResourceParser(const ResourceParser&) = delete; // No copy.
+
+    bool parse();
+
+private:
+    /*
+     * Parses the XML subtree as a StyleString (flattened XML representation for strings
+     * with formatting). If successful, `outStyleString`
+     * contains the escaped and whitespace trimmed text, while `outRawString`
+     * contains the unescaped text. Returns true on success.
+     */
+    bool flattenXmlSubtree(XmlPullParser* parser, std::u16string* outRawString,\
+                           StyleString* outStyleString);
+
+    /*
+     * Parses the XML subtree and converts it to an Item. The type of Item that can be
+     * parsed is denoted by the `typeMask`. If `allowRawValue` is true and the subtree
+     * can not be parsed as a regular Item, then a RawString is returned. Otherwise
+     * this returns nullptr.
+     */
+    std::unique_ptr<Item> parseXml(XmlPullParser* parser, uint32_t typeMask, bool allowRawValue);
+
+    bool parseResources(XmlPullParser* parser);
+    bool parseString(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    bool parseColor(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    bool parsePrimitive(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    bool parsePublic(XmlPullParser* parser, const StringPiece16& name);
+    bool parseAttr(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    std::unique_ptr<Attribute> parseAttrImpl(XmlPullParser* parser,
+                                             const ResourceNameRef& resourceName,
+                                             bool weak);
+    bool parseEnumOrFlagItem(XmlPullParser* parser, const StringPiece16& tag,
+                             Attribute::Symbol* outSymbol);
+    bool parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    bool parseUntypedItem(XmlPullParser* parser, Style& style);
+    bool parseDeclareStyleable(XmlPullParser* parser, const ResourceNameRef& resourceName);
+    bool parseArray(XmlPullParser* parser, const ResourceNameRef& resourceName, uint32_t typeMask);
+    bool parsePlural(XmlPullParser* parser, const ResourceNameRef& resourceName);
+
+    std::shared_ptr<ResourceTable> mTable;
+    Source mSource;
+    ConfigDescription mConfig;
+    SourceLogger mLogger;
+    std::shared_ptr<XmlPullParser> mParser;
+};
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_PARSER_H
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
new file mode 100644
index 0000000..5afbaf4
--- /dev/null
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -0,0 +1,399 @@
+/*
+ * 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 "ResourceParser.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "SourceXmlPullParser.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+
+TEST(ResourceParserReferenceTest, ParseReferenceWithNoPackage) {
+    ResourceNameRef expected = { {}, ResourceType::kColor, u"foo" };
+    ResourceNameRef actual;
+    bool create = false;
+    bool privateRef = false;
+    EXPECT_TRUE(ResourceParser::tryParseReference(u"@color/foo", &actual, &create, &privateRef));
+    EXPECT_EQ(expected, actual);
+    EXPECT_FALSE(create);
+    EXPECT_FALSE(privateRef);
+}
+
+TEST(ResourceParserReferenceTest, ParseReferenceWithPackage) {
+    ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
+    ResourceNameRef actual;
+    bool create = false;
+    bool privateRef = false;
+    EXPECT_TRUE(ResourceParser::tryParseReference(u"@android:color/foo", &actual, &create,
+                                                  &privateRef));
+    EXPECT_EQ(expected, actual);
+    EXPECT_FALSE(create);
+    EXPECT_FALSE(privateRef);
+}
+
+TEST(ResourceParserReferenceTest, ParseReferenceWithSurroundingWhitespace) {
+    ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
+    ResourceNameRef actual;
+    bool create = false;
+    bool privateRef = false;
+    EXPECT_TRUE(ResourceParser::tryParseReference(u"\t @android:color/foo\n \n\t", &actual,
+                                                  &create, &privateRef));
+    EXPECT_EQ(expected, actual);
+    EXPECT_FALSE(create);
+    EXPECT_FALSE(privateRef);
+}
+
+TEST(ResourceParserReferenceTest, ParseAutoCreateIdReference) {
+    ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
+    ResourceNameRef actual;
+    bool create = false;
+    bool privateRef = false;
+    EXPECT_TRUE(ResourceParser::tryParseReference(u"@+android:id/foo", &actual, &create,
+                                                  &privateRef));
+    EXPECT_EQ(expected, actual);
+    EXPECT_TRUE(create);
+    EXPECT_FALSE(privateRef);
+}
+
+TEST(ResourceParserReferenceTest, ParsePrivateReference) {
+    ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
+    ResourceNameRef actual;
+    bool create = false;
+    bool privateRef = false;
+    EXPECT_TRUE(ResourceParser::tryParseReference(u"@*android:id/foo", &actual, &create,
+                                                  &privateRef));
+    EXPECT_EQ(expected, actual);
+    EXPECT_FALSE(create);
+    EXPECT_TRUE(privateRef);
+}
+
+TEST(ResourceParserReferenceTest, FailToParseAutoCreateNonIdReference) {
+    bool create = false;
+    bool privateRef = false;
+    ResourceNameRef actual;
+    EXPECT_FALSE(ResourceParser::tryParseReference(u"@+android:color/foo", &actual, &create,
+                                                   &privateRef));
+}
+
+struct ResourceParserTest : public ::testing::Test {
+    virtual void SetUp() override {
+        mTable = std::make_shared<ResourceTable>();
+        mTable->setPackage(u"android");
+    }
+
+    ::testing::AssertionResult testParse(std::istream& in) {
+        std::stringstream input(kXmlPreamble);
+        input << "<resources>" << std::endl
+              << in.rdbuf() << std::endl
+              << "</resources>" << std::endl;
+        ResourceParser parser(mTable, Source{ "test" }, {},
+                              std::make_shared<SourceXmlPullParser>(input));
+        if (parser.parse()) {
+            return ::testing::AssertionSuccess();
+        }
+        return ::testing::AssertionFailure();
+    }
+
+    template <typename T>
+    const T* findResource(const ResourceNameRef& name, const ConfigDescription& config) {
+        using std::begin;
+        using std::end;
+
+        const ResourceTableType* type;
+        const ResourceEntry* entry;
+        std::tie(type, entry) = mTable->findResource(name);
+        if (!type || !entry) {
+            return nullptr;
+        }
+
+        for (const auto& configValue : entry->values) {
+            if (configValue.config == config) {
+                return dynamic_cast<const T*>(configValue.value.get());
+            }
+        }
+        return nullptr;
+    }
+
+    template <typename T>
+    const T* findResource(const ResourceNameRef& name) {
+        return findResource<T>(name, {});
+    }
+
+    std::shared_ptr<ResourceTable> mTable;
+};
+
+TEST_F(ResourceParserTest, FailToParseWithNoRootResourcesElement) {
+    std::stringstream input(kXmlPreamble);
+    input << "<attr name=\"foo\"/>" << std::endl;
+    ResourceParser parser(mTable, {}, {}, std::make_shared<SourceXmlPullParser>(input));
+    ASSERT_FALSE(parser.parse());
+}
+
+TEST_F(ResourceParserTest, ParseQuotedString) {
+    std::stringstream input("<string name=\"foo\">   \"  hey there \" </string>");
+    ASSERT_TRUE(testParse(input));
+
+    const String* str = findResource<String>(ResourceName{
+            u"android", ResourceType::kString, u"foo"});
+    ASSERT_NE(nullptr, str);
+    EXPECT_EQ(std::u16string(u"  hey there "), *str->value);
+}
+
+TEST_F(ResourceParserTest, ParseEscapedString) {
+    std::stringstream input("<string name=\"foo\">\\?123</string>");
+    ASSERT_TRUE(testParse(input));
+
+    const String* str = findResource<String>(ResourceName{
+            u"android", ResourceType::kString, u"foo" });
+    ASSERT_NE(nullptr, str);
+    EXPECT_EQ(std::u16string(u"?123"), *str->value);
+}
+
+TEST_F(ResourceParserTest, ParseAttr) {
+    std::stringstream input;
+    input << "<attr name=\"foo\" format=\"string\"/>" << std::endl
+          << "<attr name=\"bar\"/>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* attr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"foo"});
+    EXPECT_NE(nullptr, attr);
+    EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
+
+    attr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"bar"});
+    EXPECT_NE(nullptr, attr);
+    EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask);
+}
+
+TEST_F(ResourceParserTest, ParseUseAndDeclOfAttr) {
+    std::stringstream input;
+    input << "<declare-styleable name=\"Styleable\">" << std::endl
+          << "  <attr name=\"foo\" />" << std::endl
+          << "</declare-styleable>" << std::endl
+          << "<attr name=\"foo\" format=\"string\"/>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* attr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"foo"});
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
+}
+
+TEST_F(ResourceParserTest, ParseDoubleUseOfAttr) {
+    std::stringstream input;
+    input << "<declare-styleable name=\"Theme\">" << std::endl
+          << "  <attr name=\"foo\" />" << std::endl
+          << "</declare-styleable>" << std::endl
+          << "<declare-styleable name=\"Window\">" << std::endl
+          << "  <attr name=\"foo\" format=\"boolean\"/>" << std::endl
+          << "</declare-styleable>" << std::endl;
+
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* attr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"foo"});
+    ASSERT_NE(nullptr, attr);
+    EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask);
+}
+
+TEST_F(ResourceParserTest, ParseEnumAttr) {
+    std::stringstream input;
+    input << "<attr name=\"foo\">" << std::endl
+          << "  <enum name=\"bar\" value=\"0\"/>" << std::endl
+          << "  <enum name=\"bat\" value=\"1\"/>" << std::endl
+          << "  <enum name=\"baz\" value=\"2\"/>" << std::endl
+          << "</attr>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* enumAttr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"foo"});
+    ASSERT_NE(enumAttr, nullptr);
+    EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM);
+    ASSERT_EQ(enumAttr->symbols.size(), 3u);
+
+    EXPECT_EQ(enumAttr->symbols[0].symbol.name.entry, u"bar");
+    EXPECT_EQ(enumAttr->symbols[0].value, 0u);
+
+    EXPECT_EQ(enumAttr->symbols[1].symbol.name.entry, u"bat");
+    EXPECT_EQ(enumAttr->symbols[1].value, 1u);
+
+    EXPECT_EQ(enumAttr->symbols[2].symbol.name.entry, u"baz");
+    EXPECT_EQ(enumAttr->symbols[2].value, 2u);
+}
+
+TEST_F(ResourceParserTest, ParseFlagAttr) {
+    std::stringstream input;
+    input << "<attr name=\"foo\">" << std::endl
+          << "  <flag name=\"bar\" value=\"0\"/>" << std::endl
+          << "  <flag name=\"bat\" value=\"1\"/>" << std::endl
+          << "  <flag name=\"baz\" value=\"2\"/>" << std::endl
+          << "</attr>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* flagAttr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"foo"});
+    ASSERT_NE(flagAttr, nullptr);
+    EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS);
+    ASSERT_EQ(flagAttr->symbols.size(), 3u);
+
+    EXPECT_EQ(flagAttr->symbols[0].symbol.name.entry, u"bar");
+    EXPECT_EQ(flagAttr->symbols[0].value, 0u);
+
+    EXPECT_EQ(flagAttr->symbols[1].symbol.name.entry, u"bat");
+    EXPECT_EQ(flagAttr->symbols[1].value, 1u);
+
+    EXPECT_EQ(flagAttr->symbols[2].symbol.name.entry, u"baz");
+    EXPECT_EQ(flagAttr->symbols[2].value, 2u);
+
+    std::unique_ptr<BinaryPrimitive> flagValue =
+            ResourceParser::tryParseFlagSymbol(*flagAttr, u"baz|bat");
+    ASSERT_NE(flagValue, nullptr);
+    EXPECT_EQ(flagValue->value.data, 1u | 2u);
+}
+
+TEST_F(ResourceParserTest, FailToParseEnumAttrWithNonUniqueKeys) {
+    std::stringstream input;
+    input << "<attr name=\"foo\">" << std::endl
+          << "  <enum name=\"bar\" value=\"0\"/>" << std::endl
+          << "  <enum name=\"bat\" value=\"1\"/>" << std::endl
+          << "  <enum name=\"bat\" value=\"2\"/>" << std::endl
+          << "</attr>" << std::endl;
+    ASSERT_FALSE(testParse(input));
+}
+
+TEST_F(ResourceParserTest, ParseStyle) {
+    std::stringstream input;
+    input << "<style name=\"foo\" parent=\"fu\">" << std::endl
+          << "  <item name=\"bar\">#ffffffff</item>" << std::endl
+          << "  <item name=\"bat\">@string/hey</item>" << std::endl
+          << "  <item name=\"baz\"><b>hey</b></item>" << std::endl
+          << "</style>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Style* style = findResource<Style>(ResourceName{
+            u"android", ResourceType::kStyle, u"foo"});
+    ASSERT_NE(style, nullptr);
+    EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kStyle, u"fu"), style->parent.name);
+    ASSERT_EQ(style->entries.size(), 3u);
+
+    EXPECT_EQ(style->entries[0].key.name,
+              (ResourceName{ u"android", ResourceType::kAttr, u"bar" }));
+    EXPECT_EQ(style->entries[1].key.name,
+              (ResourceName{ u"android", ResourceType::kAttr, u"bat" }));
+    EXPECT_EQ(style->entries[2].key.name,
+              (ResourceName{ u"android", ResourceType::kAttr, u"baz" }));
+}
+
+TEST_F(ResourceParserTest, ParseAutoGeneratedIdReference) {
+    std::stringstream input;
+    input << "<string name=\"foo\">@+id/bar</string>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"bar"});
+    ASSERT_NE(id, nullptr);
+}
+
+TEST_F(ResourceParserTest, ParseAttributesDeclareStyleable) {
+    std::stringstream input;
+    input << "<declare-styleable name=\"foo\">" << std::endl
+          << "  <attr name=\"bar\" />" << std::endl
+          << "  <attr name=\"bat\" format=\"string|reference\"/>" << std::endl
+          << "</declare-styleable>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Attribute* attr = findResource<Attribute>(ResourceName{
+            u"android", ResourceType::kAttr, u"bar"});
+    ASSERT_NE(attr, nullptr);
+    EXPECT_TRUE(attr->isWeak());
+
+    attr = findResource<Attribute>(ResourceName{ u"android", ResourceType::kAttr, u"bat"});
+    ASSERT_NE(attr, nullptr);
+    EXPECT_TRUE(attr->isWeak());
+
+    const Styleable* styleable = findResource<Styleable>(ResourceName{
+            u"android", ResourceType::kStyleable, u"foo" });
+    ASSERT_NE(styleable, nullptr);
+    ASSERT_EQ(2u, styleable->entries.size());
+
+    EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bar"}), styleable->entries[0].name);
+    EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bat"}), styleable->entries[1].name);
+}
+
+TEST_F(ResourceParserTest, ParseArray) {
+    std::stringstream input;
+    input << "<array name=\"foo\">" << std::endl
+          << "  <item>@string/ref</item>" << std::endl
+          << "  <item>hey</item>" << std::endl
+          << "  <item>23</item>" << std::endl
+          << "</array>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const Array* array = findResource<Array>(ResourceName{
+            u"android", ResourceType::kArray, u"foo" });
+    ASSERT_NE(array, nullptr);
+    ASSERT_EQ(3u, array->items.size());
+
+    EXPECT_NE(nullptr, dynamic_cast<const Reference*>(array->items[0].get()));
+    EXPECT_NE(nullptr, dynamic_cast<const String*>(array->items[1].get()));
+    EXPECT_NE(nullptr, dynamic_cast<const BinaryPrimitive*>(array->items[2].get()));
+}
+
+TEST_F(ResourceParserTest, ParsePlural) {
+    std::stringstream input;
+    input << "<plurals name=\"foo\">" << std::endl
+          << "  <item quantity=\"other\">apples</item>" << std::endl
+          << "  <item quantity=\"one\">apple</item>" << std::endl
+          << "</plurals>" << std::endl
+          << std::endl;
+    ASSERT_TRUE(testParse(input));
+}
+
+TEST_F(ResourceParserTest, ParseCommentsWithResource) {
+    std::stringstream input;
+    input << "<!-- This is a comment -->" << std::endl
+          << "<string name=\"foo\">Hi</string>" << std::endl;
+    ASSERT_TRUE(testParse(input));
+
+    const ResourceTableType* type;
+    const ResourceEntry* entry;
+    std::tie(type, entry) = mTable->findResource(ResourceName{
+            u"android", ResourceType::kString, u"foo"});
+    ASSERT_NE(type, nullptr);
+    ASSERT_NE(entry, nullptr);
+    ASSERT_FALSE(entry->values.empty());
+    EXPECT_EQ(entry->values.front().comment, u"This is a comment");
+}
+
+/*
+ * Declaring an ID as public should not require a separate definition
+ * (as an ID has no value).
+ */
+TEST_F(ResourceParserTest, ParsePublicIdAsDefinition) {
+    std::stringstream input("<public type=\"id\" name=\"foo\"/>");
+    ASSERT_TRUE(testParse(input));
+
+    const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"foo" });
+    ASSERT_NE(nullptr, id);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
new file mode 100644
index 0000000..0b3dd78
--- /dev/null
+++ b/tools/aapt2/ResourceTable.cpp
@@ -0,0 +1,334 @@
+/*
+ * 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 "ConfigDescription.h"
+#include "Logger.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <androidfw/ResourceTypes.h>
+#include <memory>
+#include <string>
+#include <tuple>
+
+namespace aapt {
+
+static bool compareConfigs(const ResourceConfigValue& lhs, const ConfigDescription& rhs) {
+    return lhs.config < rhs;
+}
+
+static bool lessThanType(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
+    return lhs->type < rhs;
+}
+
+static bool lessThanEntry(const std::unique_ptr<ResourceEntry>& lhs, const StringPiece16& rhs) {
+    return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
+}
+
+ResourceTable::ResourceTable() : mPackageId(kUnsetPackageId) {
+}
+
+std::unique_ptr<ResourceTableType>& ResourceTable::findOrCreateType(ResourceType type) {
+    auto last = mTypes.end();
+    auto iter = std::lower_bound(mTypes.begin(), last, type, lessThanType);
+    if (iter != last) {
+        if ((*iter)->type == type) {
+            return *iter;
+        }
+    }
+    return *mTypes.emplace(iter, new ResourceTableType{ type });
+}
+
+std::unique_ptr<ResourceEntry>& ResourceTable::findOrCreateEntry(
+        std::unique_ptr<ResourceTableType>& type, const StringPiece16& name) {
+    auto last = type->entries.end();
+    auto iter = std::lower_bound(type->entries.begin(), last, name, lessThanEntry);
+    if (iter != last) {
+        if (name == (*iter)->name) {
+            return *iter;
+        }
+    }
+    return *type->entries.emplace(iter, new ResourceEntry{ name });
+}
+
+struct IsAttributeVisitor : ConstValueVisitor {
+    bool isAttribute = false;
+
+    void visit(const Attribute&, ValueVisitorArgs&) override {
+        isAttribute = true;
+    }
+
+    operator bool() {
+        return isAttribute;
+    }
+};
+
+/**
+ * The default handler for collisions. A return value of -1 means keep the
+ * existing value, 0 means fail, and +1 means take the incoming value.
+ */
+static int defaultCollisionHandler(const Value& existing, const Value& incoming) {
+    IsAttributeVisitor existingIsAttr, incomingIsAttr;
+    existing.accept(existingIsAttr, {});
+    incoming.accept(incomingIsAttr, {});
+
+    if (!incomingIsAttr) {
+        if (incoming.isWeak()) {
+            // We're trying to add a weak resource but a resource
+            // already exists. Keep the existing.
+            return -1;
+        } else if (existing.isWeak()) {
+            // Override the weak resource with the new strong resource.
+            return 1;
+        }
+        // The existing and incoming values are strong, this is an error
+        // if the values are not both attributes.
+        return 0;
+    }
+
+    if (!existingIsAttr) {
+        if (existing.isWeak()) {
+            // The existing value is not an attribute and it is weak,
+            // so take the incoming attribute value.
+            return 1;
+        }
+        // The existing value is not an attribute and it is strong,
+        // so the incoming attribute value is an error.
+        return 0;
+    }
+
+    //
+    // Attribute specific handling. At this point we know both
+    // values are attributes. Since we can declare and define
+    // attributes all-over, we do special handling to see
+    // which definition sticks.
+    //
+    const Attribute& existingAttr = static_cast<const Attribute&>(existing);
+    const Attribute& incomingAttr = static_cast<const Attribute&>(incoming);
+    if (existingAttr.typeMask == incomingAttr.typeMask) {
+        // The two attributes are both DECLs, but they are plain attributes
+        // with the same formats.
+        // Keep the strongest one.
+        return existingAttr.isWeak() ? 1 : -1;
+    }
+
+    if (existingAttr.isWeak() && existingAttr.typeMask == android::ResTable_map::TYPE_ANY) {
+        // Any incoming attribute is better than this.
+        return 1;
+    }
+
+    if (incomingAttr.isWeak() && incomingAttr.typeMask == android::ResTable_map::TYPE_ANY) {
+        // The incoming attribute may be a USE instead of a DECL.
+        // Keep the existing attribute.
+        return -1;
+    }
+    return 0;
+}
+
+static constexpr const char16_t* kValidNameChars = u"._-";
+
+bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId resId,
+        const ConfigDescription& config, const SourceLine& source,
+        std::unique_ptr<Value> value) {
+    if (!name.package.empty() && name.package != mPackage) {
+        Logger::error(source)
+                << "resource '"
+                << name
+                << "' has incompatible package. Must be '"
+                << mPackage
+                << "'."
+                << std::endl;
+        return false;
+    }
+
+    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+    if (badCharIter != name.entry.end()) {
+        Logger::error(source)
+                << "resource '"
+                << name
+                << "' has invalid entry name '"
+                << name.entry
+                << "'. Invalid character '"
+                << *badCharIter
+                << "'."
+                << std::endl;
+        return false;
+    }
+
+    std::unique_ptr<ResourceTableType>& type = findOrCreateType(name.type);
+    if (resId.isValid() && type->typeId != ResourceTableType::kUnsetTypeId &&
+            type->typeId != resId.typeId()) {
+        Logger::error(source)
+                << "trying to add resource '"
+                << name
+                << "' with ID "
+                << resId
+                << " but type '"
+                << type->type
+                << "' already has ID "
+                << std::hex << type->typeId << std::dec
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    std::unique_ptr<ResourceEntry>& entry = findOrCreateEntry(type, name.entry);
+    if (resId.isValid() && entry->entryId != ResourceEntry::kUnsetEntryId &&
+            entry->entryId != resId.entryId()) {
+        Logger::error(source)
+                << "trying to add resource '"
+                << name
+                << "' with ID "
+                << resId
+                << " but resource already has ID "
+                << ResourceId(mPackageId, type->typeId, entry->entryId)
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    const auto endIter = std::end(entry->values);
+    auto iter = std::lower_bound(std::begin(entry->values), endIter, config, compareConfigs);
+    if (iter == endIter || iter->config != config) {
+        // This resource did not exist before, add it.
+        entry->values.insert(iter, ResourceConfigValue{ config, source, {}, std::move(value) });
+    } else {
+        int collisionResult = defaultCollisionHandler(*iter->value, *value);
+        if (collisionResult > 0) {
+            // Take the incoming value.
+            *iter = ResourceConfigValue{ config, source, {}, std::move(value) };
+        } else if (collisionResult == 0) {
+            Logger::error(source)
+                    << "duplicate value for resource '" << name << "' "
+                    << "with config '" << iter->config << "'."
+                    << std::endl;
+
+            Logger::error(iter->source)
+                    << "resource previously defined here."
+                    << std::endl;
+            return false;
+        }
+    }
+
+    if (resId.isValid()) {
+        type->typeId = resId.typeId();
+        entry->entryId = resId.entryId();
+    }
+    return true;
+}
+
+bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
+                                const SourceLine& source, std::unique_ptr<Value> value) {
+    return addResource(name, ResourceId{}, config, source, std::move(value));
+}
+
+bool ResourceTable::markPublic(const ResourceNameRef& name, const ResourceId resId,
+                               const SourceLine& source) {
+    if (!name.package.empty() && name.package != mPackage) {
+        Logger::error(source)
+                << "resource '"
+                << name
+                << "' has incompatible package. Must be '"
+                << mPackage
+                << "'."
+            << std::endl;
+        return false;
+    }
+
+    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+    if (badCharIter != name.entry.end()) {
+        Logger::error(source)
+                << "resource '"
+                << name
+                << "' has invalid entry name '"
+                << name.entry
+                << "'. Invalid character '"
+                << *badCharIter
+                << "'."
+                << std::endl;
+        return false;
+    }
+
+    std::unique_ptr<ResourceTableType>& type = findOrCreateType(name.type);
+    if (resId.isValid() && type->typeId != ResourceTableType::kUnsetTypeId &&
+            type->typeId != resId.typeId()) {
+        Logger::error(source)
+                << "trying to make resource '"
+                << name
+                << "' public with ID "
+                << resId
+                << " but type '"
+                << type->type
+                << "' already has ID "
+                << std::hex << type->typeId << std::dec
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    std::unique_ptr<ResourceEntry>& entry = findOrCreateEntry(type, name.entry);
+    if (resId.isValid() && entry->entryId != ResourceEntry::kUnsetEntryId &&
+            entry->entryId != resId.entryId()) {
+        Logger::error(source)
+                << "trying to make resource '"
+                << name
+                << "' public with ID "
+                << resId
+                << " but resource already has ID "
+                << ResourceId(mPackageId, type->typeId, entry->entryId)
+                << "."
+                << std::endl;
+        return false;
+    }
+
+    type->publicStatus.isPublic = true;
+    entry->publicStatus.isPublic = true;
+
+    if (resId.isValid()) {
+        type->typeId = resId.typeId();
+        entry->entryId = resId.entryId();
+    }
+
+    if (entry->values.empty()) {
+        entry->values.push_back(ResourceConfigValue{ {}, source, {},
+                                    util::make_unique<Sentinel>() });
+    }
+    return true;
+}
+
+std::tuple<const ResourceTableType*, const ResourceEntry*>
+ResourceTable::findResource(const ResourceNameRef& name) const {
+    if (name.package != mPackage) {
+        return {nullptr, nullptr};
+    }
+
+    auto iter = std::lower_bound(mTypes.begin(), mTypes.end(), name.type, lessThanType);
+    if (iter == mTypes.end() || (*iter)->type != name.type) {
+        return {nullptr, nullptr};
+    }
+
+    const std::unique_ptr<ResourceTableType>& type = *iter;
+    auto iter2 = std::lower_bound(type->entries.begin(), type->entries.end(), name.entry,
+                                  lessThanEntry);
+    if (iter2 == type->entries.end() || name.entry != (*iter2)->name) {
+        return {nullptr, nullptr};
+    }
+    return {iter->get(), iter2->get()};
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
new file mode 100644
index 0000000..57b5213
--- /dev/null
+++ b/tools/aapt2/ResourceTable.h
@@ -0,0 +1,254 @@
+/*
+ * 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_RESOURCE_TABLE_H
+#define AAPT_RESOURCE_TABLE_H
+
+#include "ConfigDescription.h"
+#include "Resource.h"
+#include "ResourceValues.h"
+#include "Source.h"
+#include "StringPool.h"
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * The Public status of a resource.
+ */
+struct Public {
+    bool isPublic = false;
+    std::u16string comment;
+};
+
+/**
+ * The resource value for a specific configuration.
+ */
+struct ResourceConfigValue {
+    ConfigDescription config;
+    SourceLine source;
+    std::u16string comment;
+    std::unique_ptr<Value> value;
+};
+
+/**
+ * Represents a resource entry, which may have
+ * varying values for each defined configuration.
+ */
+struct ResourceEntry {
+    enum {
+        kUnsetEntryId = 0xffffffffu
+    };
+
+    /**
+     * The name of the resource. Immutable, as
+     * this determines the order of this resource
+     * when doing lookups.
+     */
+    const std::u16string name;
+
+    /**
+     * The entry ID for this resource.
+     */
+    size_t entryId;
+
+    /**
+     * Whether this resource is public (and must maintain the same
+     * entry ID across builds).
+     */
+    Public publicStatus;
+
+    /**
+     * The resource's values for each configuration.
+     */
+    std::vector<ResourceConfigValue> values;
+
+    inline ResourceEntry(const StringPiece16& _name);
+    inline ResourceEntry(const ResourceEntry* rhs);
+};
+
+/**
+ * Represents a resource type, which holds entries defined
+ * for this type.
+ */
+struct ResourceTableType {
+    enum {
+        kUnsetTypeId = 0xffffffffu
+    };
+
+    /**
+     * The logical type of resource (string, drawable, layout, etc.).
+     */
+    const ResourceType type;
+
+    /**
+     * The type ID for this resource.
+     */
+    size_t typeId;
+
+    /**
+     * Whether this type is public (and must maintain the same
+     * type ID across builds).
+     */
+    Public publicStatus;
+
+    /**
+     * List of resources for this type.
+     */
+    std::vector<std::unique_ptr<ResourceEntry>> entries;
+
+    ResourceTableType(const ResourceType _type);
+    ResourceTableType(const ResourceTableType* rhs);
+};
+
+/**
+ * The container and index for all resources defined for an app. This gets
+ * flattened into a binary resource table (resources.arsc).
+ */
+class ResourceTable {
+public:
+    using iterator = std::vector<std::unique_ptr<ResourceTableType>>::iterator;
+    using const_iterator = std::vector<std::unique_ptr<ResourceTableType>>::const_iterator;
+
+    enum {
+        kUnsetPackageId = 0xffffffff
+    };
+
+    ResourceTable();
+
+    size_t getPackageId() const;
+    void setPackageId(size_t packageId);
+
+    const std::u16string& getPackage() const;
+    void setPackage(const StringPiece16& package);
+
+    bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
+                     const SourceLine& source, std::unique_ptr<Value> value);
+
+    bool addResource(const ResourceNameRef& name, const ResourceId resId,
+                     const ConfigDescription& config, const SourceLine& source,
+                     std::unique_ptr<Value> value);
+
+    bool markPublic(const ResourceNameRef& name, const ResourceId resId, const SourceLine& source);
+
+    /**
+     * Returns the string pool used by this ResourceTable.
+     * Values that reference strings should use this pool to create
+     * their strings.
+     */
+    StringPool& getValueStringPool();
+    const StringPool& getValueStringPool() const;
+
+    std::tuple<const ResourceTableType*, const ResourceEntry*>
+    findResource(const ResourceNameRef& name) const;
+
+    iterator begin();
+    iterator end();
+    const_iterator begin() const;
+    const_iterator end() const;
+
+private:
+    std::unique_ptr<ResourceTableType>& findOrCreateType(ResourceType type);
+    std::unique_ptr<ResourceEntry>& findOrCreateEntry(std::unique_ptr<ResourceTableType>& type,
+                                                      const StringPiece16& name);
+
+    std::u16string mPackage;
+    size_t mPackageId;
+
+    // StringPool must come before mTypes so that it is destroyed after.
+    // When StringPool references are destroyed (as they will be when mTypes
+    // is destroyed), they decrement a refCount, which would cause invalid
+    // memory access if the pool was already destroyed.
+    StringPool mValuePool;
+
+    std::vector<std::unique_ptr<ResourceTableType>> mTypes;
+};
+
+//
+// ResourceEntry implementation.
+//
+
+inline ResourceEntry::ResourceEntry(const StringPiece16& _name) :
+        name(_name.toString()), entryId(kUnsetEntryId) {
+}
+
+inline ResourceEntry::ResourceEntry(const ResourceEntry* rhs) :
+        name(rhs->name), entryId(rhs->entryId), publicStatus(rhs->publicStatus) {
+}
+
+//
+// ResourceTableType implementation.
+//
+
+inline ResourceTableType::ResourceTableType(const ResourceType _type) :
+        type(_type), typeId(kUnsetTypeId) {
+}
+
+inline ResourceTableType::ResourceTableType(const ResourceTableType* rhs) :
+        type(rhs->type), typeId(rhs->typeId), publicStatus(rhs->publicStatus) {
+}
+
+//
+// ResourceTable implementation.
+//
+
+inline StringPool& ResourceTable::getValueStringPool() {
+    return mValuePool;
+}
+
+inline const StringPool& ResourceTable::getValueStringPool() const {
+    return mValuePool;
+}
+
+inline ResourceTable::iterator ResourceTable::begin() {
+    return mTypes.begin();
+}
+
+inline ResourceTable::iterator ResourceTable::end() {
+    return mTypes.end();
+}
+
+inline ResourceTable::const_iterator ResourceTable::begin() const {
+    return mTypes.begin();
+}
+
+inline ResourceTable::const_iterator ResourceTable::end() const {
+    return mTypes.end();
+}
+
+inline const std::u16string& ResourceTable::getPackage() const {
+    return mPackage;
+}
+
+inline size_t ResourceTable::getPackageId() const {
+    return mPackageId;
+}
+
+inline void ResourceTable::setPackage(const StringPiece16& package) {
+    mPackage = package.toString();
+}
+
+inline void ResourceTable::setPackageId(size_t packageId) {
+    mPackageId = packageId;
+}
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_TABLE_H
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
new file mode 100644
index 0000000..785ea15
--- /dev/null
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -0,0 +1,228 @@
+/*
+ * 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 "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <gtest/gtest.h>
+#include <ostream>
+#include <string>
+
+namespace aapt {
+
+struct TestValue : public Value {
+    std::u16string value;
+
+    TestValue(StringPiece16 str) : value(str.toString()) {
+    }
+
+    TestValue* clone() const override {
+        return new TestValue(value);
+    }
+
+    void print(std::ostream& out) const override {
+        out << "(test) " << value;
+    }
+
+    virtual void accept(ValueVisitor&, ValueVisitorArgs&&) override {}
+    virtual void accept(ConstValueVisitor&, ValueVisitorArgs&&) const override {}
+};
+
+struct TestWeakValue : public Value {
+    bool isWeak() const override {
+        return true;
+    }
+
+    TestWeakValue* clone() const override {
+        return new TestWeakValue();
+    }
+
+    void print(std::ostream& out) const override {
+        out << "(test) [weak]";
+    }
+
+    virtual void accept(ValueVisitor&, ValueVisitorArgs&&) override {}
+    virtual void accept(ConstValueVisitor&, ValueVisitorArgs&&) const override {}
+};
+
+TEST(ResourceTableTest, FailToAddResourceWithBadName) {
+    ResourceTable table;
+    table.setPackage(u"android");
+
+    EXPECT_FALSE(table.addResource(
+            ResourceNameRef{ u"android", ResourceType::kId, u"hey,there" },
+            {}, SourceLine{ "test.xml", 21 },
+            util::make_unique<TestValue>(u"rawValue")));
+
+    EXPECT_FALSE(table.addResource(
+            ResourceNameRef{ u"android", ResourceType::kId, u"hey:there" },
+            {}, SourceLine{ "test.xml", 21 },
+            util::make_unique<TestValue>(u"rawValue")));
+}
+
+TEST(ResourceTableTest, AddOneResource) {
+    const std::u16string kAndroidPackage = u"android";
+
+    ResourceTable table;
+    table.setPackage(kAndroidPackage);
+
+    const ResourceName name = { kAndroidPackage, ResourceType::kAttr, u"id" };
+
+    EXPECT_TRUE(table.addResource(name, {}, SourceLine{ "test/path/file.xml", 23 },
+                                  util::make_unique<TestValue>(u"rawValue")));
+
+    const ResourceTableType* type;
+    const ResourceEntry* entry;
+    std::tie(type, entry) = table.findResource(name);
+    ASSERT_NE(nullptr, type);
+    ASSERT_NE(nullptr, entry);
+    EXPECT_EQ(name.entry, entry->name);
+
+    ASSERT_NE(std::end(entry->values),
+              std::find_if(std::begin(entry->values), std::end(entry->values),
+                      [](const ResourceConfigValue& val) -> bool {
+                          return val.config == ConfigDescription{};
+                      }));
+}
+
+TEST(ResourceTableTest, AddMultipleResources) {
+    const std::u16string kAndroidPackage = u"android";
+    ResourceTable table;
+    table.setPackage(kAndroidPackage);
+
+    ConfigDescription config;
+    ConfigDescription languageConfig;
+    memcpy(languageConfig.language, "pl", sizeof(languageConfig.language));
+
+    EXPECT_TRUE(table.addResource(
+            ResourceName{ kAndroidPackage, ResourceType::kAttr, u"layout_width" },
+            config, SourceLine{ "test/path/file.xml", 10 },
+            util::make_unique<TestValue>(u"rawValue")));
+
+    EXPECT_TRUE(table.addResource(
+            ResourceName{ kAndroidPackage, ResourceType::kAttr, u"id" },
+            config, SourceLine{ "test/path/file.xml", 12 },
+            util::make_unique<TestValue>(u"rawValue")));
+
+    EXPECT_TRUE(table.addResource(
+            ResourceName{ kAndroidPackage, ResourceType::kString, u"ok" },
+            config, SourceLine{ "test/path/file.xml", 14 },
+            util::make_unique<TestValue>(u"Ok")));
+
+    EXPECT_TRUE(table.addResource(
+            ResourceName{ kAndroidPackage, ResourceType::kString, u"ok" },
+            languageConfig, SourceLine{ "test/path/file.xml", 20 },
+            util::make_unique<TestValue>(u"Tak")));
+
+    const auto endTypeIter = std::end(table);
+    auto typeIter = std::begin(table);
+
+    ASSERT_NE(endTypeIter, typeIter);
+    EXPECT_EQ(ResourceType::kAttr, (*typeIter)->type);
+
+    {
+        const std::unique_ptr<ResourceTableType>& type = *typeIter;
+        const auto endEntryIter = std::end(type->entries);
+        auto entryIter = std::begin(type->entries);
+        ASSERT_NE(endEntryIter, entryIter);
+        EXPECT_EQ(std::u16string(u"id"), (*entryIter)->name);
+
+        ++entryIter;
+        ASSERT_NE(endEntryIter, entryIter);
+        EXPECT_EQ(std::u16string(u"layout_width"), (*entryIter)->name);
+
+        ++entryIter;
+        ASSERT_EQ(endEntryIter, entryIter);
+    }
+
+    ++typeIter;
+    ASSERT_NE(endTypeIter, typeIter);
+    EXPECT_EQ(ResourceType::kString, (*typeIter)->type);
+
+    {
+        const std::unique_ptr<ResourceTableType>& type = *typeIter;
+        const auto endEntryIter = std::end(type->entries);
+        auto entryIter = std::begin(type->entries);
+        ASSERT_NE(endEntryIter, entryIter);
+        EXPECT_EQ(std::u16string(u"ok"), (*entryIter)->name);
+
+        {
+            const std::unique_ptr<ResourceEntry>& entry = *entryIter;
+            const auto endConfigIter = std::end(entry->values);
+            auto configIter = std::begin(entry->values);
+
+            ASSERT_NE(endConfigIter, configIter);
+            EXPECT_EQ(config, configIter->config);
+            const TestValue* value =
+                    dynamic_cast<const TestValue*>(configIter->value.get());
+            ASSERT_NE(nullptr, value);
+            EXPECT_EQ(std::u16string(u"Ok"), value->value);
+
+            ++configIter;
+            ASSERT_NE(endConfigIter, configIter);
+            EXPECT_EQ(languageConfig, configIter->config);
+            EXPECT_NE(nullptr, configIter->value);
+
+            value = dynamic_cast<const TestValue*>(configIter->value.get());
+            ASSERT_NE(nullptr, value);
+            EXPECT_EQ(std::u16string(u"Tak"), value->value);
+
+            ++configIter;
+            EXPECT_EQ(endConfigIter, configIter);
+        }
+
+        ++entryIter;
+        ASSERT_EQ(endEntryIter, entryIter);
+    }
+
+    ++typeIter;
+    EXPECT_EQ(endTypeIter, typeIter);
+}
+
+TEST(ResourceTableTest, OverrideWeakResourceValue) {
+    const std::u16string kAndroid = u"android";
+
+    ResourceTable table;
+    table.setPackage(kAndroid);
+    table.setPackageId(0x01);
+
+    ASSERT_TRUE(table.addResource(
+            ResourceName{ kAndroid, ResourceType::kAttr, u"foo" },
+            {}, {}, util::make_unique<TestWeakValue>()));
+
+    const ResourceTableType* type;
+    const ResourceEntry* entry;
+    std::tie(type, entry) = table.findResource(
+            ResourceNameRef{ kAndroid, ResourceType::kAttr, u"foo" });
+    ASSERT_NE(nullptr, type);
+    ASSERT_NE(nullptr, entry);
+    ASSERT_EQ(entry->values.size(), 1u);
+    EXPECT_TRUE(entry->values.front().value->isWeak());
+
+    ASSERT_TRUE(table.addResource(ResourceName{ kAndroid, ResourceType::kAttr, u"foo" }, {}, {},
+                                  util::make_unique<TestValue>(u"bar")));
+
+    std::tie(type, entry) = table.findResource(
+            ResourceNameRef{ kAndroid, ResourceType::kAttr, u"foo" });
+    ASSERT_NE(nullptr, type);
+    ASSERT_NE(nullptr, entry);
+    ASSERT_EQ(entry->values.size(), 1u);
+    EXPECT_FALSE(entry->values.front().value->isWeak());
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResourceTypeExtensions.h b/tools/aapt2/ResourceTypeExtensions.h
new file mode 100644
index 0000000..60e225e
--- /dev/null
+++ b/tools/aapt2/ResourceTypeExtensions.h
@@ -0,0 +1,120 @@
+/*
+ * 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_RESOURCE_TYPE_EXTENSIONS_H
+#define AAPT_RESOURCE_TYPE_EXTENSIONS_H
+
+#include <androidfw/ResourceTypes.h>
+
+namespace aapt {
+
+/**
+ * New android::ResChunk_header types defined
+ * for AAPT to use.
+ *
+ * TODO(adamlesinski): Consider reserving these
+ * enums in androidfw/ResourceTypes.h to avoid
+ * future collisions.
+ */
+enum {
+    /**
+     * A chunk that holds the string pool
+     * for source entries (path/to/source:line).
+     */
+    RES_TABLE_SOURCE_POOL_TYPE = 0x000e,
+
+    /**
+     * A chunk holding names of externally
+     * defined symbols and offsets to where
+     * they are referenced in the table.
+     */
+    RES_TABLE_SYMBOL_TABLE_TYPE = 0x000f,
+};
+
+/**
+ * New resource types that are meant to only be used
+ * by AAPT and will not end up on the device.
+ */
+struct ExtendedTypes {
+    enum {
+        /**
+         * A sentinel value used when a resource is defined as
+         * public but it has no defined value yet. If we don't
+         * flatten it with some value, we will lose its name.
+         */
+        TYPE_SENTINEL = 0xff,
+
+        /**
+         * A raw string value that hasn't had its escape sequences
+         * processed nor whitespace removed.
+         */
+        TYPE_RAW_STRING = 0xfe
+    };
+};
+
+/**
+ * A chunk with type RES_TABLE_SYMBOL_TABLE_TYPE.
+ * Following the header are count number of SymbolTable_entry
+ * structures, followed by an android::ResStringPool_header.
+ */
+struct SymbolTable_header {
+    android::ResChunk_header header;
+
+    /**
+     * Number of SymbolTable_entry structures following
+     * this header.
+     */
+    uint32_t count;
+};
+
+struct SymbolTable_entry {
+    /**
+     * Offset from the beginning of the resource table
+     * where the symbol entry is referenced.
+     */
+    uint32_t offset;
+
+    /**
+     * The index into the string pool where the name of this
+     * symbol exists.
+     */
+    uint32_t stringIndex;
+};
+
+/**
+ * A structure representing the source of a resourc entry.
+ * Appears after an android::ResTable_entry or android::ResTable_map_entry.
+ *
+ * TODO(adamlesinski): This causes some issues when runtime code checks
+ * the size of an android::ResTable_entry. It assumes it is an
+ * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry
+ * which may not be true if this structure is present.
+ */
+struct ResTable_entry_source {
+    /**
+     * Index into the source string pool.
+     */
+    uint32_t pathIndex;
+
+    /**
+     * Line number this resource was defined on.
+     */
+    uint32_t line;
+};
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_TYPE_EXTENSIONS_H
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
new file mode 100644
index 0000000..60ef1a8
--- /dev/null
+++ b/tools/aapt2/ResourceValues.cpp
@@ -0,0 +1,447 @@
+/*
+ * 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 "Resource.h"
+#include "ResourceTypeExtensions.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <limits>
+
+namespace aapt {
+
+bool Value::isItem() const {
+    return false;
+}
+
+bool Value::isWeak() const {
+    return false;
+}
+
+bool Item::isItem() const {
+    return true;
+}
+
+RawString::RawString(const StringPool::Ref& ref) : value(ref) {
+}
+
+RawString* RawString::clone() const {
+    return new RawString(value);
+}
+
+bool RawString::flatten(android::Res_value& outValue) const {
+    outValue.dataType = ExtendedTypes::TYPE_RAW_STRING;
+    outValue.data = static_cast<uint32_t>(value.getIndex());
+    return true;
+}
+
+void RawString::print(std::ostream& out) const {
+    out << "(raw string) " << *value;
+}
+
+Reference::Reference() : referenceType(Reference::Type::kResource) {
+}
+
+Reference::Reference(const ResourceNameRef& n, Type t) :
+        name(n.toResourceName()), referenceType(t) {
+}
+
+Reference::Reference(const ResourceId& i, Type type) : id(i), referenceType(type) {
+}
+
+bool Reference::flatten(android::Res_value& outValue) const {
+    outValue.dataType = (referenceType == Reference::Type::kResource)
+        ? android::Res_value::TYPE_REFERENCE
+        : android::Res_value::TYPE_ATTRIBUTE;
+    outValue.data = id.id;
+    return true;
+}
+
+Reference* Reference::clone() const {
+    Reference* ref = new Reference();
+    ref->referenceType = referenceType;
+    ref->name = name;
+    ref->id = id;
+    return ref;
+}
+
+void Reference::print(std::ostream& out) const {
+    out << "(reference) ";
+    if (referenceType == Reference::Type::kResource) {
+        out << "@";
+    } else {
+        out << "?";
+    }
+
+    if (name.isValid()) {
+        out << name;
+    }
+
+    if (id.isValid() || Res_INTERNALID(id.id)) {
+        out << " " << id;
+    }
+}
+
+bool Id::isWeak() const {
+    return true;
+}
+
+bool Id::flatten(android::Res_value& out) const {
+    out.dataType = android::Res_value::TYPE_NULL;
+    out.data = android::Res_value::DATA_NULL_UNDEFINED;
+    return true;
+}
+
+Id* Id::clone() const {
+    return new Id();
+}
+
+void Id::print(std::ostream& out) const {
+    out << "(id)";
+}
+
+String::String(const StringPool::Ref& ref) : value(ref) {
+}
+
+bool String::flatten(android::Res_value& outValue) const {
+    // Verify that our StringPool index is within encodeable limits.
+    if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+        return false;
+    }
+
+    outValue.dataType = android::Res_value::TYPE_STRING;
+    outValue.data = static_cast<uint32_t>(value.getIndex());
+    return true;
+}
+
+String* String::clone() const {
+    return new String(value);
+}
+
+void String::print(std::ostream& out) const {
+    out << "(string) \"" << *value << "\"";
+}
+
+StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {
+}
+
+bool StyledString::flatten(android::Res_value& outValue) const {
+    if (value.getIndex() > std::numeric_limits<uint32_t>::max()) {
+        return false;
+    }
+
+    outValue.dataType = android::Res_value::TYPE_STRING;
+    outValue.data = static_cast<uint32_t>(value.getIndex());
+    return true;
+}
+
+StyledString* StyledString::clone() const {
+    return new StyledString(value);
+}
+
+void StyledString::print(std::ostream& out) const {
+    out << "(styled string) \"" << *value->str << "\"";
+}
+
+FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {
+}
+
+bool FileReference::flatten(android::Res_value& outValue) const {
+    if (path.getIndex() > std::numeric_limits<uint32_t>::max()) {
+        return false;
+    }
+
+    outValue.dataType = android::Res_value::TYPE_STRING;
+    outValue.data = static_cast<uint32_t>(path.getIndex());
+    return true;
+}
+
+FileReference* FileReference::clone() const {
+    return new FileReference(path);
+}
+
+void FileReference::print(std::ostream& out) const {
+    out << "(file) " << *path;
+}
+
+BinaryPrimitive::BinaryPrimitive(const android::Res_value& val) : value(val) {
+}
+
+bool BinaryPrimitive::flatten(android::Res_value& outValue) const {
+    outValue = value;
+    return true;
+}
+
+BinaryPrimitive* BinaryPrimitive::clone() const {
+    return new BinaryPrimitive(value);
+}
+
+void BinaryPrimitive::print(std::ostream& out) const {
+    switch (value.dataType) {
+        case android::Res_value::TYPE_NULL:
+            out << "(null)";
+            break;
+        case android::Res_value::TYPE_INT_DEC:
+            out << "(integer) " << value.data;
+            break;
+        case android::Res_value::TYPE_INT_HEX:
+            out << "(integer) " << std::hex << value.data << std::dec;
+            break;
+        case android::Res_value::TYPE_INT_BOOLEAN:
+            out << "(boolean) " << (value.data != 0 ? "true" : "false");
+            break;
+        case android::Res_value::TYPE_INT_COLOR_ARGB8:
+        case android::Res_value::TYPE_INT_COLOR_RGB8:
+        case android::Res_value::TYPE_INT_COLOR_ARGB4:
+        case android::Res_value::TYPE_INT_COLOR_RGB4:
+            out << "(color) #" << std::hex << value.data << std::dec;
+            break;
+        default:
+            out << "(unknown 0x" << std::hex << (int) value.dataType << ") 0x"
+                << std::hex << value.data << std::dec;
+            break;
+    }
+}
+
+bool Sentinel::isWeak() const {
+    return true;
+}
+
+bool Sentinel::flatten(android::Res_value& outValue) const {
+    outValue.dataType = ExtendedTypes::TYPE_SENTINEL;
+    outValue.data = 0;
+    return true;
+}
+
+Sentinel* Sentinel::clone() const {
+    return new Sentinel();
+}
+
+void Sentinel::print(std::ostream& out) const {
+    out << "(sentinel)";
+    return;
+}
+
+Attribute::Attribute(bool w, uint32_t t) : weak(w), typeMask(t) {
+}
+
+bool Attribute::isWeak() const {
+    return weak;
+}
+
+Attribute* Attribute::clone() const {
+    Attribute* attr = new Attribute(weak);
+    attr->typeMask = typeMask;
+    std::copy(symbols.begin(), symbols.end(), std::back_inserter(attr->symbols));
+    return attr;
+}
+
+void Attribute::print(std::ostream& out) const {
+    out << "(attr)";
+    if (typeMask == android::ResTable_map::TYPE_ANY) {
+        out << " any";
+        return;
+    }
+
+    bool set = false;
+    if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "reference";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "string";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "integer";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "boolean";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "color";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "float";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "dimension";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "fraction";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "enum";
+    }
+
+    if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) {
+        if (!set) {
+            out << " ";
+            set = true;
+        } else {
+            out << "|";
+        }
+        out << "flags";
+    }
+
+    out << " ["
+        << util::joiner(symbols.begin(), symbols.end(), ", ")
+        << "]";
+
+    if (weak) {
+        out << " [weak]";
+    }
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
+    return out << s.symbol.name.entry << "=" << s.value;
+}
+
+Style* Style::clone() const {
+    Style* style = new Style();
+    style->parent = parent;
+    for (auto& entry : entries) {
+        style->entries.push_back(Entry{
+                entry.key,
+                std::unique_ptr<Item>(entry.value->clone())
+        });
+    }
+    return style;
+}
+
+void Style::print(std::ostream& out) const {
+    out << "(style) ";
+    if (!parent.name.entry.empty()) {
+        out << parent.name;
+    }
+    out << " ["
+        << util::joiner(entries.begin(), entries.end(), ", ")
+        << "]";
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const Style::Entry& value) {
+    out << value.key.name << " = ";
+    value.value->print(out);
+    return out;
+}
+
+Array* Array::clone() const {
+    Array* array = new Array();
+    for (auto& item : items) {
+        array->items.emplace_back(std::unique_ptr<Item>(item->clone()));
+    }
+    return array;
+}
+
+void Array::print(std::ostream& out) const {
+    out << "(array) ["
+        << util::joiner(items.begin(), items.end(), ", ")
+        << "]";
+}
+
+Plural* Plural::clone() const {
+    Plural* p = new Plural();
+    const size_t count = values.size();
+    for (size_t i = 0; i < count; i++) {
+        if (values[i]) {
+            p->values[i] = std::unique_ptr<Item>(values[i]->clone());
+        }
+    }
+    return p;
+}
+
+void Plural::print(std::ostream& out) const {
+    out << "(plural)";
+}
+
+static ::std::ostream& operator<<(::std::ostream& out, const std::unique_ptr<Item>& item) {
+    return out << *item;
+}
+
+Styleable* Styleable::clone() const {
+    Styleable* styleable = new Styleable();
+    std::copy(entries.begin(), entries.end(), std::back_inserter(styleable->entries));
+    return styleable;
+}
+
+void Styleable::print(std::ostream& out) const {
+    out << "(styleable) " << " ["
+        << util::joiner(entries.begin(), entries.end(), ", ")
+        << "]";
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
new file mode 100644
index 0000000..f25bcf0
--- /dev/null
+++ b/tools/aapt2/ResourceValues.h
@@ -0,0 +1,456 @@
+/*
+ * 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_RESOURCE_VALUES_H
+#define AAPT_RESOURCE_VALUES_H
+
+#include "Resource.h"
+#include "StringPool.h"
+
+#include <array>
+#include <androidfw/ResourceTypes.h>
+#include <ostream>
+#include <vector>
+
+namespace aapt {
+
+struct ValueVisitor;
+struct ConstValueVisitor;
+struct ValueVisitorArgs;
+
+/**
+ * A resource value. This is an all-encompassing representation
+ * of Item and Map and their subclasses. The way to do
+ * type specific operations is to check the Value's type() and
+ * cast it to the appropriate subclass. This isn't super clean,
+ * but it is the simplest strategy.
+ */
+struct Value {
+    /**
+     * Whether or not this is an Item.
+     */
+    virtual bool isItem() const;
+
+    /**
+     * Whether this value is weak and can be overriden without
+     * warning or error. Default for base class is false.
+     */
+    virtual bool isWeak() const;
+
+    /**
+     * Calls the appropriate overload of ValueVisitor.
+     */
+    virtual void accept(ValueVisitor& visitor, ValueVisitorArgs&& args) = 0;
+
+    /**
+     * Const version of accept().
+     */
+    virtual void accept(ConstValueVisitor& visitor, ValueVisitorArgs&& args) const = 0;
+
+    /**
+     * Clone the value.
+     */
+    virtual Value* clone() const = 0;
+
+    /**
+     * Human readable printout of this value.
+     */
+    virtual void print(std::ostream& out) const = 0;
+};
+
+/**
+ * Inherit from this to get visitor accepting implementations for free.
+ */
+template <typename Derived>
+struct BaseValue : public Value {
+    virtual void accept(ValueVisitor& visitor, ValueVisitorArgs&& args) override;
+    virtual void accept(ConstValueVisitor& visitor, ValueVisitorArgs&& args) const override;
+};
+
+/**
+ * A resource item with a single value. This maps to android::ResTable_entry.
+ */
+struct Item : public Value {
+    /**
+     * An Item is, of course, an Item.
+     */
+    virtual bool isItem() const override;
+
+    /**
+     * Clone the Item.
+     */
+    virtual Item* clone() const override = 0;
+
+    /**
+     * Fills in an android::Res_value structure with this Item's binary representation.
+     * Returns false if an error ocurred.
+     */
+    virtual bool flatten(android::Res_value& outValue) const = 0;
+};
+
+/**
+ * Inherit from this to get visitor accepting implementations for free.
+ */
+template <typename Derived>
+struct BaseItem : public Item {
+    virtual void accept(ValueVisitor& visitor, ValueVisitorArgs&& args) override;
+    virtual void accept(ConstValueVisitor& visitor, ValueVisitorArgs&& args) const override;
+};
+
+/**
+ * A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
+ *
+ * A reference can be symbolic (with the name set to a valid resource name) or be
+ * numeric (the id is set to a valid resource ID).
+ */
+struct Reference : public BaseItem<Reference> {
+    enum class Type {
+        kResource,
+        kAttribute,
+    };
+
+    ResourceName name;
+    ResourceId id;
+    Reference::Type referenceType;
+    bool privateReference = false;
+
+    Reference();
+    Reference(const ResourceNameRef& n, Type type = Type::kResource);
+    Reference(const ResourceId& i, Type type = Type::kResource);
+
+    bool flatten(android::Res_value& outValue) const override;
+    Reference* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+/**
+ * An ID resource. Has no real value, just a place holder.
+ */
+struct Id : public BaseItem<Id> {
+    bool isWeak() const override;
+    bool flatten(android::Res_value& out) const override;
+    Id* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+/**
+ * A raw, unprocessed string. This may contain quotations,
+ * escape sequences, and whitespace. This shall *NOT*
+ * end up in the final resource table.
+ */
+struct RawString : public BaseItem<RawString> {
+    StringPool::Ref value;
+
+    RawString(const StringPool::Ref& ref);
+
+    bool flatten(android::Res_value& outValue) const override;
+    RawString* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct String : public BaseItem<String> {
+    StringPool::Ref value;
+
+    String(const StringPool::Ref& ref);
+
+    bool flatten(android::Res_value& outValue) const override;
+    String* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct StyledString : public BaseItem<StyledString> {
+    StringPool::StyleRef value;
+
+    StyledString(const StringPool::StyleRef& ref);
+
+    bool flatten(android::Res_value& outValue) const override;
+    StyledString* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct FileReference : public BaseItem<FileReference> {
+    StringPool::Ref path;
+
+    FileReference() = default;
+    FileReference(const StringPool::Ref& path);
+
+    bool flatten(android::Res_value& outValue) const override;
+    FileReference* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+/**
+ * Represents any other android::Res_value.
+ */
+struct BinaryPrimitive : public BaseItem<BinaryPrimitive> {
+    android::Res_value value;
+
+    BinaryPrimitive() = default;
+    BinaryPrimitive(const android::Res_value& val);
+
+    bool flatten(android::Res_value& outValue) const override;
+    BinaryPrimitive* clone() const override;
+    void print(::std::ostream& out) const override;
+};
+
+/**
+ * Sentinel value that should be ignored in the final output.
+ * Mainly used as a placeholder for public entries with no
+ * values defined yet.
+ */
+struct Sentinel : public BaseItem<Sentinel> {
+    bool isWeak() const override;
+    bool flatten(android::Res_value& outValue) const override;
+    Sentinel* clone() const override;
+    void print(::std::ostream& out) const override;
+};
+
+struct Attribute : public BaseValue<Attribute> {
+    struct Symbol {
+        Reference symbol;
+        uint32_t value;
+    };
+
+    bool weak;
+    uint32_t typeMask;
+    uint32_t minInt;
+    uint32_t maxInt;
+    std::vector<Symbol> symbols;
+
+    Attribute(bool w, uint32_t t = 0u);
+
+    bool isWeak() const override;
+    virtual Attribute* clone() const override;
+    virtual void print(std::ostream& out) const override;
+};
+
+struct Style : public BaseValue<Style> {
+    struct Entry {
+        Reference key;
+        std::unique_ptr<Item> value;
+    };
+
+    Reference parent;
+    std::vector<Entry> entries;
+
+    Style* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct Array : public BaseValue<Array> {
+    std::vector<std::unique_ptr<Item>> items;
+
+    Array* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct Plural : public BaseValue<Plural> {
+    enum {
+        Zero = 0,
+        One,
+        Two,
+        Few,
+        Many,
+        Other,
+        Count
+    };
+
+    std::array<std::unique_ptr<Item>, Count> values;
+
+    Plural* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+struct Styleable : public BaseValue<Styleable> {
+    std::vector<Reference> entries;
+
+    Styleable* clone() const override;
+    void print(std::ostream& out) const override;
+};
+
+/**
+ * Stream operator for printing Value objects.
+ */
+inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
+    value.print(out);
+    return out;
+}
+
+/**
+ * The argument object that gets passed through the value
+ * back to the ValueVisitor. Subclasses of ValueVisitor should
+ * subclass ValueVisitorArgs to contain the data they need
+ * to operate.
+ */
+struct ValueVisitorArgs {};
+
+/**
+ * Visits a value and runs the appropriate method based on its type.
+ */
+struct ValueVisitor {
+    virtual void visit(Reference& reference, ValueVisitorArgs& args) {
+        visitItem(reference, args);
+    }
+
+    virtual void visit(RawString& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(String& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(StyledString& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(FileReference& file, ValueVisitorArgs& args) {
+        visitItem(file, args);
+    }
+
+    virtual void visit(Id& id, ValueVisitorArgs& args) {
+        visitItem(id, args);
+    }
+
+    virtual void visit(BinaryPrimitive& primitive, ValueVisitorArgs& args) {
+        visitItem(primitive, args);
+    }
+
+    virtual void visit(Sentinel& sentinel, ValueVisitorArgs& args) {
+        visitItem(sentinel, args);
+    }
+
+    virtual void visit(Attribute& attr, ValueVisitorArgs& args) {}
+    virtual void visit(Style& style, ValueVisitorArgs& args) {}
+    virtual void visit(Array& array, ValueVisitorArgs& args) {}
+    virtual void visit(Plural& array, ValueVisitorArgs& args) {}
+    virtual void visit(Styleable& styleable, ValueVisitorArgs& args) {}
+
+    virtual void visitItem(Item& item, ValueVisitorArgs& args) {}
+};
+
+/**
+ * Const version of ValueVisitor.
+ */
+struct ConstValueVisitor {
+    virtual void visit(const Reference& reference, ValueVisitorArgs& args) {
+        visitItem(reference, args);
+    }
+
+    virtual void visit(const RawString& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(const String& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(const StyledString& string, ValueVisitorArgs& args) {
+        visitItem(string, args);
+    }
+
+    virtual void visit(const FileReference& file, ValueVisitorArgs& args) {
+        visitItem(file, args);
+    }
+
+    virtual void visit(const Id& id, ValueVisitorArgs& args) {
+        visitItem(id, args);
+    }
+
+    virtual void visit(const BinaryPrimitive& primitive, ValueVisitorArgs& args) {
+        visitItem(primitive, args);
+    }
+
+    virtual void visit(const Sentinel& sentinel, ValueVisitorArgs& args) {
+        visitItem(sentinel, args);
+    }
+
+    virtual void visit(const Attribute& attr, ValueVisitorArgs& args) {}
+    virtual void visit(const Style& style, ValueVisitorArgs& args) {}
+    virtual void visit(const Array& array, ValueVisitorArgs& args) {}
+    virtual void visit(const Plural& array, ValueVisitorArgs& args) {}
+    virtual void visit(const Styleable& styleable, ValueVisitorArgs& args) {}
+
+    virtual void visitItem(const Item& item, ValueVisitorArgs& args) {}
+};
+
+/**
+ * Convenience Visitor that forwards a specific type to a function.
+ * Args are not used as the function can bind variables. Do not use
+ * directly, use the wrapper visitFunc() method.
+ */
+template <typename T, typename TFunc>
+struct ValueVisitorFunc : ValueVisitor {
+    TFunc func;
+
+    ValueVisitorFunc(TFunc f) : func(f) {
+    }
+
+    void visit(T& value, ValueVisitorArgs&) override {
+        func(value);
+    }
+};
+
+/**
+ * Const version of ValueVisitorFunc.
+ */
+template <typename T, typename TFunc>
+struct ConstValueVisitorFunc : ConstValueVisitor {
+    TFunc func;
+
+    ConstValueVisitorFunc(TFunc f) : func(f) {
+    }
+
+    void visit(const T& value, ValueVisitorArgs&) override {
+        func(value);
+    }
+};
+
+template <typename T, typename TFunc>
+void visitFunc(Value& value, TFunc f) {
+    ValueVisitorFunc<T, TFunc> visitor(f);
+    value.accept(visitor, ValueVisitorArgs{});
+}
+
+template <typename T, typename TFunc>
+void visitFunc(const Value& value, TFunc f) {
+    ConstValueVisitorFunc<T, TFunc> visitor(f);
+    value.accept(visitor, ValueVisitorArgs{});
+}
+
+template <typename Derived>
+void BaseValue<Derived>::accept(ValueVisitor& visitor, ValueVisitorArgs&& args) {
+    visitor.visit(static_cast<Derived&>(*this), args);
+}
+
+template <typename Derived>
+void BaseValue<Derived>::accept(ConstValueVisitor& visitor, ValueVisitorArgs&& args) const {
+    visitor.visit(static_cast<const Derived&>(*this), args);
+}
+
+template <typename Derived>
+void BaseItem<Derived>::accept(ValueVisitor& visitor, ValueVisitorArgs&& args) {
+    visitor.visit(static_cast<Derived&>(*this), args);
+}
+
+template <typename Derived>
+void BaseItem<Derived>::accept(ConstValueVisitor& visitor, ValueVisitorArgs&& args) const {
+    visitor.visit(static_cast<const Derived&>(*this), args);
+}
+
+} // namespace aapt
+
+#endif // AAPT_RESOURCE_VALUES_H
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
new file mode 100644
index 0000000..d957999
--- /dev/null
+++ b/tools/aapt2/Resource_test.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include "Resource.h"
+
+namespace aapt {
+
+TEST(ResourceTypeTest, ParseResourceTypes) {
+    const ResourceType* type = parseResourceType(u"anim");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kAnim);
+
+    type = parseResourceType(u"animator");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kAnimator);
+
+    type = parseResourceType(u"array");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kArray);
+
+    type = parseResourceType(u"attr");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kAttr);
+
+    type = parseResourceType(u"^attr-private");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kAttrPrivate);
+
+    type = parseResourceType(u"bool");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kBool);
+
+    type = parseResourceType(u"color");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kColor);
+
+    type = parseResourceType(u"dimen");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kDimen);
+
+    type = parseResourceType(u"drawable");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kDrawable);
+
+    type = parseResourceType(u"fraction");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kFraction);
+
+    type = parseResourceType(u"id");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kId);
+
+    type = parseResourceType(u"integer");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kInteger);
+
+    type = parseResourceType(u"integer-array");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kIntegerArray);
+
+    type = parseResourceType(u"interpolator");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kInterpolator);
+
+    type = parseResourceType(u"layout");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kLayout);
+
+    type = parseResourceType(u"menu");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kMenu);
+
+    type = parseResourceType(u"mipmap");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kMipmap);
+
+    type = parseResourceType(u"plurals");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kPlurals);
+
+    type = parseResourceType(u"raw");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kRaw);
+
+    type = parseResourceType(u"string");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kString);
+
+    type = parseResourceType(u"style");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kStyle);
+
+    type = parseResourceType(u"transition");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kTransition);
+
+    type = parseResourceType(u"xml");
+    ASSERT_NE(type, nullptr);
+    EXPECT_EQ(*type, ResourceType::kXml);
+
+    type = parseResourceType(u"blahaha");
+    EXPECT_EQ(type, nullptr);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ScopedXmlPullParser.cpp b/tools/aapt2/ScopedXmlPullParser.cpp
new file mode 100644
index 0000000..d9ae72c
--- /dev/null
+++ b/tools/aapt2/ScopedXmlPullParser.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 "ScopedXmlPullParser.h"
+
+#include <string>
+
+namespace aapt {
+
+ScopedXmlPullParser::ScopedXmlPullParser(XmlPullParser* parser) :
+        mParser(parser), mDepth(parser->getDepth()), mDone(false) {
+}
+
+ScopedXmlPullParser::~ScopedXmlPullParser() {
+    while (isGoodEvent(next()));
+}
+
+XmlPullParser::Event ScopedXmlPullParser::next() {
+    if (mDone) {
+        return Event::kEndDocument;
+    }
+
+    const Event event = mParser->next();
+    if (mParser->getDepth() <= mDepth) {
+        mDone = true;
+    }
+    return event;
+}
+
+XmlPullParser::Event ScopedXmlPullParser::getEvent() const {
+    return mParser->getEvent();
+}
+
+const std::string& ScopedXmlPullParser::getLastError() const {
+    return mParser->getLastError();
+}
+
+const std::u16string& ScopedXmlPullParser::getComment() const {
+    return mParser->getComment();
+}
+
+size_t ScopedXmlPullParser::getLineNumber() const {
+    return mParser->getLineNumber();
+}
+
+size_t ScopedXmlPullParser::getDepth() const {
+    const size_t depth = mParser->getDepth();
+    if (depth < mDepth) {
+        return 0;
+    }
+    return depth - mDepth;
+}
+
+const std::u16string& ScopedXmlPullParser::getText() const {
+    return mParser->getText();
+}
+
+const std::u16string& ScopedXmlPullParser::getNamespacePrefix() const {
+    return mParser->getNamespacePrefix();
+}
+
+const std::u16string& ScopedXmlPullParser::getNamespaceUri() const {
+    return mParser->getNamespaceUri();
+}
+
+const std::u16string& ScopedXmlPullParser::getElementNamespace() const {
+    return mParser->getElementNamespace();
+}
+
+const std::u16string& ScopedXmlPullParser::getElementName() const {
+    return mParser->getElementName();
+}
+
+size_t ScopedXmlPullParser::getAttributeCount() const {
+    return mParser->getAttributeCount();
+}
+
+XmlPullParser::const_iterator ScopedXmlPullParser::beginAttributes() const {
+    return mParser->beginAttributes();
+}
+
+XmlPullParser::const_iterator ScopedXmlPullParser::endAttributes() const {
+    return mParser->endAttributes();
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/ScopedXmlPullParser.h b/tools/aapt2/ScopedXmlPullParser.h
new file mode 100644
index 0000000..e660499
--- /dev/null
+++ b/tools/aapt2/ScopedXmlPullParser.h
@@ -0,0 +1,83 @@
+/*
+ * 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_SCOPED_XML_PULL_PARSER_H
+#define AAPT_SCOPED_XML_PULL_PARSER_H
+
+#include "XmlPullParser.h"
+
+#include <string>
+
+namespace aapt {
+
+/**
+ * An XmlPullParser that will not read past the depth
+ * of the underlying parser. When this parser is destroyed,
+ * it moves the underlying parser to the same depth it
+ * started with.
+ *
+ * You can write code like this:
+ *
+ *   while (XmlPullParser::isGoodEvent(parser.next())) {
+ *     if (parser.getEvent() != XmlPullParser::Event::StartElement) {
+ *       continue;
+ *     }
+ *
+ *     ScopedXmlPullParser scoped(parser);
+ *     if (parser.getElementName() == u"id") {
+ *       // do work.
+ *     } else {
+ *       // do nothing, as all the sub elements will be skipped
+ *       // when scoped goes out of scope.
+ *     }
+ *   }
+ */
+class ScopedXmlPullParser : public XmlPullParser {
+public:
+    ScopedXmlPullParser(XmlPullParser* parser);
+    ScopedXmlPullParser(const ScopedXmlPullParser&) = delete;
+    ScopedXmlPullParser& operator=(const ScopedXmlPullParser&) = delete;
+    ~ScopedXmlPullParser();
+
+    Event getEvent() const;
+    const std::string& getLastError() const;
+    Event next();
+
+    const std::u16string& getComment() const;
+    size_t getLineNumber() const;
+    size_t getDepth() const;
+
+    const std::u16string& getText() const;
+
+    const std::u16string& getNamespacePrefix() const;
+    const std::u16string& getNamespaceUri() const;
+
+    const std::u16string& getElementNamespace() const;
+    const std::u16string& getElementName() const;
+
+    const_iterator beginAttributes() const;
+    const_iterator endAttributes() const;
+    size_t getAttributeCount() const;
+
+private:
+    XmlPullParser* mParser;
+    size_t mDepth;
+    bool mDone;
+};
+
+} // namespace aapt
+
+#endif // AAPT_SCOPED_XML_PULL_PARSER_H
diff --git a/tools/aapt2/ScopedXmlPullParser_test.cpp b/tools/aapt2/ScopedXmlPullParser_test.cpp
new file mode 100644
index 0000000..342f305
--- /dev/null
+++ b/tools/aapt2/ScopedXmlPullParser_test.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 "ScopedXmlPullParser.h"
+#include "SourceXmlPullParser.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+TEST(ScopedXmlPullParserTest, StopIteratingAtNoNZeroDepth) {
+    std::stringstream input;
+    input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
+          << "<resources><string></string></resources>" << std::endl;
+
+    SourceXmlPullParser sourceParser(input);
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"string"), sourceParser.getElementName());
+
+    {
+        ScopedXmlPullParser scopedParser(&sourceParser);
+        EXPECT_EQ(XmlPullParser::Event::kEndElement, scopedParser.next());
+        EXPECT_EQ(std::u16string(u"string"), sourceParser.getElementName());
+
+        EXPECT_EQ(XmlPullParser::Event::kEndDocument, scopedParser.next());
+    }
+
+    EXPECT_EQ(XmlPullParser::Event::kEndElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kEndDocument, sourceParser.next());
+}
+
+TEST(ScopedXmlPullParserTest, FinishCurrentElementOnDestruction) {
+    std::stringstream input;
+    input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
+          << "<resources><string></string></resources>" << std::endl;
+
+    SourceXmlPullParser sourceParser(input);
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"string"), sourceParser.getElementName());
+
+    {
+        ScopedXmlPullParser scopedParser(&sourceParser);
+        EXPECT_EQ(std::u16string(u"string"), sourceParser.getElementName());
+    }
+
+    EXPECT_EQ(XmlPullParser::Event::kEndElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kEndDocument, sourceParser.next());
+}
+
+TEST(ScopedXmlPullParserTest, NestedParsersOperateCorrectly) {
+    std::stringstream input;
+    input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
+          << "<resources><string><foo></foo></string></resources>" << std::endl;
+
+    SourceXmlPullParser sourceParser(input);
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"string"), sourceParser.getElementName());
+
+    {
+        ScopedXmlPullParser scopedParser(&sourceParser);
+        EXPECT_EQ(std::u16string(u"string"), scopedParser.getElementName());
+        while (XmlPullParser::isGoodEvent(scopedParser.next())) {
+            if (scopedParser.getEvent() != XmlPullParser::Event::kStartElement) {
+                continue;
+            }
+
+            ScopedXmlPullParser subScopedParser(&scopedParser);
+            EXPECT_EQ(std::u16string(u"foo"), subScopedParser.getElementName());
+        }
+    }
+
+    EXPECT_EQ(XmlPullParser::Event::kEndElement, sourceParser.next());
+    EXPECT_EQ(std::u16string(u"resources"), sourceParser.getElementName());
+
+    EXPECT_EQ(XmlPullParser::Event::kEndDocument, sourceParser.next());
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
new file mode 100644
index 0000000..3f156a6
--- /dev/null
+++ b/tools/aapt2/SdkConstants.cpp
@@ -0,0 +1,693 @@
+/*
+ * 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 <string>
+#include <unordered_map>
+
+namespace aapt {
+
+static const std::unordered_map<std::u16string, size_t> sAttrMap = {
+    { u"marqueeRepeatLimit", 2 },
+    { u"windowNoDisplay", 3 },
+    { u"backgroundDimEnabled", 3 },
+    { u"inputType", 3 },
+    { u"isDefault", 3 },
+    { u"windowDisablePreview", 3 },
+    { u"privateImeOptions", 3 },
+    { u"editorExtras", 3 },
+    { u"settingsActivity", 3 },
+    { u"fastScrollEnabled", 3 },
+    { u"reqTouchScreen", 3 },
+    { u"reqKeyboardType", 3 },
+    { u"reqHardKeyboard", 3 },
+    { u"reqNavigation", 3 },
+    { u"windowSoftInputMode", 3 },
+    { u"imeFullscreenBackground", 3 },
+    { u"noHistory", 3 },
+    { u"headerDividersEnabled", 3 },
+    { u"footerDividersEnabled", 3 },
+    { u"candidatesTextStyleSpans", 3 },
+    { u"smoothScrollbar", 3 },
+    { u"reqFiveWayNav", 3 },
+    { u"keyBackground", 3 },
+    { u"keyTextSize", 3 },
+    { u"labelTextSize", 3 },
+    { u"keyTextColor", 3 },
+    { u"keyPreviewLayout", 3 },
+    { u"keyPreviewOffset", 3 },
+    { u"keyPreviewHeight", 3 },
+    { u"verticalCorrection", 3 },
+    { u"popupLayout", 3 },
+    { u"state_long_pressable", 3 },
+    { u"keyWidth", 3 },
+    { u"keyHeight", 3 },
+    { u"horizontalGap", 3 },
+    { u"verticalGap", 3 },
+    { u"rowEdgeFlags", 3 },
+    { u"codes", 3 },
+    { u"popupKeyboard", 3 },
+    { u"popupCharacters", 3 },
+    { u"keyEdgeFlags", 3 },
+    { u"isModifier", 3 },
+    { u"isSticky", 3 },
+    { u"isRepeatable", 3 },
+    { u"iconPreview", 3 },
+    { u"keyOutputText", 3 },
+    { u"keyLabel", 3 },
+    { u"keyIcon", 3 },
+    { u"keyboardMode", 3 },
+    { u"isScrollContainer", 3 },
+    { u"fillEnabled", 3 },
+    { u"updatePeriodMillis", 3 },
+    { u"initialLayout", 3 },
+    { u"voiceSearchMode", 3 },
+    { u"voiceLanguageModel", 3 },
+    { u"voicePromptText", 3 },
+    { u"voiceLanguage", 3 },
+    { u"voiceMaxResults", 3 },
+    { u"bottomOffset", 3 },
+    { u"topOffset", 3 },
+    { u"allowSingleTap", 3 },
+    { u"handle", 3 },
+    { u"content", 3 },
+    { u"animateOnClick", 3 },
+    { u"configure", 3 },
+    { u"hapticFeedbackEnabled", 3 },
+    { u"innerRadius", 3 },
+    { u"thickness", 3 },
+    { u"sharedUserLabel", 3 },
+    { u"dropDownWidth", 3 },
+    { u"dropDownAnchor", 3 },
+    { u"imeOptions", 3 },
+    { u"imeActionLabel", 3 },
+    { u"imeActionId", 3 },
+    { u"imeExtractEnterAnimation", 3 },
+    { u"imeExtractExitAnimation", 3 },
+    { u"tension", 4 },
+    { u"extraTension", 4 },
+    { u"anyDensity", 4 },
+    { u"searchSuggestThreshold", 4 },
+    { u"includeInGlobalSearch", 4 },
+    { u"onClick", 4 },
+    { u"targetSdkVersion", 4 },
+    { u"maxSdkVersion", 4 },
+    { u"testOnly", 4 },
+    { u"contentDescription", 4 },
+    { u"gestureStrokeWidth", 4 },
+    { u"gestureColor", 4 },
+    { u"uncertainGestureColor", 4 },
+    { u"fadeOffset", 4 },
+    { u"fadeDuration", 4 },
+    { u"gestureStrokeType", 4 },
+    { u"gestureStrokeLengthThreshold", 4 },
+    { u"gestureStrokeSquarenessThreshold", 4 },
+    { u"gestureStrokeAngleThreshold", 4 },
+    { u"eventsInterceptionEnabled", 4 },
+    { u"fadeEnabled", 4 },
+    { u"backupAgent", 4 },
+    { u"allowBackup", 4 },
+    { u"glEsVersion", 4 },
+    { u"queryAfterZeroResults", 4 },
+    { u"dropDownHeight", 4 },
+    { u"smallScreens", 4 },
+    { u"normalScreens", 4 },
+    { u"largeScreens", 4 },
+    { u"progressBarStyleInverse", 4 },
+    { u"progressBarStyleSmallInverse", 4 },
+    { u"progressBarStyleLargeInverse", 4 },
+    { u"searchSettingsDescription", 4 },
+    { u"textColorPrimaryInverseDisableOnly", 4 },
+    { u"autoUrlDetect", 4 },
+    { u"resizeable", 4 },
+    { u"required", 5 },
+    { u"accountType", 5 },
+    { u"contentAuthority", 5 },
+    { u"userVisible", 5 },
+    { u"windowShowWallpaper", 5 },
+    { u"wallpaperOpenEnterAnimation", 5 },
+    { u"wallpaperOpenExitAnimation", 5 },
+    { u"wallpaperCloseEnterAnimation", 5 },
+    { u"wallpaperCloseExitAnimation", 5 },
+    { u"wallpaperIntraOpenEnterAnimation", 5 },
+    { u"wallpaperIntraOpenExitAnimation", 5 },
+    { u"wallpaperIntraCloseEnterAnimation", 5 },
+    { u"wallpaperIntraCloseExitAnimation", 5 },
+    { u"supportsUploading", 5 },
+    { u"killAfterRestore", 5 },
+    { u"restoreNeedsApplication", 5 },
+    { u"smallIcon", 5 },
+    { u"accountPreferences", 5 },
+    { u"textAppearanceSearchResultSubtitle", 5 },
+    { u"textAppearanceSearchResultTitle", 5 },
+    { u"summaryColumn", 5 },
+    { u"detailColumn", 5 },
+    { u"detailSocialSummary", 5 },
+    { u"thumbnail", 5 },
+    { u"detachWallpaper", 5 },
+    { u"finishOnCloseSystemDialogs", 5 },
+    { u"scrollbarFadeDuration", 5 },
+    { u"scrollbarDefaultDelayBeforeFade", 5 },
+    { u"fadeScrollbars", 5 },
+    { u"colorBackgroundCacheHint", 5 },
+    { u"dropDownHorizontalOffset", 5 },
+    { u"dropDownVerticalOffset", 5 },
+    { u"quickContactBadgeStyleWindowSmall", 6 },
+    { u"quickContactBadgeStyleWindowMedium", 6 },
+    { u"quickContactBadgeStyleWindowLarge", 6 },
+    { u"quickContactBadgeStyleSmallWindowSmall", 6 },
+    { u"quickContactBadgeStyleSmallWindowMedium", 6 },
+    { u"quickContactBadgeStyleSmallWindowLarge", 6 },
+    { u"author", 7 },
+    { u"autoStart", 7 },
+    { u"expandableListViewWhiteStyle", 8 },
+    { u"installLocation", 8 },
+    { u"vmSafeMode", 8 },
+    { u"webTextViewStyle", 8 },
+    { u"restoreAnyVersion", 8 },
+    { u"tabStripLeft", 8 },
+    { u"tabStripRight", 8 },
+    { u"tabStripEnabled", 8 },
+    { u"logo", 9 },
+    { u"xlargeScreens", 9 },
+    { u"immersive", 9 },
+    { u"overScrollMode", 9 },
+    { u"overScrollHeader", 9 },
+    { u"overScrollFooter", 9 },
+    { u"filterTouchesWhenObscured", 9 },
+    { u"textSelectHandleLeft", 9 },
+    { u"textSelectHandleRight", 9 },
+    { u"textSelectHandle", 9 },
+    { u"textSelectHandleWindowStyle", 9 },
+    { u"popupAnimationStyle", 9 },
+    { u"screenSize", 9 },
+    { u"screenDensity", 9 },
+    { u"allContactsName", 11 },
+    { u"windowActionBar", 11 },
+    { u"actionBarStyle", 11 },
+    { u"navigationMode", 11 },
+    { u"displayOptions", 11 },
+    { u"subtitle", 11 },
+    { u"customNavigationLayout", 11 },
+    { u"hardwareAccelerated", 11 },
+    { u"measureWithLargestChild", 11 },
+    { u"animateFirstView", 11 },
+    { u"dropDownSpinnerStyle", 11 },
+    { u"actionDropDownStyle", 11 },
+    { u"actionButtonStyle", 11 },
+    { u"showAsAction", 11 },
+    { u"previewImage", 11 },
+    { u"actionModeBackground", 11 },
+    { u"actionModeCloseDrawable", 11 },
+    { u"windowActionModeOverlay", 11 },
+    { u"valueFrom", 11 },
+    { u"valueTo", 11 },
+    { u"valueType", 11 },
+    { u"propertyName", 11 },
+    { u"ordering", 11 },
+    { u"fragment", 11 },
+    { u"windowActionBarOverlay", 11 },
+    { u"fragmentOpenEnterAnimation", 11 },
+    { u"fragmentOpenExitAnimation", 11 },
+    { u"fragmentCloseEnterAnimation", 11 },
+    { u"fragmentCloseExitAnimation", 11 },
+    { u"fragmentFadeEnterAnimation", 11 },
+    { u"fragmentFadeExitAnimation", 11 },
+    { u"actionBarSize", 11 },
+    { u"imeSubtypeLocale", 11 },
+    { u"imeSubtypeMode", 11 },
+    { u"imeSubtypeExtraValue", 11 },
+    { u"splitMotionEvents", 11 },
+    { u"listChoiceBackgroundIndicator", 11 },
+    { u"spinnerMode", 11 },
+    { u"animateLayoutChanges", 11 },
+    { u"actionBarTabStyle", 11 },
+    { u"actionBarTabBarStyle", 11 },
+    { u"actionBarTabTextStyle", 11 },
+    { u"actionOverflowButtonStyle", 11 },
+    { u"actionModeCloseButtonStyle", 11 },
+    { u"titleTextStyle", 11 },
+    { u"subtitleTextStyle", 11 },
+    { u"iconifiedByDefault", 11 },
+    { u"actionLayout", 11 },
+    { u"actionViewClass", 11 },
+    { u"activatedBackgroundIndicator", 11 },
+    { u"state_activated", 11 },
+    { u"listPopupWindowStyle", 11 },
+    { u"popupMenuStyle", 11 },
+    { u"textAppearanceLargePopupMenu", 11 },
+    { u"textAppearanceSmallPopupMenu", 11 },
+    { u"breadCrumbTitle", 11 },
+    { u"breadCrumbShortTitle", 11 },
+    { u"listDividerAlertDialog", 11 },
+    { u"textColorAlertDialogListItem", 11 },
+    { u"loopViews", 11 },
+    { u"dialogTheme", 11 },
+    { u"alertDialogTheme", 11 },
+    { u"dividerVertical", 11 },
+    { u"homeAsUpIndicator", 11 },
+    { u"enterFadeDuration", 11 },
+    { u"exitFadeDuration", 11 },
+    { u"selectableItemBackground", 11 },
+    { u"autoAdvanceViewId", 11 },
+    { u"useIntrinsicSizeAsMinimum", 11 },
+    { u"actionModeCutDrawable", 11 },
+    { u"actionModeCopyDrawable", 11 },
+    { u"actionModePasteDrawable", 11 },
+    { u"textEditPasteWindowLayout", 11 },
+    { u"textEditNoPasteWindowLayout", 11 },
+    { u"textIsSelectable", 11 },
+    { u"windowEnableSplitTouch", 11 },
+    { u"indeterminateProgressStyle", 11 },
+    { u"progressBarPadding", 11 },
+    { u"animationResolution", 11 },
+    { u"state_accelerated", 11 },
+    { u"baseline", 11 },
+    { u"homeLayout", 11 },
+    { u"opacity", 11 },
+    { u"alpha", 11 },
+    { u"transformPivotX", 11 },
+    { u"transformPivotY", 11 },
+    { u"translationX", 11 },
+    { u"translationY", 11 },
+    { u"scaleX", 11 },
+    { u"scaleY", 11 },
+    { u"rotation", 11 },
+    { u"rotationX", 11 },
+    { u"rotationY", 11 },
+    { u"showDividers", 11 },
+    { u"dividerPadding", 11 },
+    { u"borderlessButtonStyle", 11 },
+    { u"dividerHorizontal", 11 },
+    { u"itemPadding", 11 },
+    { u"buttonBarStyle", 11 },
+    { u"buttonBarButtonStyle", 11 },
+    { u"segmentedButtonStyle", 11 },
+    { u"staticWallpaperPreview", 11 },
+    { u"allowParallelSyncs", 11 },
+    { u"isAlwaysSyncable", 11 },
+    { u"verticalScrollbarPosition", 11 },
+    { u"fastScrollAlwaysVisible", 11 },
+    { u"fastScrollThumbDrawable", 11 },
+    { u"fastScrollPreviewBackgroundLeft", 11 },
+    { u"fastScrollPreviewBackgroundRight", 11 },
+    { u"fastScrollTrackDrawable", 11 },
+    { u"fastScrollOverlayPosition", 11 },
+    { u"customTokens", 11 },
+    { u"nextFocusForward", 11 },
+    { u"firstDayOfWeek", 11 },
+    { u"showWeekNumber", 11 },
+    { u"minDate", 11 },
+    { u"maxDate", 11 },
+    { u"shownWeekCount", 11 },
+    { u"selectedWeekBackgroundColor", 11 },
+    { u"focusedMonthDateColor", 11 },
+    { u"unfocusedMonthDateColor", 11 },
+    { u"weekNumberColor", 11 },
+    { u"weekSeparatorLineColor", 11 },
+    { u"selectedDateVerticalBar", 11 },
+    { u"weekDayTextAppearance", 11 },
+    { u"dateTextAppearance", 11 },
+    { u"solidColor", 11 },
+    { u"spinnersShown", 11 },
+    { u"calendarViewShown", 11 },
+    { u"state_multiline", 11 },
+    { u"detailsElementBackground", 11 },
+    { u"textColorHighlightInverse", 11 },
+    { u"textColorLinkInverse", 11 },
+    { u"editTextColor", 11 },
+    { u"editTextBackground", 11 },
+    { u"horizontalScrollViewStyle", 11 },
+    { u"layerType", 11 },
+    { u"alertDialogIcon", 11 },
+    { u"windowMinWidthMajor", 11 },
+    { u"windowMinWidthMinor", 11 },
+    { u"queryHint", 11 },
+    { u"fastScrollTextColor", 11 },
+    { u"largeHeap", 11 },
+    { u"windowCloseOnTouchOutside", 11 },
+    { u"datePickerStyle", 11 },
+    { u"calendarViewStyle", 11 },
+    { u"textEditSidePasteWindowLayout", 11 },
+    { u"textEditSideNoPasteWindowLayout", 11 },
+    { u"actionMenuTextAppearance", 11 },
+    { u"actionMenuTextColor", 11 },
+    { u"textCursorDrawable", 12 },
+    { u"resizeMode", 12 },
+    { u"requiresSmallestWidthDp", 12 },
+    { u"compatibleWidthLimitDp", 12 },
+    { u"largestWidthLimitDp", 12 },
+    { u"state_hovered", 13 },
+    { u"state_drag_can_accept", 13 },
+    { u"state_drag_hovered", 13 },
+    { u"stopWithTask", 13 },
+    { u"switchTextOn", 13 },
+    { u"switchTextOff", 13 },
+    { u"switchPreferenceStyle", 13 },
+    { u"switchTextAppearance", 13 },
+    { u"track", 13 },
+    { u"switchMinWidth", 13 },
+    { u"switchPadding", 13 },
+    { u"thumbTextPadding", 13 },
+    { u"textSuggestionsWindowStyle", 13 },
+    { u"textEditSuggestionItemLayout", 13 },
+    { u"rowCount", 13 },
+    { u"rowOrderPreserved", 13 },
+    { u"columnCount", 13 },
+    { u"columnOrderPreserved", 13 },
+    { u"useDefaultMargins", 13 },
+    { u"alignmentMode", 13 },
+    { u"layout_row", 13 },
+    { u"layout_rowSpan", 13 },
+    { u"layout_columnSpan", 13 },
+    { u"actionModeSelectAllDrawable", 13 },
+    { u"isAuxiliary", 13 },
+    { u"accessibilityEventTypes", 13 },
+    { u"packageNames", 13 },
+    { u"accessibilityFeedbackType", 13 },
+    { u"notificationTimeout", 13 },
+    { u"accessibilityFlags", 13 },
+    { u"canRetrieveWindowContent", 13 },
+    { u"listPreferredItemHeightLarge", 13 },
+    { u"listPreferredItemHeightSmall", 13 },
+    { u"actionBarSplitStyle", 13 },
+    { u"actionProviderClass", 13 },
+    { u"backgroundStacked", 13 },
+    { u"backgroundSplit", 13 },
+    { u"textAllCaps", 13 },
+    { u"colorPressedHighlight", 13 },
+    { u"colorLongPressedHighlight", 13 },
+    { u"colorFocusedHighlight", 13 },
+    { u"colorActivatedHighlight", 13 },
+    { u"colorMultiSelectHighlight", 13 },
+    { u"drawableStart", 13 },
+    { u"drawableEnd", 13 },
+    { u"actionModeStyle", 13 },
+    { u"minResizeWidth", 13 },
+    { u"minResizeHeight", 13 },
+    { u"actionBarWidgetTheme", 13 },
+    { u"uiOptions", 13 },
+    { u"subtypeLocale", 13 },
+    { u"subtypeExtraValue", 13 },
+    { u"actionBarDivider", 13 },
+    { u"actionBarItemBackground", 13 },
+    { u"actionModeSplitBackground", 13 },
+    { u"textAppearanceListItem", 13 },
+    { u"textAppearanceListItemSmall", 13 },
+    { u"targetDescriptions", 13 },
+    { u"directionDescriptions", 13 },
+    { u"overridesImplicitlyEnabledSubtype", 13 },
+    { u"listPreferredItemPaddingLeft", 13 },
+    { u"listPreferredItemPaddingRight", 13 },
+    { u"requiresFadingEdge", 13 },
+    { u"publicKey", 13 },
+    { u"parentActivityName", 16 },
+    { u"isolatedProcess", 16 },
+    { u"importantForAccessibility", 16 },
+    { u"keyboardLayout", 16 },
+    { u"fontFamily", 16 },
+    { u"mediaRouteButtonStyle", 16 },
+    { u"mediaRouteTypes", 16 },
+    { u"supportsRtl", 17 },
+    { u"textDirection", 17 },
+    { u"textAlignment", 17 },
+    { u"layoutDirection", 17 },
+    { u"paddingStart", 17 },
+    { u"paddingEnd", 17 },
+    { u"layout_marginStart", 17 },
+    { u"layout_marginEnd", 17 },
+    { u"layout_toStartOf", 17 },
+    { u"layout_toEndOf", 17 },
+    { u"layout_alignStart", 17 },
+    { u"layout_alignEnd", 17 },
+    { u"layout_alignParentStart", 17 },
+    { u"layout_alignParentEnd", 17 },
+    { u"listPreferredItemPaddingStart", 17 },
+    { u"listPreferredItemPaddingEnd", 17 },
+    { u"singleUser", 17 },
+    { u"presentationTheme", 17 },
+    { u"subtypeId", 17 },
+    { u"initialKeyguardLayout", 17 },
+    { u"widgetCategory", 17 },
+    { u"permissionGroupFlags", 17 },
+    { u"labelFor", 17 },
+    { u"permissionFlags", 17 },
+    { u"checkedTextViewStyle", 17 },
+    { u"showOnLockScreen", 17 },
+    { u"format12Hour", 17 },
+    { u"format24Hour", 17 },
+    { u"timeZone", 17 },
+    { u"mipMap", 18 },
+    { u"mirrorForRtl", 18 },
+    { u"windowOverscan", 18 },
+    { u"requiredForAllUsers", 18 },
+    { u"indicatorStart", 18 },
+    { u"indicatorEnd", 18 },
+    { u"childIndicatorStart", 18 },
+    { u"childIndicatorEnd", 18 },
+    { u"restrictedAccountType", 18 },
+    { u"requiredAccountType", 18 },
+    { u"canRequestTouchExplorationMode", 18 },
+    { u"canRequestEnhancedWebAccessibility", 18 },
+    { u"canRequestFilterKeyEvents", 18 },
+    { u"layoutMode", 18 },
+    { u"keySet", 19 },
+    { u"targetId", 19 },
+    { u"fromScene", 19 },
+    { u"toScene", 19 },
+    { u"transition", 19 },
+    { u"transitionOrdering", 19 },
+    { u"fadingMode", 19 },
+    { u"startDelay", 19 },
+    { u"ssp", 19 },
+    { u"sspPrefix", 19 },
+    { u"sspPattern", 19 },
+    { u"addPrintersActivity", 19 },
+    { u"vendor", 19 },
+    { u"category", 19 },
+    { u"isAsciiCapable", 19 },
+    { u"autoMirrored", 19 },
+    { u"supportsSwitchingToNextInputMethod", 19 },
+    { u"requireDeviceUnlock", 19 },
+    { u"apduServiceBanner", 19 },
+    { u"accessibilityLiveRegion", 19 },
+    { u"windowTranslucentStatus", 19 },
+    { u"windowTranslucentNavigation", 19 },
+    { u"advancedPrintOptionsActivity", 19 },
+    { u"banner", 20 },
+    { u"windowSwipeToDismiss", 20 },
+    { u"isGame", 20 },
+    { u"allowEmbedded", 20 },
+    { u"setupActivity", 20 },
+    { u"fastScrollStyle", 21 },
+    { u"windowContentTransitions", 21 },
+    { u"windowContentTransitionManager", 21 },
+    { u"translationZ", 21 },
+    { u"tintMode", 21 },
+    { u"controlX1", 21 },
+    { u"controlY1", 21 },
+    { u"controlX2", 21 },
+    { u"controlY2", 21 },
+    { u"transitionName", 21 },
+    { u"transitionGroup", 21 },
+    { u"viewportWidth", 21 },
+    { u"viewportHeight", 21 },
+    { u"fillColor", 21 },
+    { u"pathData", 21 },
+    { u"strokeColor", 21 },
+    { u"strokeWidth", 21 },
+    { u"trimPathStart", 21 },
+    { u"trimPathEnd", 21 },
+    { u"trimPathOffset", 21 },
+    { u"strokeLineCap", 21 },
+    { u"strokeLineJoin", 21 },
+    { u"strokeMiterLimit", 21 },
+    { u"colorControlNormal", 21 },
+    { u"colorControlActivated", 21 },
+    { u"colorButtonNormal", 21 },
+    { u"colorControlHighlight", 21 },
+    { u"persistableMode", 21 },
+    { u"titleTextAppearance", 21 },
+    { u"subtitleTextAppearance", 21 },
+    { u"slideEdge", 21 },
+    { u"actionBarTheme", 21 },
+    { u"textAppearanceListItemSecondary", 21 },
+    { u"colorPrimary", 21 },
+    { u"colorPrimaryDark", 21 },
+    { u"colorAccent", 21 },
+    { u"nestedScrollingEnabled", 21 },
+    { u"windowEnterTransition", 21 },
+    { u"windowExitTransition", 21 },
+    { u"windowSharedElementEnterTransition", 21 },
+    { u"windowSharedElementExitTransition", 21 },
+    { u"windowAllowReturnTransitionOverlap", 21 },
+    { u"windowAllowEnterTransitionOverlap", 21 },
+    { u"sessionService", 21 },
+    { u"stackViewStyle", 21 },
+    { u"switchStyle", 21 },
+    { u"elevation", 21 },
+    { u"excludeId", 21 },
+    { u"excludeClass", 21 },
+    { u"hideOnContentScroll", 21 },
+    { u"actionOverflowMenuStyle", 21 },
+    { u"documentLaunchMode", 21 },
+    { u"maxRecents", 21 },
+    { u"autoRemoveFromRecents", 21 },
+    { u"stateListAnimator", 21 },
+    { u"toId", 21 },
+    { u"fromId", 21 },
+    { u"reversible", 21 },
+    { u"splitTrack", 21 },
+    { u"targetName", 21 },
+    { u"excludeName", 21 },
+    { u"matchOrder", 21 },
+    { u"windowDrawsSystemBarBackgrounds", 21 },
+    { u"statusBarColor", 21 },
+    { u"navigationBarColor", 21 },
+    { u"contentInsetStart", 21 },
+    { u"contentInsetEnd", 21 },
+    { u"contentInsetLeft", 21 },
+    { u"contentInsetRight", 21 },
+    { u"paddingMode", 21 },
+    { u"layout_rowWeight", 21 },
+    { u"layout_columnWeight", 21 },
+    { u"translateX", 21 },
+    { u"translateY", 21 },
+    { u"selectableItemBackgroundBorderless", 21 },
+    { u"elegantTextHeight", 21 },
+    { u"searchKeyphraseId", 21 },
+    { u"searchKeyphrase", 21 },
+    { u"searchKeyphraseSupportedLocales", 21 },
+    { u"windowTransitionBackgroundFadeDuration", 21 },
+    { u"overlapAnchor", 21 },
+    { u"progressTint", 21 },
+    { u"progressTintMode", 21 },
+    { u"progressBackgroundTint", 21 },
+    { u"progressBackgroundTintMode", 21 },
+    { u"secondaryProgressTint", 21 },
+    { u"secondaryProgressTintMode", 21 },
+    { u"indeterminateTint", 21 },
+    { u"indeterminateTintMode", 21 },
+    { u"backgroundTint", 21 },
+    { u"backgroundTintMode", 21 },
+    { u"foregroundTint", 21 },
+    { u"foregroundTintMode", 21 },
+    { u"buttonTint", 21 },
+    { u"buttonTintMode", 21 },
+    { u"thumbTint", 21 },
+    { u"thumbTintMode", 21 },
+    { u"fullBackupOnly", 21 },
+    { u"propertyXName", 21 },
+    { u"propertyYName", 21 },
+    { u"relinquishTaskIdentity", 21 },
+    { u"tileModeX", 21 },
+    { u"tileModeY", 21 },
+    { u"actionModeShareDrawable", 21 },
+    { u"actionModeFindDrawable", 21 },
+    { u"actionModeWebSearchDrawable", 21 },
+    { u"transitionVisibilityMode", 21 },
+    { u"minimumHorizontalAngle", 21 },
+    { u"minimumVerticalAngle", 21 },
+    { u"maximumAngle", 21 },
+    { u"searchViewStyle", 21 },
+    { u"closeIcon", 21 },
+    { u"goIcon", 21 },
+    { u"searchIcon", 21 },
+    { u"voiceIcon", 21 },
+    { u"commitIcon", 21 },
+    { u"suggestionRowLayout", 21 },
+    { u"queryBackground", 21 },
+    { u"submitBackground", 21 },
+    { u"buttonBarPositiveButtonStyle", 21 },
+    { u"buttonBarNeutralButtonStyle", 21 },
+    { u"buttonBarNegativeButtonStyle", 21 },
+    { u"popupElevation", 21 },
+    { u"actionBarPopupTheme", 21 },
+    { u"multiArch", 21 },
+    { u"touchscreenBlocksFocus", 21 },
+    { u"windowElevation", 21 },
+    { u"launchTaskBehindTargetAnimation", 21 },
+    { u"launchTaskBehindSourceAnimation", 21 },
+    { u"restrictionType", 21 },
+    { u"dayOfWeekBackground", 21 },
+    { u"dayOfWeekTextAppearance", 21 },
+    { u"headerMonthTextAppearance", 21 },
+    { u"headerDayOfMonthTextAppearance", 21 },
+    { u"headerYearTextAppearance", 21 },
+    { u"yearListItemTextAppearance", 21 },
+    { u"yearListSelectorColor", 21 },
+    { u"calendarTextColor", 21 },
+    { u"recognitionService", 21 },
+    { u"timePickerStyle", 21 },
+    { u"timePickerDialogTheme", 21 },
+    { u"headerTimeTextAppearance", 21 },
+    { u"headerAmPmTextAppearance", 21 },
+    { u"numbersTextColor", 21 },
+    { u"numbersBackgroundColor", 21 },
+    { u"numbersSelectorColor", 21 },
+    { u"amPmTextColor", 21 },
+    { u"amPmBackgroundColor", 21 },
+    { u"searchKeyphraseRecognitionFlags", 21 },
+    { u"checkMarkTint", 21 },
+    { u"checkMarkTintMode", 21 },
+    { u"popupTheme", 21 },
+    { u"toolbarStyle", 21 },
+    { u"windowClipToOutline", 21 },
+    { u"datePickerDialogTheme", 21 },
+    { u"showText", 21 },
+    { u"windowReturnTransition", 21 },
+    { u"windowReenterTransition", 21 },
+    { u"windowSharedElementReturnTransition", 21 },
+    { u"windowSharedElementReenterTransition", 21 },
+    { u"resumeWhilePausing", 21 },
+    { u"datePickerMode", 21 },
+    { u"timePickerMode", 21 },
+    { u"inset", 21 },
+    { u"letterSpacing", 21 },
+    { u"fontFeatureSettings", 21 },
+    { u"outlineProvider", 21 },
+    { u"contentAgeHint", 21 },
+    { u"country", 21 },
+    { u"windowSharedElementsUseOverlay", 21 },
+    { u"reparent", 21 },
+    { u"reparentWithOverlay", 21 },
+    { u"ambientShadowAlpha", 21 },
+    { u"spotShadowAlpha", 21 },
+    { u"navigationIcon", 21 },
+    { u"navigationContentDescription", 21 },
+    { u"fragmentExitTransition", 21 },
+    { u"fragmentEnterTransition", 21 },
+    { u"fragmentSharedElementEnterTransition", 21 },
+    { u"fragmentReturnTransition", 21 },
+    { u"fragmentSharedElementReturnTransition", 21 },
+    { u"fragmentReenterTransition", 21 },
+    { u"fragmentAllowEnterTransitionOverlap", 21 },
+    { u"fragmentAllowReturnTransitionOverlap", 21 },
+    { u"patternPathData", 21 },
+    { u"strokeAlpha", 21 },
+    { u"fillAlpha", 21 },
+    { u"windowActivityTransitions", 21 },
+    { u"colorEdgeEffect", 21 }
+};
+
+size_t findAttributeSdkLevel(const std::u16string& name) {
+    auto iter = sAttrMap.find(name);
+    if (iter != sAttrMap.end()) {
+        return iter->second;
+    }
+    return 0;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
new file mode 100644
index 0000000..469c355
--- /dev/null
+++ b/tools/aapt2/SdkConstants.h
@@ -0,0 +1,53 @@
+/*
+ * 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_SDK_CONSTANTS_H
+#define AAPT_SDK_CONSTANTS_H
+
+#include "Resource.h"
+
+#include <string>
+
+namespace aapt {
+
+enum {
+    SDK_CUPCAKE = 3,
+    SDK_DONUT = 4,
+    SDK_ECLAIR = 5,
+    SDK_ECLAIR_0_1 = 6,
+    SDK_ECLAIR_MR1 = 7,
+    SDK_FROYO = 8,
+    SDK_GINGERBREAD = 9,
+    SDK_GINGERBREAD_MR1 = 10,
+    SDK_HONEYCOMB = 11,
+    SDK_HONEYCOMB_MR1 = 12,
+    SDK_HONEYCOMB_MR2 = 13,
+    SDK_ICE_CREAM_SANDWICH = 14,
+    SDK_ICE_CREAM_SANDWICH_MR1 = 15,
+    SDK_JELLY_BEAN = 16,
+    SDK_JELLY_BEAN_MR1 = 17,
+    SDK_JELLY_BEAN_MR2 = 18,
+    SDK_KITKAT = 19,
+    SDK_KITKAT_WATCH = 20,
+    SDK_LOLLIPOP = 21,
+    SDK_LOLLIPOP_MR1 = 22,
+};
+
+size_t findAttributeSdkLevel(const std::u16string& name);
+
+} // namespace aapt
+
+#endif // AAPT_SDK_CONSTANTS_H
diff --git a/tools/aapt2/Source.h b/tools/aapt2/Source.h
new file mode 100644
index 0000000..10c75aa
--- /dev/null
+++ b/tools/aapt2/Source.h
@@ -0,0 +1,85 @@
+/*
+ * 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_SOURCE_H
+#define AAPT_SOURCE_H
+
+#include <ostream>
+#include <string>
+
+namespace aapt {
+
+struct SourceLineColumn;
+struct SourceLine;
+
+/**
+ * Represents a file on disk. Used for logging and
+ * showing errors.
+ */
+struct Source {
+    std::string path;
+
+    inline SourceLine line(size_t line) const;
+};
+
+/**
+ * Represents a file on disk and a line number in that file.
+ * Used for logging and showing errors.
+ */
+struct SourceLine {
+    std::string path;
+    size_t line;
+
+    inline SourceLineColumn column(size_t column) const;
+};
+
+/**
+ * Represents a file on disk and a line:column number in that file.
+ * Used for logging and showing errors.
+ */
+struct SourceLineColumn {
+    std::string path;
+    size_t line;
+    size_t column;
+};
+
+//
+// Implementations
+//
+
+SourceLine Source::line(size_t line) const {
+    return SourceLine{ path, line };
+}
+
+SourceLineColumn SourceLine::column(size_t column) const {
+    return SourceLineColumn{ path, line, column };
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const Source& source) {
+    return out << source.path;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const SourceLine& source) {
+    return out << source.path << ":" << source.line;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const SourceLineColumn& source) {
+    return out << source.path << ":" << source.line << ":" << source.column;
+}
+
+} // namespace aapt
+
+#endif // AAPT_SOURCE_H
diff --git a/tools/aapt2/SourceXmlPullParser.cpp b/tools/aapt2/SourceXmlPullParser.cpp
new file mode 100644
index 0000000..cb6a3c0
--- /dev/null
+++ b/tools/aapt2/SourceXmlPullParser.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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 <iostream>
+#include <string>
+
+#include "SourceXmlPullParser.h"
+#include "Util.h"
+
+namespace aapt {
+
+constexpr char kXmlNamespaceSep = 1;
+
+SourceXmlPullParser::SourceXmlPullParser(std::istream& in) : mIn(in), mEmpty(), mDepth(0) {
+    mParser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep);
+    XML_SetUserData(mParser, this);
+    XML_SetElementHandler(mParser, startElementHandler, endElementHandler);
+    XML_SetNamespaceDeclHandler(mParser, startNamespaceHandler, endNamespaceHandler);
+    XML_SetCharacterDataHandler(mParser, characterDataHandler);
+    XML_SetCommentHandler(mParser, commentDataHandler);
+    mEventQueue.push(EventData{ Event::kStartDocument, 0, mDepth++ });
+}
+
+SourceXmlPullParser::~SourceXmlPullParser() {
+    XML_ParserFree(mParser);
+}
+
+SourceXmlPullParser::Event SourceXmlPullParser::next() {
+    const Event currentEvent = getEvent();
+    if (currentEvent == Event::kBadDocument || currentEvent == Event::kEndDocument) {
+        return currentEvent;
+    }
+
+    mEventQueue.pop();
+    while (mEventQueue.empty()) {
+        mIn.read(mBuffer, sizeof(mBuffer) / sizeof(*mBuffer));
+
+        const bool done = mIn.eof();
+        if (mIn.bad() && !done) {
+            mLastError = strerror(errno);
+            mEventQueue.push(EventData{ Event::kBadDocument });
+            continue;
+        }
+
+        if (XML_Parse(mParser, mBuffer, mIn.gcount(), done) == XML_STATUS_ERROR) {
+            mLastError = XML_ErrorString(XML_GetErrorCode(mParser));
+            mEventQueue.push(EventData{ Event::kBadDocument });
+            continue;
+        }
+
+        if (done) {
+            mEventQueue.push(EventData{ Event::kEndDocument, 0, 0 });
+        }
+    }
+
+    return getEvent();
+}
+
+SourceXmlPullParser::Event SourceXmlPullParser::getEvent() const {
+    return mEventQueue.front().event;
+}
+
+const std::string& SourceXmlPullParser::getLastError() const {
+    return mLastError;
+}
+
+const std::u16string& SourceXmlPullParser::getComment() const {
+    return mEventQueue.front().comment;
+}
+
+size_t SourceXmlPullParser::getLineNumber() const {
+    return mEventQueue.front().lineNumber;
+}
+
+size_t SourceXmlPullParser::getDepth() const {
+    return mEventQueue.front().depth;
+}
+
+const std::u16string& SourceXmlPullParser::getText() const {
+    if (getEvent() != Event::kText) {
+        return mEmpty;
+    }
+    return mEventQueue.front().data1;
+}
+
+const std::u16string& SourceXmlPullParser::getNamespacePrefix() const {
+    const Event currentEvent = getEvent();
+    if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) {
+        return mEmpty;
+    }
+    return mEventQueue.front().data1;
+}
+
+const std::u16string& SourceXmlPullParser::getNamespaceUri() const {
+    const Event currentEvent = getEvent();
+    if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) {
+        return mEmpty;
+    }
+    return mEventQueue.front().data2;
+}
+
+const std::u16string& SourceXmlPullParser::getElementNamespace() const {
+    const Event currentEvent = getEvent();
+    if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) {
+        return mEmpty;
+    }
+    return mEventQueue.front().data1;
+}
+
+const std::u16string& SourceXmlPullParser::getElementName() const {
+    const Event currentEvent = getEvent();
+    if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) {
+        return mEmpty;
+    }
+    return mEventQueue.front().data2;
+}
+
+XmlPullParser::const_iterator SourceXmlPullParser::beginAttributes() const {
+    return mEventQueue.front().attributes.begin();
+}
+
+XmlPullParser::const_iterator SourceXmlPullParser::endAttributes() const {
+    return mEventQueue.front().attributes.end();
+}
+
+size_t SourceXmlPullParser::getAttributeCount() const {
+    if (getEvent() != Event::kStartElement) {
+        return 0;
+    }
+    return mEventQueue.front().attributes.size();
+}
+
+/**
+ * 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 = std::u16string();
+        outName = util::utf8ToUtf16(name);
+    } else {
+        outNs = util::utf8ToUtf16(StringPiece(name, (p - name)));
+        outName = util::utf8ToUtf16(p + 1);
+    }
+}
+
+void XMLCALL SourceXmlPullParser::startNamespaceHandler(void* userData, const char* prefix,
+        const char* uri) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+    std::u16string namespaceUri = uri != nullptr ? util::utf8ToUtf16(uri) : std::u16string();
+    parser->mNamespaceUris.push(namespaceUri);
+    parser->mEventQueue.push(EventData{
+            Event::kStartNamespace,
+            XML_GetCurrentLineNumber(parser->mParser),
+            parser->mDepth++,
+            prefix != nullptr ? util::utf8ToUtf16(prefix) : std::u16string(),
+            namespaceUri
+    });
+}
+
+void XMLCALL SourceXmlPullParser::startElementHandler(void* userData, const char* name,
+        const char** attrs) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+
+    EventData data = {
+            Event::kStartElement, XML_GetCurrentLineNumber(parser->mParser), parser->mDepth++
+    };
+    splitName(name, data.data1, data.data2);
+
+    while (*attrs) {
+        Attribute attribute;
+        splitName(*attrs++, attribute.namespaceUri, attribute.name);
+        attribute.value = util::utf8ToUtf16(*attrs++);
+
+        // Insert in sorted order.
+        auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(), attribute);
+        data.attributes.insert(iter, std::move(attribute));
+    }
+
+    // Move the structure into the queue (no copy).
+    parser->mEventQueue.push(std::move(data));
+}
+
+void XMLCALL SourceXmlPullParser::characterDataHandler(void* userData, const char* s, int len) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+
+    parser->mEventQueue.push(EventData{
+            Event::kText,
+            XML_GetCurrentLineNumber(parser->mParser),
+            parser->mDepth,
+            util::utf8ToUtf16(StringPiece(s, len))
+    });
+}
+
+void XMLCALL SourceXmlPullParser::endElementHandler(void* userData, const char* name) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+
+    EventData data = {
+            Event::kEndElement, XML_GetCurrentLineNumber(parser->mParser), --(parser->mDepth)
+    };
+    splitName(name, data.data1, data.data2);
+
+    // Move the data into the queue (no copy).
+    parser->mEventQueue.push(std::move(data));
+}
+
+void XMLCALL SourceXmlPullParser::endNamespaceHandler(void* userData, const char* prefix) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+
+    parser->mEventQueue.push(EventData{
+            Event::kEndNamespace,
+            XML_GetCurrentLineNumber(parser->mParser),
+            --(parser->mDepth),
+            prefix != nullptr ? util::utf8ToUtf16(prefix) : std::u16string(),
+            parser->mNamespaceUris.top()
+    });
+    parser->mNamespaceUris.pop();
+}
+
+void XMLCALL SourceXmlPullParser::commentDataHandler(void* userData, const char* comment) {
+    SourceXmlPullParser* parser = reinterpret_cast<SourceXmlPullParser*>(userData);
+
+    parser->mEventQueue.push(EventData{
+            Event::kComment,
+            XML_GetCurrentLineNumber(parser->mParser),
+            parser->mDepth,
+            util::utf8ToUtf16(comment)
+    });
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/SourceXmlPullParser.h b/tools/aapt2/SourceXmlPullParser.h
new file mode 100644
index 0000000..ba904ba
--- /dev/null
+++ b/tools/aapt2/SourceXmlPullParser.h
@@ -0,0 +1,87 @@
+/*
+ * 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_SOURCE_XML_PULL_PARSER_H
+#define AAPT_SOURCE_XML_PULL_PARSER_H
+
+#include <istream>
+#include <libexpat/expat.h>
+#include <queue>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "XmlPullParser.h"
+
+namespace aapt {
+
+class SourceXmlPullParser : public XmlPullParser {
+public:
+    SourceXmlPullParser(std::istream& in);
+    SourceXmlPullParser(const SourceXmlPullParser& rhs) = delete;
+    ~SourceXmlPullParser();
+
+    Event getEvent() const;
+    const std::string& getLastError() const;
+    Event next();
+
+    const std::u16string& getComment() const;
+    size_t getLineNumber() const;
+    size_t getDepth() const;
+
+    const std::u16string& getText() const;
+
+    const std::u16string& getNamespacePrefix() const;
+    const std::u16string& getNamespaceUri() const;
+
+    const std::u16string& getElementNamespace() const;
+    const std::u16string& getElementName() const;
+
+    const_iterator beginAttributes() const;
+    const_iterator endAttributes() const;
+    size_t getAttributeCount() const;
+
+private:
+    static void XMLCALL startNamespaceHandler(void* userData, const char* prefix, const char* uri);
+    static void XMLCALL startElementHandler(void* userData, const char* name, const char** attrs);
+    static void XMLCALL characterDataHandler(void* userData, const char* s, int len);
+    static void XMLCALL endElementHandler(void* userData, const char* name);
+    static void XMLCALL endNamespaceHandler(void* userData, const char* prefix);
+    static void XMLCALL commentDataHandler(void* userData, const char* comment);
+
+    struct EventData {
+        Event event;
+        size_t lineNumber;
+        size_t depth;
+        std::u16string data1;
+        std::u16string data2;
+        std::u16string comment;
+        std::vector<Attribute> attributes;
+    };
+
+    std::istream& mIn;
+    XML_Parser mParser;
+    char mBuffer[16384];
+    std::queue<EventData> mEventQueue;
+    std::string mLastError;
+    const std::u16string mEmpty;
+    size_t mDepth;
+    std::stack<std::u16string> mNamespaceUris;
+};
+
+} // namespace aapt
+
+#endif // AAPT_SOURCE_XML_PULL_PARSER_H
diff --git a/tools/aapt2/StringPiece.h b/tools/aapt2/StringPiece.h
new file mode 100644
index 0000000..e2a1597
--- /dev/null
+++ b/tools/aapt2/StringPiece.h
@@ -0,0 +1,232 @@
+/*
+ * 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_STRING_PIECE_H
+#define AAPT_STRING_PIECE_H
+
+#include <ostream>
+#include <string>
+#include <utils/String8.h>
+#include <utils/Unicode.h>
+
+namespace aapt {
+
+/**
+ * Read only wrapper around basic C strings.
+ * Prevents excessive copying.
+ *
+ * WARNING: When creating from std::basic_string<>, moving the original
+ * std::basic_string<> will invalidate the data held in a BasicStringPiece<>.
+ * BasicStringPiece<> should only be used transitively.
+ */
+template <typename TChar>
+class BasicStringPiece {
+public:
+    using const_iterator = const TChar*;
+
+    BasicStringPiece();
+    BasicStringPiece(const BasicStringPiece<TChar>& str);
+    BasicStringPiece(const std::basic_string<TChar>& str);
+    BasicStringPiece(const TChar* str);
+    BasicStringPiece(const TChar* str, size_t len);
+
+    BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs);
+    BasicStringPiece<TChar>& assign(const TChar* str, size_t len);
+
+    BasicStringPiece<TChar> substr(size_t start, size_t len) const;
+    BasicStringPiece<TChar> substr(BasicStringPiece<TChar>::const_iterator begin,
+                                   BasicStringPiece<TChar>::const_iterator end) const;
+
+    const TChar* data() const;
+    size_t length() const;
+    size_t size() const;
+    bool empty() const;
+    std::basic_string<TChar> toString() const;
+
+    int compare(const BasicStringPiece<TChar>& rhs) const;
+    bool operator<(const BasicStringPiece<TChar>& rhs) const;
+    bool operator>(const BasicStringPiece<TChar>& rhs) const;
+    bool operator==(const BasicStringPiece<TChar>& rhs) const;
+    bool operator!=(const BasicStringPiece<TChar>& rhs) const;
+
+    const_iterator begin() const;
+    const_iterator end() const;
+
+private:
+    const TChar* mData;
+    size_t mLength;
+};
+
+using StringPiece = BasicStringPiece<char>;
+using StringPiece16 = BasicStringPiece<char16_t>;
+
+//
+// BasicStringPiece implementation.
+//
+
+template <typename TChar>
+inline BasicStringPiece<TChar>::BasicStringPiece() : mData(nullptr) , mLength(0) {
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar>::BasicStringPiece(const BasicStringPiece<TChar>& str) :
+        mData(str.mData), mLength(str.mLength) {
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar>::BasicStringPiece(const std::basic_string<TChar>& str) :
+        mData(str.data()), mLength(str.length()) {
+}
+
+template <>
+inline BasicStringPiece<char>::BasicStringPiece(const char* str) :
+        mData(str), mLength(str != nullptr ? strlen(str) : 0) {
+}
+
+template <>
+inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) :
+        mData(str), mLength(str != nullptr ? strlen16(str) : 0) {
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) :
+        mData(str), mLength(len) {
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=(
+        const BasicStringPiece<TChar>& rhs) {
+    mData = rhs.mData;
+    mLength = rhs.mLength;
+    return *this;
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(const TChar* str, size_t len) {
+    mData = str;
+    mLength = len;
+    return *this;
+}
+
+
+template <typename TChar>
+inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const {
+    if (start + len > mLength) {
+        return BasicStringPiece<TChar>();
+    }
+    return BasicStringPiece<TChar>(mData + start, len);
+}
+
+template <typename TChar>
+inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(
+        BasicStringPiece<TChar>::const_iterator begin,
+        BasicStringPiece<TChar>::const_iterator end) const {
+    return BasicStringPiece<TChar>(begin, end - begin);
+}
+
+template <typename TChar>
+inline const TChar* BasicStringPiece<TChar>::data() const {
+    return mData;
+}
+
+template <typename TChar>
+inline size_t BasicStringPiece<TChar>::length() const {
+    return mLength;
+}
+
+template <typename TChar>
+inline size_t BasicStringPiece<TChar>::size() const {
+    return mLength;
+}
+
+template <typename TChar>
+inline bool BasicStringPiece<TChar>::empty() const {
+    return mLength == 0;
+}
+
+template <typename TChar>
+inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const {
+    return std::basic_string<TChar>(mData, mLength);
+}
+
+template <>
+inline int BasicStringPiece<char>::compare(const BasicStringPiece<char>& rhs) const {
+    const char nullStr = '\0';
+    const char* b1 = mData != nullptr ? mData : &nullStr;
+    const char* e1 = b1 + mLength;
+    const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
+    const char* e2 = b2 + rhs.mLength;
+
+    while (b1 < e1 && b2 < e2) {
+        const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++);
+        if (d) {
+            return d;
+        }
+    }
+    return static_cast<int>(mLength - rhs.mLength);
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char16_t>& str) {
+    android::String8 utf8(str.data(), str.size());
+    return out.write(utf8.string(), utf8.size());
+}
+
+
+template <>
+inline int BasicStringPiece<char16_t>::compare(const BasicStringPiece<char16_t>& rhs) const {
+    const char16_t nullStr = u'\0';
+    const char16_t* b1 = mData != nullptr ? mData : &nullStr;
+    const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
+    return strzcmp16(b1, mLength, b2, rhs.mLength);
+}
+
+template <typename TChar>
+inline bool BasicStringPiece<TChar>::operator<(const BasicStringPiece<TChar>& rhs) const {
+    return compare(rhs) < 0;
+}
+
+template <typename TChar>
+inline bool BasicStringPiece<TChar>::operator>(const BasicStringPiece<TChar>& rhs) const {
+    return compare(rhs) > 0;
+}
+
+template <typename TChar>
+inline bool BasicStringPiece<TChar>::operator==(const BasicStringPiece<TChar>& rhs) const {
+    return compare(rhs) == 0;
+}
+
+template <typename TChar>
+inline bool BasicStringPiece<TChar>::operator!=(const BasicStringPiece<TChar>& rhs) const {
+    return compare(rhs) != 0;
+}
+
+template <typename TChar>
+inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const {
+    return mData;
+}
+
+template <typename TChar>
+inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const {
+    return mData + mLength;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char>& str) {
+    return out.write(str.data(), str.size());
+}
+
+} // namespace aapt
+
+#endif // AAPT_STRING_PIECE_H
diff --git a/tools/aapt2/StringPiece_test.cpp b/tools/aapt2/StringPiece_test.cpp
new file mode 100644
index 0000000..43f7a37
--- /dev/null
+++ b/tools/aapt2/StringPiece_test.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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 <algorithm>
+#include <gtest/gtest.h>
+#include <string>
+#include <vector>
+
+#include "StringPiece.h"
+
+namespace aapt {
+
+TEST(StringPieceTest, CompareNonNullTerminatedPiece) {
+    StringPiece a("hello world", 5);
+    StringPiece b("hello moon", 5);
+    EXPECT_EQ(a, b);
+
+    StringPiece16 a16(u"hello world", 5);
+    StringPiece16 b16(u"hello moon", 5);
+    EXPECT_EQ(a16, b16);
+}
+
+TEST(StringPieceTest, PiecesHaveCorrectSortOrder) {
+    std::u16string testing(u"testing");
+    std::u16string banana(u"banana");
+    std::u16string car(u"car");
+
+    EXPECT_TRUE(StringPiece16(testing) > banana);
+    EXPECT_TRUE(StringPiece16(testing) > car);
+    EXPECT_TRUE(StringPiece16(banana) < testing);
+    EXPECT_TRUE(StringPiece16(banana) < car);
+    EXPECT_TRUE(StringPiece16(car) < testing);
+    EXPECT_TRUE(StringPiece16(car) > banana);
+}
+
+TEST(StringPieceTest, PiecesHaveCorrectSortOrderUtf8) {
+    std::string testing("testing");
+    std::string banana("banana");
+    std::string car("car");
+
+    EXPECT_TRUE(StringPiece(testing) > banana);
+    EXPECT_TRUE(StringPiece(testing) > car);
+    EXPECT_TRUE(StringPiece(banana) < testing);
+    EXPECT_TRUE(StringPiece(banana) < car);
+    EXPECT_TRUE(StringPiece(car) < testing);
+    EXPECT_TRUE(StringPiece(car) > banana);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/StringPool.cpp b/tools/aapt2/StringPool.cpp
new file mode 100644
index 0000000..b159a00
--- /dev/null
+++ b/tools/aapt2/StringPool.cpp
@@ -0,0 +1,348 @@
+/*
+ * 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 "BigBuffer.h"
+#include "StringPiece.h"
+#include "StringPool.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <androidfw/ResourceTypes.h>
+#include <memory>
+#include <string>
+
+namespace aapt {
+
+StringPool::Ref::Ref() : mEntry(nullptr) {
+}
+
+StringPool::Ref::Ref(const StringPool::Ref& rhs) : mEntry(rhs.mEntry) {
+    if (mEntry != nullptr) {
+        mEntry->ref++;
+    }
+}
+
+StringPool::Ref::Ref(StringPool::Entry* entry) : mEntry(entry) {
+    if (mEntry != nullptr) {
+        mEntry->ref++;
+    }
+}
+
+StringPool::Ref::~Ref() {
+    if (mEntry != nullptr) {
+        mEntry->ref--;
+    }
+}
+
+StringPool::Ref& StringPool::Ref::operator=(const StringPool::Ref& rhs) {
+    if (rhs.mEntry != nullptr) {
+        rhs.mEntry->ref++;
+    }
+
+    if (mEntry != nullptr) {
+        mEntry->ref--;
+    }
+    mEntry = rhs.mEntry;
+    return *this;
+}
+
+const std::u16string* StringPool::Ref::operator->() const {
+    return &mEntry->value;
+}
+
+const std::u16string& StringPool::Ref::operator*() const {
+    return mEntry->value;
+}
+
+size_t StringPool::Ref::getIndex() const {
+    return mEntry->index;
+}
+
+const StringPool::Context& StringPool::Ref::getContext() const {
+    return mEntry->context;
+}
+
+StringPool::StyleRef::StyleRef() : mEntry(nullptr) {
+}
+
+StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs) : mEntry(rhs.mEntry) {
+    if (mEntry != nullptr) {
+        mEntry->ref++;
+    }
+}
+
+StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : mEntry(entry) {
+    if (mEntry != nullptr) {
+        mEntry->ref++;
+    }
+}
+
+StringPool::StyleRef::~StyleRef() {
+    if (mEntry != nullptr) {
+        mEntry->ref--;
+    }
+}
+
+StringPool::StyleRef& StringPool::StyleRef::operator=(const StringPool::StyleRef& rhs) {
+    if (rhs.mEntry != nullptr) {
+        rhs.mEntry->ref++;
+    }
+
+    if (mEntry != nullptr) {
+        mEntry->ref--;
+    }
+    mEntry = rhs.mEntry;
+    return *this;
+}
+
+const StringPool::StyleEntry* StringPool::StyleRef::operator->() const {
+    return mEntry;
+}
+
+const StringPool::StyleEntry& StringPool::StyleRef::operator*() const {
+    return *mEntry;
+}
+
+size_t StringPool::StyleRef::getIndex() const {
+    return mEntry->str.getIndex();
+}
+
+const StringPool::Context& StringPool::StyleRef::getContext() const {
+    return mEntry->str.getContext();
+}
+
+StringPool::Ref StringPool::makeRef(const StringPiece16& str) {
+    return makeRefImpl(str, Context{}, true);
+}
+
+StringPool::Ref StringPool::makeRef(const StringPiece16& str, const Context& context) {
+    return makeRefImpl(str, context, true);
+}
+
+StringPool::Ref StringPool::makeRefImpl(const StringPiece16& str, const Context& context,
+        bool unique) {
+    if (unique) {
+        auto iter = mIndexedStrings.find(str);
+        if (iter != std::end(mIndexedStrings)) {
+            return Ref(iter->second);
+        }
+    }
+
+    Entry* entry = new Entry();
+    entry->value = str.toString();
+    entry->context = context;
+    entry->index = mStrings.size();
+    entry->ref = 0;
+    mStrings.emplace_back(entry);
+    mIndexedStrings.insert(std::make_pair(StringPiece16(entry->value), entry));
+    return Ref(entry);
+}
+
+StringPool::StyleRef StringPool::makeRef(const StyleString& str) {
+    return makeRef(str, Context{});
+}
+
+StringPool::StyleRef StringPool::makeRef(const StyleString& str, const Context& context) {
+    Entry* entry = new Entry();
+    entry->value = str.str;
+    entry->context = context;
+    entry->index = mStrings.size();
+    entry->ref = 0;
+    mStrings.emplace_back(entry);
+    mIndexedStrings.insert(std::make_pair(StringPiece16(entry->value), entry));
+
+    StyleEntry* styleEntry = new StyleEntry();
+    styleEntry->str = Ref(entry);
+    for (const aapt::Span& span : str.spans) {
+        styleEntry->spans.emplace_back(Span{makeRef(span.name),
+                span.firstChar, span.lastChar});
+    }
+    styleEntry->ref = 0;
+    mStyles.emplace_back(styleEntry);
+    return StyleRef(styleEntry);
+}
+
+void StringPool::merge(StringPool&& pool) {
+    mIndexedStrings.insert(pool.mIndexedStrings.begin(), pool.mIndexedStrings.end());
+    pool.mIndexedStrings.clear();
+    std::move(pool.mStrings.begin(), pool.mStrings.end(), std::back_inserter(mStrings));
+    pool.mStrings.clear();
+    std::move(pool.mStyles.begin(), pool.mStyles.end(), std::back_inserter(mStyles));
+    pool.mStyles.clear();
+
+    // Assign the indices.
+    const size_t len = mStrings.size();
+    for (size_t index = 0; index < len; index++) {
+        mStrings[index]->index = index;
+    }
+}
+
+void StringPool::hintWillAdd(size_t stringCount, size_t styleCount) {
+    mStrings.reserve(mStrings.size() + stringCount);
+    mStyles.reserve(mStyles.size() + styleCount);
+}
+
+void StringPool::prune() {
+    const auto iterEnd = std::end(mIndexedStrings);
+    auto indexIter = std::begin(mIndexedStrings);
+    while (indexIter != iterEnd) {
+        if (indexIter->second->ref <= 0) {
+            mIndexedStrings.erase(indexIter++);
+        } else {
+            ++indexIter;
+        }
+    }
+
+    auto endIter2 = std::remove_if(std::begin(mStrings), std::end(mStrings),
+            [](const std::unique_ptr<Entry>& entry) -> bool {
+                return entry->ref <= 0;
+            }
+    );
+
+    auto endIter3 = std::remove_if(std::begin(mStyles), std::end(mStyles),
+            [](const std::unique_ptr<StyleEntry>& entry) -> bool {
+                return entry->ref <= 0;
+            }
+    );
+
+    // Remove the entries at the end or else we'll be accessing
+    // a deleted string from the StyleEntry.
+    mStrings.erase(endIter2, std::end(mStrings));
+    mStyles.erase(endIter3, std::end(mStyles));
+}
+
+void StringPool::sort(const std::function<bool(const Entry&, const Entry&)>& cmp) {
+    std::sort(std::begin(mStrings), std::end(mStrings),
+            [&cmp](const std::unique_ptr<Entry>& a, const std::unique_ptr<Entry>& b) -> bool {
+                return cmp(*a, *b);
+            }
+    );
+
+    // Assign the indices.
+    const size_t len = mStrings.size();
+    for (size_t index = 0; index < len; index++) {
+        mStrings[index]->index = index;
+    }
+
+    // Reorder the styles.
+    std::sort(std::begin(mStyles), std::end(mStyles),
+            [](const std::unique_ptr<StyleEntry>& lhs,
+               const std::unique_ptr<StyleEntry>& rhs) -> bool {
+                return lhs->str.getIndex() < rhs->str.getIndex();
+            }
+    );
+}
+
+static uint8_t* encodeLength(uint8_t* data, size_t length) {
+    if (length > 0x7fu) {
+        *data++ = 0x80u | (0x000000ffu & (length >> 8));
+    }
+    *data++ = 0x000000ffu & length;
+    return data;
+}
+
+static size_t encodedLengthByteCount(size_t length) {
+    return length > 0x7fu ? 2 : 1;
+}
+
+bool StringPool::flattenUtf8(BigBuffer* out, const StringPool& pool) {
+    const size_t startIndex = out->size();
+    android::ResStringPool_header* header = out->nextBlock<android::ResStringPool_header>();
+    header->header.type = android::RES_STRING_POOL_TYPE;
+    header->header.headerSize = sizeof(*header);
+    header->stringCount = pool.size();
+    header->flags |= android::ResStringPool_header::UTF8_FLAG;
+
+    uint32_t* indices = out->nextBlock<uint32_t>(pool.size());
+
+    uint32_t* styleIndices = nullptr;
+    if (!pool.mStyles.empty()) {
+        header->styleCount = pool.mStyles.back()->str.getIndex() + 1;
+        styleIndices = out->nextBlock<uint32_t>(header->styleCount);
+    }
+
+    const size_t beforeStringsIndex = out->size();
+    header->stringsStart = beforeStringsIndex - startIndex;
+
+    for (const auto& entry : pool) {
+        *indices = out->size() - beforeStringsIndex;
+        indices++;
+
+        std::string encoded = util::utf16ToUtf8(entry->value);
+
+        const size_t stringByteLength = sizeof(char) * encoded.length();
+        const size_t totalSize = encodedLengthByteCount(entry->value.size())
+                + encodedLengthByteCount(encoded.length())
+                + stringByteLength
+                + sizeof(char);
+
+        uint8_t* data = out->nextBlock<uint8_t>(totalSize);
+
+        // First encode the actual UTF16 string length.
+        data = encodeLength(data, entry->value.size());
+
+        // Now encode the size of the converted UTF8 string.
+        data = encodeLength(data, encoded.length());
+
+        memcpy(data, encoded.data(), stringByteLength);
+        data += stringByteLength;
+        *data = 0;
+    }
+
+    out->align4();
+
+    if (!pool.mStyles.empty()) {
+        const size_t beforeStylesIndex = out->size();
+        header->stylesStart = beforeStylesIndex - startIndex;
+
+        size_t currentIndex = 0;
+        for (const auto& entry : pool.mStyles) {
+            while (entry->str.getIndex() > currentIndex) {
+                styleIndices[currentIndex++] = out->size() - beforeStylesIndex;
+
+                uint32_t* spanOffset = out->nextBlock<uint32_t>();
+                *spanOffset = android::ResStringPool_span::END;
+            }
+            styleIndices[currentIndex++] = out->size() - beforeStylesIndex;
+
+            android::ResStringPool_span* span =
+                    out->nextBlock<android::ResStringPool_span>(entry->spans.size());
+            for (const auto& s : entry->spans) {
+                span->name.index = s.name.getIndex();
+                span->firstChar = s.firstChar;
+                span->lastChar = s.lastChar;
+                span++;
+            }
+
+            uint32_t* spanEnd = out->nextBlock<uint32_t>();
+            *spanEnd = android::ResStringPool_span::END;
+        }
+
+        // The error checking code in the platform looks for an entire
+        // ResStringPool_span structure worth of 0xFFFFFFFF at the end
+        // of the style block, so fill in the remaining 2 32bit words
+        // with 0xFFFFFFFF.
+        const size_t paddingLength = sizeof(android::ResStringPool_span)
+                - sizeof(android::ResStringPool_span::name);
+        uint8_t* padding = out->nextBlock<uint8_t>(paddingLength);
+        memset(padding, 0xff, paddingLength);
+        out->align4();
+    }
+    header->header.size = out->size() - startIndex;
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h
new file mode 100644
index 0000000..2aa5b65
--- /dev/null
+++ b/tools/aapt2/StringPool.h
@@ -0,0 +1,215 @@
+/*
+ * 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_STRING_POOL_H
+#define AAPT_STRING_POOL_H
+
+#include "BigBuffer.h"
+#include "ConfigDescription.h"
+#include "StringPiece.h"
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+struct Span {
+    std::u16string name;
+    uint32_t firstChar;
+    uint32_t lastChar;
+};
+
+struct StyleString {
+    std::u16string str;
+    std::vector<Span> spans;
+};
+
+class StringPool {
+public:
+    struct Context {
+        uint32_t priority;
+        ConfigDescription config;
+    };
+
+    class Entry;
+
+    class Ref {
+    public:
+        Ref();
+        Ref(const Ref&);
+        ~Ref();
+
+        Ref& operator=(const Ref& rhs);
+        const std::u16string* operator->() const;
+        const std::u16string& operator*() const;
+
+        size_t getIndex() const;
+        const Context& getContext() const;
+
+    private:
+        friend class StringPool;
+
+        Ref(Entry* entry);
+
+        Entry* mEntry;
+    };
+
+    class StyleEntry;
+
+    class StyleRef {
+    public:
+        StyleRef();
+        StyleRef(const StyleRef&);
+        ~StyleRef();
+
+        StyleRef& operator=(const StyleRef& rhs);
+        const StyleEntry* operator->() const;
+        const StyleEntry& operator*() const;
+
+        size_t getIndex() const;
+        const Context& getContext() const;
+
+    private:
+        friend class StringPool;
+
+        StyleRef(StyleEntry* entry);
+
+        StyleEntry* mEntry;
+    };
+
+    class Entry {
+    public:
+        std::u16string value;
+        Context context;
+        size_t index;
+
+    private:
+        friend class StringPool;
+        friend class Ref;
+
+        int ref;
+    };
+
+    struct Span {
+        Ref name;
+        uint32_t firstChar;
+        uint32_t lastChar;
+    };
+
+    class StyleEntry {
+    public:
+        Ref str;
+        std::vector<Span> spans;
+
+    private:
+        friend class StringPool;
+        friend class StyleRef;
+
+        int ref;
+    };
+
+    using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
+
+    static bool flattenUtf8(BigBuffer* out, const StringPool& pool);
+    static bool flatten(BigBuffer* out, const StringPool& pool);
+
+    StringPool() = default;
+    StringPool(const StringPool&) = delete;
+
+    /**
+     * Adds a string to the pool, unless it already exists. Returns
+     * a reference to the string in the pool.
+     */
+    Ref makeRef(const StringPiece16& str);
+
+    /**
+     * Adds a string to the pool, unless it already exists, with a context
+     * object that can be used when sorting the string pool. Returns
+     * a reference to the string in the pool.
+     */
+    Ref makeRef(const StringPiece16& str, const Context& context);
+
+    /**
+     * Adds a style to the string pool and returns a reference to it.
+     */
+    StyleRef makeRef(const StyleString& str);
+
+    /**
+     * Adds a style to the string pool with a context object that
+     * can be used when sorting the string pool. Returns a reference
+     * to the style in the string pool.
+     */
+    StyleRef makeRef(const StyleString& str, const Context& context);
+
+    /**
+     * Moves pool into this one without coalescing strings. When this
+     * function returns, pool will be empty.
+     */
+    void merge(StringPool&& pool);
+
+    /**
+     * Retuns the number of strings in the table.
+     */
+    inline size_t size() const;
+
+    /**
+     * Reserves space for strings and styles as an optimization.
+     */
+    void hintWillAdd(size_t stringCount, size_t styleCount);
+
+    /**
+     * Sorts the strings according to some comparison function.
+     */
+    void sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
+
+    /**
+     * Removes any strings that have no references.
+     */
+    void prune();
+
+private:
+    friend const_iterator begin(const StringPool& pool);
+    friend const_iterator end(const StringPool& pool);
+
+    Ref makeRefImpl(const StringPiece16& str, const Context& context, bool unique);
+
+    std::vector<std::unique_ptr<Entry>> mStrings;
+    std::vector<std::unique_ptr<StyleEntry>> mStyles;
+    std::multimap<StringPiece16, Entry*> mIndexedStrings;
+};
+
+//
+// Inline implementation
+//
+
+inline size_t StringPool::size() const {
+    return mStrings.size();
+}
+
+inline StringPool::const_iterator begin(const StringPool& pool) {
+    return pool.mStrings.begin();
+}
+
+inline StringPool::const_iterator end(const StringPool& pool) {
+    return pool.mStrings.end();
+}
+
+} // namespace aapt
+
+#endif // AAPT_STRING_POOL_H
diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp
new file mode 100644
index 0000000..5ee1a2d
--- /dev/null
+++ b/tools/aapt2/StringPool_test.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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 "StringPool.h"
+#include "Util.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+namespace aapt {
+
+TEST(StringPoolTest, InsertOneString) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"wut");
+    EXPECT_EQ(*ref, u"wut");
+}
+
+TEST(StringPoolTest, InsertTwoUniqueStrings) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"wut");
+    StringPool::Ref ref2 = pool.makeRef(u"hey");
+
+    EXPECT_EQ(*ref, u"wut");
+    EXPECT_EQ(*ref2, u"hey");
+}
+
+TEST(StringPoolTest, DoNotInsertNewDuplicateString) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"wut");
+    StringPool::Ref ref2 = pool.makeRef(u"wut");
+
+    EXPECT_EQ(*ref, u"wut");
+    EXPECT_EQ(*ref2, u"wut");
+    EXPECT_EQ(1u, pool.size());
+}
+
+TEST(StringPoolTest, MaintainInsertionOrderIndex) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"z");
+    StringPool::Ref ref2 = pool.makeRef(u"a");
+    StringPool::Ref ref3 = pool.makeRef(u"m");
+
+    EXPECT_EQ(0u, ref.getIndex());
+    EXPECT_EQ(1u, ref2.getIndex());
+    EXPECT_EQ(2u, ref3.getIndex());
+}
+
+TEST(StringPoolTest, PruneStringsWithNoReferences) {
+    StringPool pool;
+
+    {
+        StringPool::Ref ref = pool.makeRef(u"wut");
+        EXPECT_EQ(*ref, u"wut");
+        EXPECT_EQ(1u, pool.size());
+    }
+
+    EXPECT_EQ(1u, pool.size());
+    pool.prune();
+    EXPECT_EQ(0u, pool.size());
+}
+
+TEST(StringPoolTest, SortAndMaintainIndexesInReferences) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"z");
+    StringPool::StyleRef ref2 = pool.makeRef(StyleString{ {u"a"} });
+    StringPool::Ref ref3 = pool.makeRef(u"m");
+
+    EXPECT_EQ(*ref, u"z");
+    EXPECT_EQ(0u, ref.getIndex());
+
+    EXPECT_EQ(*(ref2->str), u"a");
+    EXPECT_EQ(1u, ref2.getIndex());
+
+    EXPECT_EQ(*ref3, u"m");
+    EXPECT_EQ(2u, ref3.getIndex());
+
+    pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+        return a.value < b.value;
+    });
+
+
+    EXPECT_EQ(*ref, u"z");
+    EXPECT_EQ(2u, ref.getIndex());
+
+    EXPECT_EQ(*(ref2->str), u"a");
+    EXPECT_EQ(0u, ref2.getIndex());
+
+    EXPECT_EQ(*ref3, u"m");
+    EXPECT_EQ(1u, ref3.getIndex());
+}
+
+TEST(StringPoolTest, SortAndStillDedupe) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"z");
+    StringPool::Ref ref2 = pool.makeRef(u"a");
+    StringPool::Ref ref3 = pool.makeRef(u"m");
+
+    pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+        return a.value < b.value;
+    });
+
+    StringPool::Ref ref4 = pool.makeRef(u"z");
+    StringPool::Ref ref5 = pool.makeRef(u"a");
+    StringPool::Ref ref6 = pool.makeRef(u"m");
+
+    EXPECT_EQ(ref4.getIndex(), ref.getIndex());
+    EXPECT_EQ(ref5.getIndex(), ref2.getIndex());
+    EXPECT_EQ(ref6.getIndex(), ref3.getIndex());
+}
+
+TEST(StringPoolTest, AddStyles) {
+    StringPool pool;
+
+    StyleString str {
+        { u"android" },
+        {
+            Span{ { u"b" }, 2, 6 }
+        }
+    };
+
+    StringPool::StyleRef ref = pool.makeRef(str);
+
+    EXPECT_EQ(0u, ref.getIndex());
+    EXPECT_EQ(std::u16string(u"android"), *(ref->str));
+    ASSERT_EQ(1u, ref->spans.size());
+
+    const StringPool::Span& span = ref->spans.front();
+    EXPECT_EQ(*(span.name), u"b");
+    EXPECT_EQ(2u, span.firstChar);
+    EXPECT_EQ(6u, span.lastChar);
+}
+
+TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
+    StringPool pool;
+
+    StringPool::Ref ref = pool.makeRef(u"android");
+
+    StyleString str { { u"android" } };
+    StringPool::StyleRef styleRef = pool.makeRef(str);
+
+    EXPECT_NE(ref.getIndex(), styleRef.getIndex());
+}
+
+constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。";
+
+TEST(StringPoolTest, FlattenUtf8) {
+    StringPool pool;
+
+    StringPool::Ref ref1 = pool.makeRef(u"hello");
+    StringPool::Ref ref2 = pool.makeRef(u"goodbye");
+    StringPool::Ref ref3 = pool.makeRef(sLongString);
+    StringPool::StyleRef ref4 = pool.makeRef(StyleString{
+            { u"style" },
+            { Span{ { u"b" }, 0, 1 }, Span{ { u"i" }, 2, 3 } }
+    });
+
+    EXPECT_EQ(0u, ref1.getIndex());
+    EXPECT_EQ(1u, ref2.getIndex());
+    EXPECT_EQ(2u, ref3.getIndex());
+    EXPECT_EQ(3u, ref4.getIndex());
+
+    BigBuffer buffer(1024);
+    StringPool::flattenUtf8(&buffer, pool);
+
+    uint8_t* data = new uint8_t[buffer.size()];
+    uint8_t* p = data;
+    for (const auto& b : buffer) {
+        memcpy(p, b.buffer.get(), b.size);
+        p += b.size;
+    }
+
+    {
+        android::ResStringPool test;
+        ASSERT_EQ(android::NO_ERROR, test.setTo(data, buffer.size()));
+
+        EXPECT_EQ(util::getString(test, 0), u"hello");
+        EXPECT_EQ(util::getString(test, 1), u"goodbye");
+        EXPECT_EQ(util::getString(test, 2), sLongString);
+        EXPECT_EQ(util::getString(test, 3), u"style");
+
+        const android::ResStringPool_span* span = test.styleAt(3);
+        ASSERT_NE(nullptr, span);
+        EXPECT_EQ(util::getString(test, span->name.index), u"b");
+        EXPECT_EQ(0u, span->firstChar);
+        EXPECT_EQ(1u, span->lastChar);
+        span++;
+
+        ASSERT_NE(android::ResStringPool_span::END, span->name.index);
+        EXPECT_EQ(util::getString(test, span->name.index), u"i");
+        EXPECT_EQ(2u, span->firstChar);
+        EXPECT_EQ(3u, span->lastChar);
+        span++;
+
+        EXPECT_EQ(android::ResStringPool_span::END, span->name.index);
+    }
+    delete[] data;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/TableFlattener.cpp b/tools/aapt2/TableFlattener.cpp
new file mode 100644
index 0000000..c306185
--- /dev/null
+++ b/tools/aapt2/TableFlattener.cpp
@@ -0,0 +1,511 @@
+/*
+ * 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 "BigBuffer.h"
+#include "ConfigDescription.h"
+#include "Logger.h"
+#include "ResourceTable.h"
+#include "ResourceTypeExtensions.h"
+#include "ResourceValues.h"
+#include "StringPool.h"
+#include "TableFlattener.h"
+#include "Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <sstream>
+
+namespace aapt {
+
+struct FlatEntry {
+    const ResourceEntry& entry;
+    const Value& value;
+    uint32_t entryKey;
+    uint32_t sourcePathKey;
+    uint32_t sourceLine;
+};
+
+/**
+ * Visitor that knows how to encode Map values.
+ */
+class MapFlattener : public ConstValueVisitor {
+public:
+    MapFlattener(BigBuffer* out, const FlatEntry& flatEntry,
+                 std::vector<std::pair<ResourceNameRef, uint32_t>>& symbols) :
+            mOut(out), mSymbols(symbols) {
+        mMap = mOut->nextBlock<android::ResTable_map_entry>();
+        mMap->key.index = flatEntry.entryKey;
+        mMap->flags = android::ResTable_entry::FLAG_COMPLEX;
+        if (flatEntry.entry.publicStatus.isPublic) {
+            mMap->flags |= android::ResTable_entry::FLAG_PUBLIC;
+        }
+        if (flatEntry.value.isWeak()) {
+            mMap->flags |= android::ResTable_entry::FLAG_WEAK;
+        }
+
+        ResTable_entry_source* sourceBlock = mOut->nextBlock<ResTable_entry_source>();
+        sourceBlock->pathIndex = flatEntry.sourcePathKey;
+        sourceBlock->line = flatEntry.sourceLine;
+
+        mMap->size = sizeof(*mMap) + sizeof(*sourceBlock);
+    }
+
+    void flattenParent(const Reference& ref) {
+        if (!ref.id.isValid()) {
+            mSymbols.push_back({
+                    ResourceNameRef(ref.name),
+                    (mOut->size() - mMap->size) + sizeof(*mMap) - sizeof(android::ResTable_entry)
+            });
+        }
+        mMap->parent.ident = ref.id.id;
+    }
+
+    void flattenEntry(const Reference& key, const Item& value) {
+        mMap->count++;
+
+        android::ResTable_map* outMapEntry = mOut->nextBlock<android::ResTable_map>();
+
+        // Write the key.
+        if (!Res_INTERNALID(key.id.id) && !key.id.isValid()) {
+            mSymbols.push_back(std::make_pair(ResourceNameRef(key.name),
+                    mOut->size() - sizeof(*outMapEntry)));
+        }
+        outMapEntry->name.ident = key.id.id;
+
+        // Write the value.
+        value.flatten(outMapEntry->value);
+
+        if (outMapEntry->value.data == 0x0) {
+            visitFunc<Reference>(value, [&](const Reference& reference) {
+                mSymbols.push_back(std::make_pair(ResourceNameRef(reference.name),
+                        mOut->size() - sizeof(outMapEntry->value.data)));
+            });
+        }
+        outMapEntry->value.size = sizeof(outMapEntry->value);
+    }
+
+    static bool compareStyleEntries(const Style::Entry* lhs, const Style::Entry* rhs) {
+        return lhs->key.id < rhs->key.id;
+    }
+
+    void visit(const Style& style, ValueVisitorArgs&) override {
+        if (style.parent.name.isValid()) {
+            flattenParent(style.parent);
+        }
+
+        // First sort the entries by ID.
+        std::vector<const Style::Entry*> sortedEntries;
+        for (const auto& styleEntry : style.entries) {
+            auto iter = std::lower_bound(sortedEntries.begin(), sortedEntries.end(),
+                    &styleEntry, compareStyleEntries);
+            sortedEntries.insert(iter, &styleEntry);
+        }
+
+        for (const Style::Entry* styleEntry : sortedEntries) {
+            flattenEntry(styleEntry->key, *styleEntry->value);
+        }
+    }
+
+    void visit(const Attribute& attr, ValueVisitorArgs&) override {
+        android::Res_value tempVal;
+        tempVal.dataType = android::Res_value::TYPE_INT_DEC;
+        tempVal.data = attr.typeMask;
+        flattenEntry(Reference(ResourceId{android::ResTable_map::ATTR_TYPE}),
+                BinaryPrimitive(tempVal));
+
+        for (const auto& symbol : attr.symbols) {
+            tempVal.data = symbol.value;
+            flattenEntry(symbol.symbol, BinaryPrimitive(tempVal));
+        }
+    }
+
+    void visit(const Styleable& styleable, ValueVisitorArgs&) override {
+        for (const auto& attr : styleable.entries) {
+            flattenEntry(attr, BinaryPrimitive(android::Res_value{}));
+        }
+    }
+
+    void visit(const Array& array, ValueVisitorArgs&) override {
+        for (const auto& item : array.items) {
+            flattenEntry({}, *item);
+        }
+    }
+
+    void visit(const Plural& plural, ValueVisitorArgs&) override {
+        const size_t count = plural.values.size();
+        for (size_t i = 0; i < count; i++) {
+            if (!plural.values[i]) {
+                continue;
+            }
+
+            ResourceId q;
+            switch (i) {
+                case Plural::Zero:
+                    q.id = android::ResTable_map::ATTR_ZERO;
+                    break;
+
+                case Plural::One:
+                    q.id = android::ResTable_map::ATTR_ONE;
+                    break;
+
+                case Plural::Two:
+                    q.id = android::ResTable_map::ATTR_TWO;
+                    break;
+
+                case Plural::Few:
+                    q.id = android::ResTable_map::ATTR_FEW;
+                    break;
+
+                case Plural::Many:
+                    q.id = android::ResTable_map::ATTR_MANY;
+                    break;
+
+                case Plural::Other:
+                    q.id = android::ResTable_map::ATTR_OTHER;
+                    break;
+
+                default:
+                    assert(false);
+                    break;
+            }
+
+            flattenEntry(Reference(q), *plural.values[i]);
+        }
+    }
+
+private:
+    BigBuffer* mOut;
+    std::vector<std::pair<ResourceNameRef, uint32_t>>& mSymbols;
+    android::ResTable_map_entry* mMap;
+};
+
+TableFlattener::TableFlattener(Options options)
+: mOptions(options) {
+}
+
+bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry,
+        std::vector<std::pair<ResourceNameRef, uint32_t>>& symbolEntries) {
+    if (flatEntry.value.isItem()) {
+        android::ResTable_entry* entry = out->nextBlock<android::ResTable_entry>();
+
+        if (flatEntry.entry.publicStatus.isPublic) {
+            entry->flags |= android::ResTable_entry::FLAG_PUBLIC;
+        }
+
+        if (flatEntry.value.isWeak()) {
+            entry->flags |= android::ResTable_entry::FLAG_WEAK;
+        }
+
+        entry->key.index = flatEntry.entryKey;
+        entry->size = sizeof(*entry);
+
+        if (mOptions.useExtendedChunks) {
+            // Write the extra source block. This will be ignored by
+            // the Android runtime.
+            ResTable_entry_source* sourceBlock = out->nextBlock<ResTable_entry_source>();
+            sourceBlock->pathIndex = flatEntry.sourcePathKey;
+            sourceBlock->line = flatEntry.sourceLine;
+
+            entry->size += sizeof(*sourceBlock);
+        }
+
+        android::Res_value* outValue = out->nextBlock<android::Res_value>();
+
+        const Item& item = static_cast<const Item&>(flatEntry.value);
+        if (!item.flatten(*outValue)) {
+            return false;
+        }
+
+        if (outValue->data == 0x0) {
+            visitFunc<Reference>(item, [&](const Reference& reference) {
+                symbolEntries.push_back({
+                        ResourceNameRef(reference.name),
+                        out->size() - sizeof(outValue->data)
+                });
+            });
+        }
+        outValue->size = sizeof(*outValue);
+        return true;
+    }
+
+    MapFlattener flattener(out, flatEntry, symbolEntries);
+    flatEntry.value.accept(flattener, {});
+    return true;
+}
+
+bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) {
+    const size_t beginning = out->size();
+
+    if (table.getPackage().size() == 0) {
+        Logger::error()
+                << "ResourceTable has no package name."
+                << std::endl;
+        return false;
+    }
+
+    if (table.getPackageId() == ResourceTable::kUnsetPackageId) {
+        Logger::error()
+                << "ResourceTable has no package ID set."
+                << std::endl;
+        return false;
+    }
+
+    std::vector<std::pair<ResourceNameRef, uint32_t>> symbolEntries;
+
+    StringPool typePool;
+    StringPool keyPool;
+    StringPool sourcePool;
+
+    // Sort the types by their IDs. They will be inserted into the StringPool
+    // in this order.
+    std::vector<ResourceTableType*> sortedTypes;
+    for (const auto& type : table) {
+        if (type->type == ResourceType::kStyleable && !mOptions.useExtendedChunks) {
+            continue;
+        }
+
+        auto iter = std::lower_bound(std::begin(sortedTypes), std::end(sortedTypes), type.get(),
+                [](const ResourceTableType* lhs, const ResourceTableType* rhs) -> bool {
+                    return lhs->typeId < rhs->typeId;
+                });
+        sortedTypes.insert(iter, type.get());
+    }
+
+    BigBuffer typeBlock(1024);
+    size_t expectedTypeId = 1;
+    for (const ResourceTableType* type : sortedTypes) {
+        if (type->typeId == ResourceTableType::kUnsetTypeId
+                || type->typeId == 0) {
+            Logger::error()
+                    << "resource type '"
+                    << type->type
+                    << "' from package '"
+                    << table.getPackage()
+                    << "' has no ID."
+                    << std::endl;
+            return false;
+        }
+
+        // If there is a gap in the type IDs, fill in the StringPool
+        // with empty values until we reach the ID we expect.
+        while (type->typeId > expectedTypeId) {
+            std::u16string typeName(u"?");
+            typeName += expectedTypeId;
+            typePool.makeRef(typeName);
+            expectedTypeId++;
+        }
+        expectedTypeId++;
+        typePool.makeRef(toString(type->type));
+
+        android::ResTable_typeSpec* spec = typeBlock.nextBlock<android::ResTable_typeSpec>();
+        spec->header.type = android::RES_TABLE_TYPE_SPEC_TYPE;
+        spec->header.headerSize = sizeof(*spec);
+        spec->header.size = spec->header.headerSize + (type->entries.size() * sizeof(uint32_t));
+        spec->id = type->typeId;
+        spec->entryCount = type->entries.size();
+
+        // Reserve space for the masks of each resource in this type. These
+        // show for which configuration axis the resource changes.
+        uint32_t* configMasks = typeBlock.nextBlock<uint32_t>(type->entries.size());
+
+        // Sort the entries by entry ID and write their configuration masks.
+        std::vector<ResourceEntry*> entries;
+        const size_t entryCount = type->entries.size();
+        for (size_t entryIndex = 0; entryIndex < entryCount; entryIndex++) {
+            const auto& entry = type->entries[entryIndex];
+
+            if (entry->entryId == ResourceEntry::kUnsetEntryId) {
+                Logger::error()
+                        << "resource '"
+                        << ResourceName{ table.getPackage(), type->type, entry->name }
+                        << "' has no ID."
+                        << std::endl;
+                return false;
+            }
+
+            auto iter = std::lower_bound(std::begin(entries), std::end(entries), entry.get(),
+                    [](const ResourceEntry* lhs, const ResourceEntry* rhs) -> bool {
+                        return lhs->entryId < rhs->entryId;
+                    });
+            entries.insert(iter, entry.get());
+
+            // Populate the config masks for this entry.
+            if (entry->publicStatus.isPublic) {
+                configMasks[entry->entryId] |= android::ResTable_typeSpec::SPEC_PUBLIC;
+            }
+
+            const size_t configCount = entry->values.size();
+            for (size_t i = 0; i < configCount; i++) {
+                const ConfigDescription& config = entry->values[i].config;
+                for (size_t j = i + 1; j < configCount; j++) {
+                    configMasks[entry->entryId] |= config.diff(entry->values[j].config);
+                }
+            }
+        }
+
+        // The binary resource table lists resource entries for each configuration.
+        // We store them inverted, where a resource entry lists the values for each
+        // configuration available. Here we reverse this to match the binary table.
+        std::map<ConfigDescription, std::vector<FlatEntry>> data;
+        for (const ResourceEntry* entry : entries) {
+            size_t keyIndex = keyPool.makeRef(entry->name).getIndex();
+
+            if (keyIndex > std::numeric_limits<uint32_t>::max()) {
+                Logger::error()
+                        << "resource key string pool exceeded max size."
+                        << std::endl;
+                return false;
+            }
+
+            for (const auto& configValue : entry->values) {
+                data[configValue.config].push_back(FlatEntry{
+                        *entry,
+                        *configValue.value,
+                        static_cast<uint32_t>(keyIndex),
+                        static_cast<uint32_t>(sourcePool.makeRef(util::utf8ToUtf16(
+                                        configValue.source.path)).getIndex()),
+                        static_cast<uint32_t>(configValue.source.line)
+                });
+            }
+        }
+
+        // Begin flattening a configuration for the current type.
+        for (const auto& entry : data) {
+            const size_t typeHeaderStart = typeBlock.size();
+            android::ResTable_type* typeHeader = typeBlock.nextBlock<android::ResTable_type>();
+            typeHeader->header.type = android::RES_TABLE_TYPE_TYPE;
+            typeHeader->header.headerSize = sizeof(*typeHeader);
+            typeHeader->id = type->typeId;
+            typeHeader->entryCount = type->entries.size();
+            typeHeader->entriesStart = typeHeader->header.headerSize
+                    + (sizeof(uint32_t) * type->entries.size());
+            typeHeader->config = entry.first;
+
+            uint32_t* indices = typeBlock.nextBlock<uint32_t>(type->entries.size());
+            memset(indices, 0xff, type->entries.size() * sizeof(uint32_t));
+
+            const size_t entryStart = typeBlock.size();
+            for (const FlatEntry& flatEntry : entry.second) {
+                assert(flatEntry.entry.entryId < type->entries.size());
+                indices[flatEntry.entry.entryId] = typeBlock.size() - entryStart;
+                if (!flattenValue(&typeBlock, flatEntry, symbolEntries)) {
+                    Logger::error()
+                            << "failed to flatten resource '"
+                            << ResourceNameRef {
+                                    table.getPackage(), type->type, flatEntry.entry.name }
+                            << "' for configuration '"
+                            << entry.first
+                            << "'."
+                            << std::endl;
+                    return false;
+                }
+            }
+
+            typeBlock.align4();
+            typeHeader->header.size = typeBlock.size() - typeHeaderStart;
+        }
+    }
+
+    const size_t beforeTable = out->size();
+    android::ResTable_header* header = out->nextBlock<android::ResTable_header>();
+    header->header.type = android::RES_TABLE_TYPE;
+    header->header.headerSize = sizeof(*header);
+    header->packageCount = 1;
+
+    SymbolTable_entry* symbolEntryData = nullptr;
+    if (!symbolEntries.empty() && mOptions.useExtendedChunks) {
+        const size_t beforeSymbolTable = out->size();
+        StringPool symbolPool;
+        SymbolTable_header* symbolHeader = out->nextBlock<SymbolTable_header>();
+        symbolHeader->header.type = RES_TABLE_SYMBOL_TABLE_TYPE;
+        symbolHeader->header.headerSize = sizeof(*symbolHeader);
+        symbolHeader->count = symbolEntries.size();
+
+        symbolEntryData = out->nextBlock<SymbolTable_entry>(symbolHeader->count);
+
+        size_t i = 0;
+        for (const auto& entry : symbolEntries) {
+            symbolEntryData[i].offset = entry.second;
+            StringPool::Ref ref = symbolPool.makeRef(
+                    entry.first.package.toString() + u":" +
+                    toString(entry.first.type).toString() + u"/" +
+                    entry.first.entry.toString());
+            symbolEntryData[i].stringIndex = ref.getIndex();
+            i++;
+        }
+
+        StringPool::flattenUtf8(out, symbolPool);
+        out->align4();
+        symbolHeader->header.size = out->size() - beforeSymbolTable;
+    }
+
+    if (sourcePool.size() > 0 && mOptions.useExtendedChunks) {
+        const size_t beforeSourcePool = out->size();
+        android::ResChunk_header* sourceHeader = out->nextBlock<android::ResChunk_header>();
+        sourceHeader->type = RES_TABLE_SOURCE_POOL_TYPE;
+        sourceHeader->headerSize = sizeof(*sourceHeader);
+        StringPool::flattenUtf8(out, sourcePool);
+        out->align4();
+        sourceHeader->size = out->size() - beforeSourcePool;
+    }
+
+    StringPool::flattenUtf8(out, table.getValueStringPool());
+
+    const size_t beforePackageIndex = out->size();
+    android::ResTable_package* package = out->nextBlock<android::ResTable_package>();
+    package->header.type = android::RES_TABLE_PACKAGE_TYPE;
+    package->header.headerSize = sizeof(*package);
+
+    if (table.getPackageId() > std::numeric_limits<uint8_t>::max()) {
+        Logger::error()
+                << "package ID 0x'"
+                << std::hex << table.getPackageId() << std::dec
+                << "' is invalid."
+                << std::endl;
+        return false;
+    }
+    package->id = table.getPackageId();
+
+    if (table.getPackage().size() >= sizeof(package->name) / sizeof(package->name[0])) {
+        Logger::error()
+                << "package name '"
+                << table.getPackage()
+                << "' is too long."
+                << std::endl;
+        return false;
+    }
+    memcpy(package->name, reinterpret_cast<const uint16_t*>(table.getPackage().data()),
+            table.getPackage().length() * sizeof(char16_t));
+    package->name[table.getPackage().length()] = 0;
+
+    package->typeStrings = package->header.headerSize;
+    StringPool::flattenUtf8(out, typePool);
+    package->keyStrings = out->size() - beforePackageIndex;
+    StringPool::flattenUtf8(out, keyPool);
+
+    if (symbolEntryData != nullptr) {
+        for (size_t i = 0; i < symbolEntries.size(); i++) {
+            symbolEntryData[i].offset += out->size() - beginning;
+        }
+    }
+
+    out->appendBuffer(std::move(typeBlock));
+
+    package->header.size = out->size() - beforePackageIndex;
+    header->header.size = out->size() - beforeTable;
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/TableFlattener.h b/tools/aapt2/TableFlattener.h
new file mode 100644
index 0000000..0ae798c
--- /dev/null
+++ b/tools/aapt2/TableFlattener.h
@@ -0,0 +1,60 @@
+/*
+ * 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_TABLE_FLATTENER_H
+#define AAPT_TABLE_FLATTENER_H
+
+#include "BigBuffer.h"
+#include "ResourceTable.h"
+
+namespace aapt {
+
+struct FlatEntry;
+
+/**
+ * Flattens a ResourceTable into a binary format suitable
+ * for loading into a ResTable on the host or device.
+ */
+struct TableFlattener {
+    /**
+     * A set of options for this TableFlattener.
+     */
+    struct Options {
+        /**
+         * Specifies whether to output extended chunks, like
+         * source information and mising symbol entries. Default
+         * is true.
+         *
+         * Set this to false when emitting the final table to be used
+         * on device.
+         */
+        bool useExtendedChunks = true;
+    };
+
+    TableFlattener(Options options);
+
+    bool flatten(BigBuffer* out, const ResourceTable& table);
+
+private:
+    bool flattenValue(BigBuffer* out, const FlatEntry& flatEntry,
+                      std::vector<std::pair<ResourceNameRef, uint32_t>>& symbolEntries);
+
+    Options mOptions;
+};
+
+} // namespace aapt
+
+#endif // AAPT_TABLE_FLATTENER_H
diff --git a/tools/aapt2/Util.cpp b/tools/aapt2/Util.cpp
new file mode 100644
index 0000000..8a4c88f
--- /dev/null
+++ b/tools/aapt2/Util.cpp
@@ -0,0 +1,290 @@
+/*
+ * 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 "BigBuffer.h"
+#include "Maybe.h"
+#include "StringPiece.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <ostream>
+#include <string>
+#include <utils/Unicode.h>
+#include <vector>
+
+namespace aapt {
+namespace util {
+
+static std::vector<std::string> splitAndTransform(const StringPiece& str, char sep,
+        const std::function<char(char)>& f) {
+    std::vector<std::string> parts;
+    const StringPiece::const_iterator end = std::end(str);
+    StringPiece::const_iterator start = std::begin(str);
+    StringPiece::const_iterator current;
+    do {
+        current = std::find(start, end, sep);
+        parts.emplace_back(str.substr(start, current).toString());
+        if (f) {
+            std::string& part = parts.back();
+            std::transform(part.begin(), part.end(), part.begin(), f);
+        }
+        start = current + 1;
+    } while (current != end);
+    return parts;
+}
+
+std::vector<std::string> split(const StringPiece& str, char sep) {
+    return splitAndTransform(str, sep, nullptr);
+}
+
+std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep) {
+    return splitAndTransform(str, sep, ::tolower);
+}
+
+bool stringEndsWith(const StringPiece& str, const StringPiece& suffix) {
+    if (str.size() < suffix.size()) {
+        return false;
+    }
+    return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
+}
+
+StringPiece16 trimWhitespace(const StringPiece16& str) {
+    if (str.size() == 0 || str.data() == nullptr) {
+        return str;
+    }
+
+    const char16_t* start = str.data();
+    const char16_t* end = str.data() + str.length();
+
+    while (start != end && util::isspace16(*start)) {
+        start++;
+    }
+
+    while (end != start && util::isspace16(*(end - 1))) {
+        end--;
+    }
+
+    return StringPiece16(start, end - start);
+}
+
+StringPiece16::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece16& str,
+        const StringPiece16& allowedChars) {
+    const auto endIter = str.end();
+    for (auto iter = str.begin(); iter != endIter; ++iter) {
+        char16_t c = *iter;
+        if ((c >= u'a' && c <= u'z') ||
+                (c >= u'A' && c <= u'Z') ||
+                (c >= u'0' && c <= u'9')) {
+            continue;
+        }
+
+        bool match = false;
+        for (char16_t i : allowedChars) {
+            if (c == i) {
+                match = true;
+                break;
+            }
+        }
+
+        if (!match) {
+            return iter;
+        }
+    }
+    return endIter;
+}
+
+static Maybe<char16_t> parseUnicodeCodepoint(const char16_t** start, const char16_t* end) {
+    char16_t code = 0;
+    for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) {
+        char16_t c = **start;
+        int a;
+        if (c >= '0' && c <= '9') {
+            a = c - '0';
+        } else if (c >= 'a' && c <= 'f') {
+            a = c - 'a' + 10;
+        } else if (c >= 'A' && c <= 'F') {
+            a = c - 'A' + 10;
+        } else {
+            return make_nothing<char16_t>();
+        }
+        code = (code << 4) | a;
+    }
+    return make_value(code);
+}
+
+StringBuilder& StringBuilder::append(const StringPiece16& str) {
+    if (!mError.empty()) {
+        return *this;
+    }
+
+    const char16_t* const end = str.end();
+    const char16_t* start = str.begin();
+    const char16_t* current = start;
+    while (current != end) {
+        if (*current == u'"') {
+            if (!mQuote && mTrailingSpace) {
+                // We found an opening quote, and we have
+                // trailing space, so we should append that
+                // space now.
+                if (mTrailingSpace) {
+                    // We had trailing whitespace, so
+                    // replace with a single space.
+                    if (!mStr.empty()) {
+                        mStr += u' ';
+                    }
+                    mTrailingSpace = false;
+                }
+            }
+            mQuote = !mQuote;
+            mStr.append(start, current - start);
+            start = current + 1;
+        } else if (*current == u'\'' && !mQuote) {
+            // This should be escaped.
+            mError = "unescaped apostrophe";
+            return *this;
+        } else if (*current == u'\\') {
+            // This is an escape sequence, convert to the real value.
+            if (!mQuote && mTrailingSpace) {
+                // We had trailing whitespace, so
+                // replace with a single space.
+                if (!mStr.empty()) {
+                    mStr += u' ';
+                }
+                mTrailingSpace = false;
+            }
+            mStr.append(start, current - start);
+            start = current + 1;
+
+            current++;
+            if (current != end) {
+                switch (*current) {
+                    case u't':
+                        mStr += u'\t';
+                        break;
+                    case u'n':
+                        mStr += u'\n';
+                        break;
+                    case u'#':
+                        mStr += u'#';
+                        break;
+                    case u'@':
+                        mStr += u'@';
+                        break;
+                    case u'?':
+                        mStr += u'?';
+                        break;
+                    case u'"':
+                        mStr += u'"';
+                        break;
+                    case u'\'':
+                        mStr += u'\'';
+                        break;
+                    case u'\\':
+                        mStr += u'\\';
+                        break;
+                    case u'u': {
+                        current++;
+                        Maybe<char16_t> c = parseUnicodeCodepoint(&current, end);
+                        if (!c) {
+                            mError = "invalid unicode escape sequence";
+                            return *this;
+                        }
+                        mStr += c.value();
+                        current -= 1;
+                        break;
+                    }
+
+                    default:
+                        // Ignore.
+                        break;
+                }
+                start = current + 1;
+            }
+        } else if (!mQuote) {
+            // This is not quoted text, so look for whitespace.
+            if (isspace16(*current)) {
+                // We found whitespace, see if we have seen some
+                // before.
+                if (!mTrailingSpace) {
+                    // We didn't see a previous adjacent space,
+                    // so mark that we did.
+                    mTrailingSpace = true;
+                    mStr.append(start, current - start);
+                }
+
+                // Keep skipping whitespace.
+                start = current + 1;
+            } else if (mTrailingSpace) {
+                // We saw trailing space before, so replace all
+                // that trailing space with one space.
+                if (!mStr.empty()) {
+                    mStr += u' ';
+                }
+                mTrailingSpace = false;
+            }
+        }
+        current++;
+    }
+    mStr.append(start, end - start);
+    return *this;
+}
+
+std::u16string utf8ToUtf16(const StringPiece& utf8) {
+    ssize_t utf16Length = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(utf8.data()),
+            utf8.length());
+    if (utf16Length <= 0) {
+        return {};
+    }
+
+    std::u16string utf16;
+    utf16.resize(utf16Length);
+    utf8_to_utf16(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length(), &*utf16.begin());
+    return utf16;
+}
+
+std::string utf16ToUtf8(const StringPiece16& utf16) {
+    ssize_t utf8Length = utf16_to_utf8_length(utf16.data(), utf16.length());
+    if (utf8Length <= 0) {
+        return {};
+    }
+
+    std::string utf8;
+    utf8.resize(utf8Length);
+    utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin());
+    return utf8;
+}
+
+bool writeAll(std::ostream& out, const BigBuffer& buffer) {
+    for (const auto& b : buffer) {
+        if (!out.write(reinterpret_cast<const char*>(b.buffer.get()), b.size)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer) {
+    std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]);
+    uint8_t* p = data.get();
+    for (const auto& block : buffer) {
+        memcpy(p, block.buffer.get(), block.size);
+        p += block.size;
+    }
+    return data;
+}
+
+} // namespace util
+} // namespace aapt
diff --git a/tools/aapt2/Util.h b/tools/aapt2/Util.h
new file mode 100644
index 0000000..4c5249be
--- /dev/null
+++ b/tools/aapt2/Util.h
@@ -0,0 +1,276 @@
+/*
+ * 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_UTIL_H
+#define AAPT_UTIL_H
+
+#include "BigBuffer.h"
+#include "StringPiece.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <functional>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <vector>
+
+namespace aapt {
+namespace util {
+
+std::vector<std::string> split(const StringPiece& str, char sep);
+std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep);
+
+/**
+ * Returns true if the string ends with suffix.
+ */
+bool stringEndsWith(const StringPiece& str, const StringPiece& suffix);
+
+/**
+ * Creates a new StringPiece16 that points to a substring
+ * of the original string without leading or trailing whitespace.
+ */
+StringPiece16 trimWhitespace(const StringPiece16& str);
+
+/**
+ * UTF-16 isspace(). It basically checks for lower range characters that are
+ * whitespace.
+ */
+inline bool isspace16(char16_t c) {
+    return c < 0x0080 && isspace(c);
+}
+
+/**
+ * Returns an iterator to the first character that is not alpha-numeric and that
+ * is not in the allowedChars set.
+ */
+StringPiece16::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece16& str,
+        const StringPiece16& allowedChars);
+
+/**
+ * Makes a std::unique_ptr<> with the template parameter inferred by the compiler.
+ * This will be present in C++14 and can be removed then.
+ */
+template <typename T, class... Args>
+std::unique_ptr<T> make_unique(Args&&... args) {
+    return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
+}
+
+/**
+ * Writes a set of items to the std::ostream, joining the times with the provided
+ * separator.
+ */
+template <typename Iterator>
+::std::function<::std::ostream&(::std::ostream&)> joiner(Iterator begin, Iterator end,
+        const char* sep) {
+    return [begin, end, sep](::std::ostream& out) -> ::std::ostream& {
+        for (auto iter = begin; iter != end; ++iter) {
+            if (iter != begin) {
+                out << sep;
+            }
+            out << *iter;
+        }
+        return out;
+    };
+}
+
+inline ::std::function<::std::ostream&(::std::ostream&)> formatSize(size_t size) {
+    return [size](::std::ostream& out) -> ::std::ostream& {
+        constexpr size_t K = 1024;
+        constexpr size_t M = K * K;
+        constexpr size_t G = M * M;
+        if (size < K) {
+            out << size << "B";
+        } else if (size < M) {
+            out << (double(size) / K) << " KiB";
+        } else if (size < G) {
+            out << (double(size) / M) << " MiB";
+        } else {
+            out << (double(size) / G) << " GiB";
+        }
+        return out;
+    };
+}
+
+/**
+ * Helper method to extract a string from a StringPool.
+ */
+inline StringPiece16 getString(const android::ResStringPool& pool, size_t idx) {
+    size_t len;
+    const char16_t* str = pool.stringAt(idx, &len);
+    if (str != nullptr) {
+        return StringPiece16(str, len);
+    }
+    return StringPiece16();
+}
+
+class StringBuilder {
+public:
+    StringBuilder& append(const StringPiece16& str);
+    const std::u16string& str() const;
+    const std::string& error() const;
+    operator bool() const;
+
+private:
+    std::u16string mStr;
+    bool mQuote = false;
+    bool mTrailingSpace = false;
+    std::string mError;
+};
+
+inline const std::u16string& StringBuilder::str() const {
+    return mStr;
+}
+
+inline const std::string& StringBuilder::error() const {
+    return mError;
+}
+
+inline StringBuilder::operator bool() const {
+    return mError.empty();
+}
+
+/**
+ * Converts a UTF8 string to a UTF16 string.
+ */
+std::u16string utf8ToUtf16(const StringPiece& utf8);
+std::string utf16ToUtf8(const StringPiece16& utf8);
+
+/**
+ * Writes the entire BigBuffer to the output stream.
+ */
+bool writeAll(std::ostream& out, const BigBuffer& buffer);
+
+/*
+ * Copies the entire BigBuffer into a single buffer.
+ */
+std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer);
+
+/**
+ * A Tokenizer implemented as an iterable collection. It does not allocate
+ * any memory on the heap nor use standard containers.
+ */
+template <typename Char>
+class Tokenizer {
+public:
+    class iterator {
+    public:
+        iterator(const iterator&) = default;
+        iterator& operator=(const iterator&) = default;
+
+        iterator& operator++();
+        BasicStringPiece<Char> operator*();
+        bool operator==(const iterator& rhs) const;
+        bool operator!=(const iterator& rhs) const;
+
+    private:
+        friend class Tokenizer<Char>;
+
+        iterator(BasicStringPiece<Char> s, Char sep, BasicStringPiece<Char> tok);
+
+        BasicStringPiece<Char> str;
+        Char separator;
+        BasicStringPiece<Char> token;
+    };
+
+    Tokenizer(BasicStringPiece<Char> str, Char sep);
+    iterator begin();
+    iterator end();
+
+private:
+    const iterator mBegin;
+    const iterator mEnd;
+};
+
+template <typename Char>
+inline Tokenizer<Char> tokenize(BasicStringPiece<Char> str, Char sep) {
+    return Tokenizer<Char>(str, sep);
+}
+
+template <typename Char>
+typename Tokenizer<Char>::iterator& Tokenizer<Char>::iterator::operator++() {
+    const Char* start = token.end();
+    const Char* end = str.end();
+    if (start == end) {
+        token.assign(token.end(), 0);
+        return *this;
+    }
+
+    start += 1;
+    const Char* current = start;
+    while (current != end) {
+        if (*current == separator) {
+            token.assign(start, current - start);
+            return *this;
+        }
+        ++current;
+    }
+    token.assign(start, end - start);
+    return *this;
+}
+
+template <typename Char>
+inline BasicStringPiece<Char> Tokenizer<Char>::iterator::operator*() {
+    return token;
+}
+
+template <typename Char>
+inline bool Tokenizer<Char>::iterator::operator==(const iterator& rhs) const {
+    // We check equality here a bit differently.
+    // We need to know that the addresses are the same.
+    return token.begin() == rhs.token.begin() && token.end() == rhs.token.end();
+}
+
+template <typename Char>
+inline bool Tokenizer<Char>::iterator::operator!=(const iterator& rhs) const {
+    return !(*this == rhs);
+}
+
+template <typename Char>
+inline Tokenizer<Char>::iterator::iterator(BasicStringPiece<Char> s, Char sep,
+                                           BasicStringPiece<Char> tok) :
+        str(s), separator(sep), token(tok) {
+}
+
+template <typename Char>
+inline typename Tokenizer<Char>::iterator Tokenizer<Char>::begin() {
+    return mBegin;
+}
+
+template <typename Char>
+inline typename Tokenizer<Char>::iterator Tokenizer<Char>::end() {
+    return mEnd;
+}
+
+template <typename Char>
+inline Tokenizer<Char>::Tokenizer(BasicStringPiece<Char> str, Char sep) :
+        mBegin(++iterator(str, sep, BasicStringPiece<Char>(str.begin() - 1, 0))),
+        mEnd(str, sep, BasicStringPiece<Char>(str.end(), 0)) {
+}
+
+} // namespace util
+
+/**
+ * Stream operator for functions. Calls the function with the stream as an argument.
+ * In the aapt namespace for lookup.
+ */
+inline ::std::ostream& operator<<(::std::ostream& out,
+                                  ::std::function<::std::ostream&(::std::ostream&)> f) {
+    return f(out);
+}
+
+} // namespace aapt
+
+#endif // AAPT_UTIL_H
diff --git a/tools/aapt2/Util_test.cpp b/tools/aapt2/Util_test.cpp
new file mode 100644
index 0000000..7dbe7e0
--- /dev/null
+++ b/tools/aapt2/Util_test.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <string>
+
+#include "StringPiece.h"
+#include "Util.h"
+
+namespace aapt {
+
+TEST(UtilTest, TrimOnlyWhitespace) {
+    const std::u16string full = u"\n        ";
+
+    StringPiece16 trimmed = util::trimWhitespace(full);
+    EXPECT_TRUE(trimmed.empty());
+    EXPECT_EQ(0u, trimmed.size());
+}
+
+TEST(UtilTest, StringEndsWith) {
+    EXPECT_TRUE(util::stringEndsWith("hello.xml", ".xml"));
+}
+
+TEST(UtilTest, StringBuilderWhitespaceRemoval) {
+    EXPECT_EQ(StringPiece16(u"hey guys this is so cool"),
+            util::StringBuilder().append(u"    hey guys ")
+                                 .append(u" this is so cool ")
+                                 .str());
+
+    EXPECT_EQ(StringPiece16(u" wow,  so many \t spaces. what?"),
+            util::StringBuilder().append(u" \" wow,  so many \t ")
+                                 .append(u"spaces. \"what? ")
+                                 .str());
+
+    EXPECT_EQ(StringPiece16(u"where is the pie?"),
+            util::StringBuilder().append(u"  where \t ")
+                                 .append(u" \nis the "" pie?")
+                                 .str());
+}
+
+TEST(UtilTest, StringBuilderEscaping) {
+    EXPECT_EQ(StringPiece16(u"hey guys\n this \t is so\\ cool"),
+            util::StringBuilder().append(u"    hey guys\\n ")
+                                 .append(u" this \\t is so\\\\ cool ")
+                                 .str());
+
+    EXPECT_EQ(StringPiece16(u"@?#\\\'"),
+            util::StringBuilder().append(u"\\@\\?\\#\\\\\\'")
+                                 .str());
+}
+
+TEST(UtilTest, StringBuilderMisplacedQuote) {
+    util::StringBuilder builder{};
+    EXPECT_FALSE(builder.append(u"they're coming!"));
+}
+
+TEST(UtilTest, StringBuilderUnicodeCodes) {
+    EXPECT_EQ(StringPiece16(u"\u00AF\u0AF0 woah"),
+            util::StringBuilder().append(u"\\u00AF\\u0AF0 woah")
+                                 .str());
+
+    EXPECT_FALSE(util::StringBuilder().append(u"\\u00 yo"));
+}
+
+TEST(UtilTest, TokenizeInput) {
+    auto tokenizer = util::tokenize(StringPiece16(u"this| is|the|end"), u'|');
+    auto iter = tokenizer.begin();
+    ASSERT_EQ(*iter, StringPiece16(u"this"));
+    ++iter;
+    ASSERT_EQ(*iter, StringPiece16(u" is"));
+    ++iter;
+    ASSERT_EQ(*iter, StringPiece16(u"the"));
+    ++iter;
+    ASSERT_EQ(*iter, StringPiece16(u"end"));
+    ++iter;
+    ASSERT_EQ(tokenizer.end(), iter);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XliffXmlPullParser.cpp b/tools/aapt2/XliffXmlPullParser.cpp
new file mode 100644
index 0000000..f0950a3
--- /dev/null
+++ b/tools/aapt2/XliffXmlPullParser.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "XliffXmlPullParser.h"
+
+#include <string>
+
+namespace aapt {
+
+XliffXmlPullParser::XliffXmlPullParser(const std::shared_ptr<XmlPullParser>& parser) :
+        mParser(parser) {
+}
+
+XmlPullParser::Event XliffXmlPullParser::next() {
+    while (XmlPullParser::isGoodEvent(mParser->next())) {
+        Event event = mParser->getEvent();
+        if (event != Event::kStartElement && event != Event::kEndElement) {
+            break;
+        }
+
+        if (mParser->getElementNamespace() !=
+                u"urn:oasis:names:tc:xliff:document:1.2") {
+            break;
+        }
+
+        const std::u16string& name = mParser->getElementName();
+        if (name != u"bpt"
+                && name != u"ept"
+                && name != u"it"
+                && name != u"ph"
+                && name != u"g"
+                && name != u"bx"
+                && name != u"ex"
+                && name != u"x") {
+            break;
+        }
+
+        // We hit a tag that was ignored, so get the next event.
+    }
+    return mParser->getEvent();
+}
+
+XmlPullParser::Event XliffXmlPullParser::getEvent() const {
+    return mParser->getEvent();
+}
+
+const std::string& XliffXmlPullParser::getLastError() const {
+    return mParser->getLastError();
+}
+
+const std::u16string& XliffXmlPullParser::getComment() const {
+    return mParser->getComment();
+}
+
+size_t XliffXmlPullParser::getLineNumber() const {
+    return mParser->getLineNumber();
+}
+
+size_t XliffXmlPullParser::getDepth() const {
+    return mParser->getDepth();
+}
+
+const std::u16string& XliffXmlPullParser::getText() const {
+    return mParser->getText();
+}
+
+const std::u16string& XliffXmlPullParser::getNamespacePrefix() const {
+    return mParser->getNamespacePrefix();
+}
+
+const std::u16string& XliffXmlPullParser::getNamespaceUri() const {
+    return mParser->getNamespaceUri();
+}
+
+const std::u16string& XliffXmlPullParser::getElementNamespace() const {
+    return mParser->getElementNamespace();
+}
+
+const std::u16string& XliffXmlPullParser::getElementName() const {
+    return mParser->getElementName();
+}
+
+size_t XliffXmlPullParser::getAttributeCount() const {
+    return mParser->getAttributeCount();
+}
+
+XmlPullParser::const_iterator XliffXmlPullParser::beginAttributes() const {
+    return mParser->beginAttributes();
+}
+
+XmlPullParser::const_iterator XliffXmlPullParser::endAttributes() const {
+    return mParser->endAttributes();
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XliffXmlPullParser.h b/tools/aapt2/XliffXmlPullParser.h
new file mode 100644
index 0000000..d362521
--- /dev/null
+++ b/tools/aapt2/XliffXmlPullParser.h
@@ -0,0 +1,61 @@
+/*
+ * 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_XLIFF_XML_PULL_PARSER_H
+#define AAPT_XLIFF_XML_PULL_PARSER_H
+
+#include "XmlPullParser.h"
+
+#include <string>
+
+namespace aapt {
+
+/**
+ * Strips xliff elements and provides the caller with a view of the
+ * underlying XML without xliff.
+ */
+class XliffXmlPullParser : public XmlPullParser {
+public:
+    XliffXmlPullParser(const std::shared_ptr<XmlPullParser>& parser);
+    XliffXmlPullParser(const XliffXmlPullParser& rhs) = delete;
+
+    Event getEvent() const;
+    const std::string& getLastError() const;
+    Event next();
+
+    const std::u16string& getComment() const;
+    size_t getLineNumber() const;
+    size_t getDepth() const;
+
+    const std::u16string& getText() const;
+
+    const std::u16string& getNamespacePrefix() const;
+    const std::u16string& getNamespaceUri() const;
+
+    const std::u16string& getElementNamespace() const;
+    const std::u16string& getElementName() const;
+
+    const_iterator beginAttributes() const;
+    const_iterator endAttributes() const;
+    size_t getAttributeCount() const;
+
+private:
+    std::shared_ptr<XmlPullParser> mParser;
+};
+
+} // namespace aapt
+
+#endif // AAPT_XLIFF_XML_PULL_PARSER_H
diff --git a/tools/aapt2/XliffXmlPullParser_test.cpp b/tools/aapt2/XliffXmlPullParser_test.cpp
new file mode 100644
index 0000000..f9030724
--- /dev/null
+++ b/tools/aapt2/XliffXmlPullParser_test.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 "SourceXmlPullParser.h"
+#include "XliffXmlPullParser.h"
+
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+TEST(XliffXmlPullParserTest, IgnoreXliffTags) {
+    std::stringstream input;
+    input << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
+          << "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">" << std::endl
+          << "<string name=\"foo\">"
+          << "Hey <xliff:g><xliff:it>there</xliff:it></xliff:g> world</string>" << std::endl
+          << "</resources>" << std::endl;
+    std::shared_ptr<XmlPullParser> sourceParser = std::make_shared<SourceXmlPullParser>(input);
+    XliffXmlPullParser parser(sourceParser);
+    EXPECT_EQ(XmlPullParser::Event::kStartDocument, parser.getEvent());
+
+    EXPECT_EQ(XmlPullParser::Event::kStartNamespace, parser.next());
+    EXPECT_EQ(parser.getNamespaceUri(), u"urn:oasis:names:tc:xliff:document:1.2");
+    EXPECT_EQ(parser.getNamespacePrefix(), u"xliff");
+
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, parser.next());
+    EXPECT_EQ(parser.getElementNamespace(), u"");
+    EXPECT_EQ(parser.getElementName(), u"resources");
+    EXPECT_EQ(XmlPullParser::Event::kText, parser.next()); // Account for newline/whitespace.
+
+    EXPECT_EQ(XmlPullParser::Event::kStartElement, parser.next());
+    EXPECT_EQ(parser.getElementNamespace(), u"");
+    EXPECT_EQ(parser.getElementName(), u"string");
+
+    EXPECT_EQ(XmlPullParser::Event::kText, parser.next());
+    EXPECT_EQ(parser.getText(), u"Hey ");
+
+    EXPECT_EQ(XmlPullParser::Event::kText, parser.next());
+    EXPECT_EQ(parser.getText(), u"there");
+
+    EXPECT_EQ(XmlPullParser::Event::kText, parser.next());
+    EXPECT_EQ(parser.getText(), u" world");
+
+    EXPECT_EQ(XmlPullParser::Event::kEndElement, parser.next());
+    EXPECT_EQ(parser.getElementNamespace(), u"");
+    EXPECT_EQ(parser.getElementName(), u"string");
+    EXPECT_EQ(XmlPullParser::Event::kText, parser.next()); // Account for newline/whitespace.
+
+    EXPECT_EQ(XmlPullParser::Event::kEndElement, parser.next());
+    EXPECT_EQ(parser.getElementNamespace(), u"");
+    EXPECT_EQ(parser.getElementName(), u"resources");
+
+    EXPECT_EQ(XmlPullParser::Event::kEndNamespace, parser.next());
+    EXPECT_EQ(parser.getNamespacePrefix(), u"xliff");
+    EXPECT_EQ(parser.getNamespaceUri(), u"urn:oasis:names:tc:xliff:document:1.2");
+
+    EXPECT_EQ(XmlPullParser::Event::kEndDocument, parser.next());
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XmlFlattener.cpp b/tools/aapt2/XmlFlattener.cpp
new file mode 100644
index 0000000..b6ca6d5
--- /dev/null
+++ b/tools/aapt2/XmlFlattener.cpp
@@ -0,0 +1,437 @@
+/*
+ * 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 "BigBuffer.h"
+#include "Logger.h"
+#include "Maybe.h"
+#include "Resolver.h"
+#include "Resource.h"
+#include "ResourceParser.h"
+#include "ResourceValues.h"
+#include "SdkConstants.h"
+#include "Source.h"
+#include "StringPool.h"
+#include "Util.h"
+#include "XmlFlattener.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <limits>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+struct AttributeValueFlattener : ValueVisitor {
+    struct Args : ValueVisitorArgs {
+        Args(std::shared_ptr<Resolver> r, SourceLogger& s, android::Res_value& oV,
+                std::shared_ptr<XmlPullParser> p, bool& e, StringPool::Ref& rV,
+                std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>>& sR) :
+                resolver(r), logger(s), outValue(oV), parser(p), error(e), rawValue(rV),
+                stringRefs(sR) {
+        }
+
+        std::shared_ptr<Resolver> resolver;
+        SourceLogger& logger;
+        android::Res_value& outValue;
+        std::shared_ptr<XmlPullParser> parser;
+        bool& error;
+        StringPool::Ref& rawValue;
+        std::vector<std::pair<StringPool::Ref, android::ResStringPool_ref*>>& stringRefs;
+    };
+
+    void visit(Reference& reference, ValueVisitorArgs& a) override {
+        Args& args = static_cast<Args&>(a);
+
+        Maybe<ResourceId> result = args.resolver->findId(reference.name);
+        if (!result || !result.value().isValid()) {
+            args.logger.error(args.parser->getLineNumber())
+                    << "unresolved reference '"
+                    << reference.name
+                    << "'."
+                    << std::endl;
+            args.error = true;
+        } else {
+            reference.id = result.value();
+            reference.flatten(args.outValue);
+        }
+    }
+
+    void visit(String& string, ValueVisitorArgs& a) override {
+        Args& args = static_cast<Args&>(a);
+
+        args.outValue.dataType = android::Res_value::TYPE_STRING;
+        args.stringRefs.emplace_back(args.rawValue,
+                reinterpret_cast<android::ResStringPool_ref*>(&args.outValue.data));
+    }
+
+    void visitItem(Item& item, ValueVisitorArgs& a) override {
+        Args& args = static_cast<Args&>(a);
+        item.flatten(args.outValue);
+    }
+};
+
+struct XmlAttribute {
+    uint32_t resourceId;
+    const XmlPullParser::Attribute* xmlAttr;
+    const Attribute* attr;
+    StringPool::Ref nameRef;
+};
+
+static bool lessAttributeId(const XmlAttribute& a, uint32_t id) {
+    return a.resourceId < id;
+}
+
+XmlFlattener::XmlFlattener(const std::shared_ptr<Resolver>& resolver) : mResolver(resolver) {
+}
+
+/**
+ * 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
+ * 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>();
+                stringRefs.emplace_back(
+                        pool.makeRef(parser->getElementNamespace(), lowPriority), &elem->ns);
+                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 (attrIter->namespaceUri.empty()) {
+                        // 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 {
+                        StringPiece16 package;
+                        if (attrIter->namespaceUri == u"http://schemas.android.com/apk/res-auto") {
+                            package = mResolver->getDefaultPackage();
+                        } else {
+                            // TODO(adamlesinski): Extract package from namespace.
+                            // The package name appears like so:
+                            // http://schemas.android.com/apk/res/<package name>
+                            package = u"android";
+                        }
+
+                        // Find the Attribute object via our Resolver.
+                        ResourceName attrName = {
+                                package.toString(), ResourceType::kAttr, attrIter->name };
+                        Maybe<Resolver::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;
+                        }
+
+                        if (options.maxSdkAttribute && package == u"android") {
+                            size_t sdkVersion = findAttributeSdkLevel(attrIter->name);
+                            if (sdkVersion > options.maxSdkAttribute.value()) {
+                                // We will silently omit this attribute
+                                smallestStrippedAttributeSdk =
+                                        std::min(smallestStrippedAttributeSdk, sdkVersion);
+                                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.toString()].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.
+                for (auto entry : sortedAttributes) {
+                    android::ResXMLTree_attribute* attr =
+                            out.nextBlock<android::ResXMLTree_attribute>();
+                    stringRefs.emplace_back(
+                            pool.makeRef(entry.xmlAttr->namespaceUri, lowPriority), &attr->ns);
+                    StringPool::Ref rawValueRef = pool.makeRef(entry.xmlAttr->value, lowPriority);
+                    stringRefs.emplace_back(rawValueRef, &attr->rawValue);
+                    stringRefs.emplace_back(entry.nameRef, &attr->name);
+
+                    if (entry.attr) {
+                        std::unique_ptr<Item> value = ResourceParser::parseItemForAttribute(
+                                entry.xmlAttr->value, *entry.attr, mResolver->getDefaultPackage());
+                        if (value) {
+                            AttributeValueFlattener flattener;
+                            value->accept(flattener, AttributeValueFlattener::Args{
+                                    mResolver,
+                                    logger,
+                                    attr->typedValue,
+                                    parser,
+                                    error,
+                                    rawValueRef,
+                                    stringRefs
+                            });
+                        } else if (!(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;
+                            stringRefs.emplace_back(rawValueRef,
+                                    reinterpret_cast<android::ResStringPool_ref*>(
+                                            &attr->typedValue.data));
+                        }
+                    } else {
+                        attr->typedValue.dataType = android::Res_value::TYPE_STRING;
+                        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 {
+        return a.context.priority < b.context.priority;
+    });
+
+    // Now we flatten the string pool references into the correct places.
+    for (const auto& refEntry : stringRefs) {
+        refEntry.second->index = refEntry.first.getIndex();
+    }
+
+    // Write the XML header.
+    const size_t beforeXmlTreeIndex = outBuffer->size();
+    android::ResXMLTree_header* header = outBuffer->nextBlock<android::ResXMLTree_header>();
+    header->header.type = android::RES_XML_TYPE;
+    header->header.headerSize = sizeof(*header);
+
+    // 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) {
+        ResourceId id { str->context.priority };
+        if (!id.isValid()) {
+            // When we see the first non-resource ID,
+            // we're done.
+            break;
+        }
+
+        uint32_t* flatId = outBuffer->nextBlock<uint32_t>();
+        *flatId = id.id;
+    }
+    resIdMapChunk->size = outBuffer->size() - beforeResIdMapIndex;
+
+    // Flatten the StringPool.
+    StringPool::flattenUtf8(outBuffer, pool);
+
+    // Move the temporary BigBuffer into outBuffer->
+    outBuffer->appendBuffer(std::move(out));
+
+    header->header.size = outBuffer->size() - beforeXmlTreeIndex;
+
+    if (smallestStrippedAttributeSdk == std::numeric_limits<size_t>::max()) {
+        // Nothing was stripped
+        return 0u;
+    }
+    return smallestStrippedAttributeSdk;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XmlFlattener.h b/tools/aapt2/XmlFlattener.h
new file mode 100644
index 0000000..abf64ab
--- /dev/null
+++ b/tools/aapt2/XmlFlattener.h
@@ -0,0 +1,68 @@
+/*
+ * 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_FLATTENER_H
+#define AAPT_XML_FLATTENER_H
+
+#include "BigBuffer.h"
+#include "Maybe.h"
+#include "Resolver.h"
+#include "Source.h"
+#include "XmlPullParser.h"
+
+namespace aapt {
+
+/**
+ * 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.
+ */
+class XmlFlattener {
+public:
+    struct Options {
+        /**
+         * If set, tells the XmlFlattener to strip out
+         * attributes that have been introduced after
+         * max SDK.
+         */
+        Maybe<size_t> maxSdkAttribute;
+    };
+
+    /**
+     * Creates a flattener with a Resolver to resolve references
+     * and attributes.
+     */
+    XmlFlattener(const std::shared_ptr<Resolver>& 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<Resolver> mResolver;
+};
+
+} // namespace aapt
+
+#endif // AAPT_XML_FLATTENER_H
diff --git a/tools/aapt2/XmlFlattener_test.cpp b/tools/aapt2/XmlFlattener_test.cpp
new file mode 100644
index 0000000..79030be
--- /dev/null
+++ b/tools/aapt2/XmlFlattener_test.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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 "Resolver.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "SourceXmlPullParser.h"
+#include "Util.h"
+#include "XmlFlattener.h"
+
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <gtest/gtest.h>
+#include <sstream>
+#include <string>
+
+namespace aapt {
+
+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<ResourceTable> table = std::make_shared<ResourceTable>();
+        table->setPackage(u"android");
+        table->setPackageId(0x01);
+
+        table->addResource(ResourceName{ {}, ResourceType::kAttr, u"id" },
+                           ResourceId{ 0x01010000 }, {}, {},
+                           util::make_unique<Attribute>(false, android::ResTable_map::TYPE_ANY));
+
+        table->addResource(ResourceName{ {}, ResourceType::kId, u"test" },
+                           ResourceId{ 0x01020000 }, {}, {}, util::make_unique<Id>());
+
+        mFlattener = std::make_shared<XmlFlattener>(
+                std::make_shared<Resolver>(table, std::make_shared<android::AssetManager>()));
+    }
+
+    ::testing::AssertionResult testFlatten(std::istream& in, android::ResXMLTree* outTree) {
+        std::stringstream input(kXmlPreamble);
+        input << in.rdbuf() << std::endl;
+        std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<SourceXmlPullParser>(input);
+        BigBuffer outBuffer(1024);
+        if (!mFlattener->flatten(Source{ "test" }, xmlParser, &outBuffer, {})) {
+            return ::testing::AssertionFailure();
+        }
+
+        std::unique_ptr<uint8_t[]> data = util::copy(outBuffer);
+        if (outTree->setTo(data.get(), outBuffer.size(), true) != android::NO_ERROR) {
+            return ::testing::AssertionFailure();
+        }
+        return ::testing::AssertionSuccess();
+    }
+
+    std::shared_ptr<XmlFlattener> mFlattener;
+};
+
+TEST_F(XmlFlattenerTest, ParseSimpleView) {
+    std::stringstream input;
+    input << "<View xmlns:android=\"http://schemas.android.com/apk/res/android\"" << std::endl
+          << "      android:id=\"@id/test\">" << std::endl
+          << "</View>" << std::endl;
+
+    android::ResXMLTree tree;
+    ASSERT_TRUE(testFlatten(input, &tree));
+
+    while (tree.next() != android::ResXMLTree::END_DOCUMENT) {
+        ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT);
+    }
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/XmlPullParser.h b/tools/aapt2/XmlPullParser.h
new file mode 100644
index 0000000..c667df2
--- /dev/null
+++ b/tools/aapt2/XmlPullParser.h
@@ -0,0 +1,234 @@
+/*
+ * 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_PULL_PARSER_H
+#define AAPT_XML_PULL_PARSER_H
+
+#include <algorithm>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "StringPiece.h"
+
+namespace aapt {
+
+class XmlPullParser {
+public:
+    enum class Event {
+        kBadDocument,
+        kStartDocument,
+        kEndDocument,
+
+        kStartNamespace,
+        kEndNamespace,
+        kStartElement,
+        kEndElement,
+        kText,
+        kComment,
+    };
+
+    static void skipCurrentElement(XmlPullParser* parser);
+    static bool isGoodEvent(Event event);
+
+    virtual ~XmlPullParser() {}
+
+    /**
+     * Returns the current event that is being processed.
+     */
+    virtual Event getEvent() const = 0;
+
+    virtual const std::string& getLastError() const = 0;
+
+    /**
+     * Note, unlike XmlPullParser, the first call to next() will return
+     * StartElement of the first element.
+     */
+    virtual Event next() = 0;
+
+    //
+    // These are available for all nodes.
+    //
+
+    virtual const std::u16string& getComment() const = 0;
+    virtual size_t getLineNumber() const = 0;
+    virtual size_t getDepth() const = 0;
+
+    /**
+     * Returns the character data for a Text event.
+     */
+    virtual const std::u16string& getText() const = 0;
+
+    /**
+     * Namespace prefix is available for StartNamespace and EndNamespace.
+     */
+    virtual const std::u16string& getNamespacePrefix() const = 0;
+
+    /**
+     * Namespace URI is available for StartNamespace.
+     */
+    virtual const std::u16string& getNamespaceUri() const = 0;
+
+    //
+    // These are available for StartElement and EndElement.
+    //
+
+    virtual const std::u16string& getElementNamespace() const = 0;
+    virtual const std::u16string& getElementName() const = 0;
+
+    //
+    // Remaining methods are for retrieving information about attributes
+    // associated with a StartElement.
+    //
+    // Attributes must be in sorted order (according to the less than operator
+    // of struct Attribute).
+    //
+
+    struct Attribute {
+        std::u16string namespaceUri;
+        std::u16string name;
+        std::u16string value;
+
+        int compare(const Attribute& rhs) const;
+        bool operator<(const Attribute& rhs) const;
+        bool operator==(const Attribute& rhs) const;
+        bool operator!=(const Attribute& rhs) const;
+    };
+
+    using const_iterator = std::vector<Attribute>::const_iterator;
+
+    virtual const_iterator beginAttributes() const = 0;
+    virtual const_iterator endAttributes() const = 0;
+    virtual size_t getAttributeCount() const = 0;
+    const_iterator findAttribute(StringPiece16 namespaceUri, StringPiece16 name) const;
+};
+
+/*
+ * Automatically reads up to the end tag of the element it was initialized with
+ * when being destroyed.
+ */
+class AutoFinishElement {
+public:
+    AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser);
+    ~AutoFinishElement();
+
+private:
+    std::shared_ptr<XmlPullParser> mParser;
+    int mDepth;
+};
+
+//
+// Implementation
+//
+
+inline ::std::ostream& operator<<(::std::ostream& out, XmlPullParser::Event event) {
+    switch (event) {
+        case XmlPullParser::Event::kBadDocument: return out << "BadDocument";
+        case XmlPullParser::Event::kStartDocument: return out << "StartDocument";
+        case XmlPullParser::Event::kEndDocument: return out << "EndDocument";
+        case XmlPullParser::Event::kStartNamespace: return out << "StartNamespace";
+        case XmlPullParser::Event::kEndNamespace: return out << "EndNamespace";
+        case XmlPullParser::Event::kStartElement: return out << "StartElement";
+        case XmlPullParser::Event::kEndElement: return out << "EndElement";
+        case XmlPullParser::Event::kText: return out << "Text";
+        case XmlPullParser::Event::kComment: return out << "Comment";
+    }
+    return out;
+}
+
+inline void XmlPullParser::skipCurrentElement(XmlPullParser* parser) {
+    int depth = 1;
+    while (depth > 0) {
+        switch (parser->next()) {
+            case Event::kEndDocument:
+            case Event::kBadDocument:
+                return;
+            case Event::kStartElement:
+                depth++;
+                break;
+            case Event::kEndElement:
+                depth--;
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+inline bool XmlPullParser::isGoodEvent(XmlPullParser::Event event) {
+    return event != Event::kBadDocument && event != Event::kEndDocument;
+}
+
+inline int XmlPullParser::Attribute::compare(const Attribute& rhs) const {
+    int cmp = namespaceUri.compare(rhs.namespaceUri);
+    if (cmp != 0) return cmp;
+    return name.compare(rhs.name);
+}
+
+inline bool XmlPullParser::Attribute::operator<(const Attribute& rhs) const {
+    return compare(rhs) < 0;
+}
+
+inline bool XmlPullParser::Attribute::operator==(const Attribute& rhs) const {
+    return compare(rhs) == 0;
+}
+
+inline bool XmlPullParser::Attribute::operator!=(const Attribute& rhs) const {
+    return compare(rhs) != 0;
+}
+
+inline XmlPullParser::const_iterator XmlPullParser::findAttribute(StringPiece16 namespaceUri,
+                                                                  StringPiece16 name) const {
+    const auto endIter = endAttributes();
+    const auto iter = std::lower_bound(beginAttributes(), endIter,
+            std::pair<StringPiece16, StringPiece16>(namespaceUri, name),
+            [](const Attribute& attr, const std::pair<StringPiece16, StringPiece16>& rhs) -> bool {
+                int cmp = attr.namespaceUri.compare(0, attr.namespaceUri.size(),
+                        rhs.first.data(), rhs.first.size());
+                if (cmp < 0) return true;
+                if (cmp > 0) return false;
+                cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(), rhs.second.size());
+                if (cmp < 0) return true;
+                return false;
+            }
+    );
+
+    if (iter != endIter && namespaceUri == iter->namespaceUri && name == iter->name) {
+        return iter;
+    }
+    return endIter;
+}
+
+inline AutoFinishElement::AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser) :
+        mParser(parser), mDepth(parser->getDepth()) {
+}
+
+inline AutoFinishElement::~AutoFinishElement() {
+    int depth;
+    XmlPullParser::Event event;
+    while ((depth = mParser->getDepth()) >= mDepth &&
+            XmlPullParser::isGoodEvent(event = mParser->getEvent())) {
+        if (depth == mDepth && (event == XmlPullParser::Event::kEndElement ||
+                event == XmlPullParser::Event::kEndNamespace)) {
+            return;
+        }
+        mParser->next();
+    }
+}
+
+} // namespace aapt
+
+#endif // AAPT_XML_PULL_PARSER_H
diff --git a/tools/aapt2/data/AndroidManifest.xml b/tools/aapt2/data/AndroidManifest.xml
new file mode 100644
index 0000000..c017a0d
--- /dev/null
+++ b/tools/aapt2/data/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.app">
+    <application>
+    </application>
+</manifest>
diff --git a/tools/aapt2/data/res/drawable/image.xml b/tools/aapt2/data/res/drawable/image.xml
new file mode 100644
index 0000000..9b38739
--- /dev/null
+++ b/tools/aapt2/data/res/drawable/image.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector />
diff --git a/tools/aapt2/data/res/layout/main.xml b/tools/aapt2/data/res/layout/main.xml
new file mode 100644
index 0000000..e0b55c0
--- /dev/null
+++ b/tools/aapt2/data/res/layout/main.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/view"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+    <View xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:id="@+id/me"
+        android:layout_width="1dp"
+        android:layout_height="match_parent"
+        app:layout_width="false"
+        app:flags="complex|weak"
+        android:colorAccent="#ffffff"/>
+</LinearLayout>
diff --git a/tools/aapt2/data/res/values-v4/styles.xml b/tools/aapt2/data/res/values-v4/styles.xml
new file mode 100644
index 0000000..979a82a
--- /dev/null
+++ b/tools/aapt2/data/res/values-v4/styles.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="App" parent="android:Theme.Material">
+        <item name="android:colorAccent">@color/accent</item>
+        <item name="android:text">Hey</item>
+    </style>
+</resources>
diff --git a/tools/aapt2/data/res/values/colors.xml b/tools/aapt2/data/res/values/colors.xml
new file mode 100644
index 0000000..89db5fb
--- /dev/null
+++ b/tools/aapt2/data/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="primary">#f44336</color>
+    <color name="primary_dark">#b71c1c</color>
+    <color name="accent">#fdd835</color>
+</resources>
diff --git a/tools/aapt2/data/res/values/styles.xml b/tools/aapt2/data/res/values/styles.xml
new file mode 100644
index 0000000..71ce388
--- /dev/null
+++ b/tools/aapt2/data/res/values/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="App" parent="android:Theme.Material">
+        <item name="android:background">@color/primary</item>
+        <item name="android:colorPrimary">@color/primary</item>
+        <item name="android:colorPrimaryDark">@color/primary_dark</item>
+        <item name="android:colorAccent">@color/accent</item>
+    </style>
+    <attr name="custom" format="reference" />
+    <style name="Pop">
+        <item name="custom">@drawable/image</item>
+    </style>
+    <string name="yo">@string/wow</string>
+
+    <declare-styleable name="View">
+        <attr name="custom" />
+        <attr name="decor">
+            <enum name="no-border" value="0"/>
+            <enum name="border" value="1"/>
+            <enum name="shadow" value="2"/>
+        </attr>
+    </declare-styleable>
+
+</resources>
diff --git a/tools/aapt2/data/res/values/test.xml b/tools/aapt2/data/res/values/test.xml
new file mode 100644
index 0000000..d3ead34
--- /dev/null
+++ b/tools/aapt2/data/res/values/test.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hooha"><font bgcolor="#ffffff">Hey guys!</font> <xliff:g>My</xliff:g> name is <b>Adam</b>. How <b><i>are</i></b> you?</string>
+    <public name="hooha" type="string" id="0x7f020001"/>
+    <string name="wow">@android:string/ok</string>
+    <public name="image" type="drawable" id="0x7f060000" />
+    <attr name="layout_width" format="boolean" />
+    <attr name="flags">
+        <flag name="complex" value="1" />
+        <flag name="pub" value="2" />
+        <flag name="weak" value="4" />
+    </attr>
+</resources>
diff --git a/tools/aapt2/data/resources.arsc b/tools/aapt2/data/resources.arsc
new file mode 100644
index 0000000..6a416df
--- /dev/null
+++ b/tools/aapt2/data/resources.arsc
Binary files differ
diff --git a/tools/aapt2/data/resources_base.arsc b/tools/aapt2/data/resources_base.arsc
new file mode 100644
index 0000000..f9d0610
--- /dev/null
+++ b/tools/aapt2/data/resources_base.arsc
Binary files differ
diff --git a/tools/aapt2/data/resources_hdpi.arsc b/tools/aapt2/data/resources_hdpi.arsc
new file mode 100644
index 0000000..97232a3
--- /dev/null
+++ b/tools/aapt2/data/resources_hdpi.arsc
Binary files differ
diff --git a/tools/aapt2/process.dot b/tools/aapt2/process.dot
new file mode 100644
index 0000000..a92405d
--- /dev/null
+++ b/tools/aapt2/process.dot
@@ -0,0 +1,92 @@
+digraph aapt {
+    out_package [label="out/default/package.apk"];
+    out_fr_package [label="out/fr/package.apk"];
+    out_table_aligned [label="out/default/resources-aligned.arsc"];
+    out_table_fr_aligned [label="out/fr/resources-aligned.arsc"];
+    out_res_layout_main_xml [label="out/res/layout/main.xml"];
+    out_res_layout_v21_main_xml [color=red,label="out/res/layout-v21/main.xml"];
+    out_res_layout_fr_main_xml [label="out/res/layout-fr/main.xml"];
+    out_res_layout_fr_v21_main_xml [color=red,label="out/res/layout-fr-v21/main.xml"];
+    out_table [label="out/default/resources.arsc"];
+    out_fr_table [label="out/fr/resources.arsc"];
+    out_values_table [label="out/values/resources.arsc"];
+    out_layout_table [label="out/layout/resources.arsc"];
+    out_values_fr_table [label="out/values-fr/resources.arsc"];
+    out_layout_fr_table [label="out/layout-fr/resources.arsc"];
+    res_values_strings_xml [label="res/values/strings.xml"];
+    res_values_attrs_xml [label="res/values/attrs.xml"];
+    res_layout_main_xml [label="res/layout/main.xml"];
+    res_layout_fr_main_xml [label="res/layout-fr/main.xml"];
+    res_values_fr_strings_xml [label="res/values-fr/strings.xml"];
+
+    out_package -> package_default;
+    out_fr_package -> package_fr;
+
+    package_default [shape=box,label="Assemble",color=blue];
+    package_default -> out_table_aligned;
+    package_default -> out_res_layout_main_xml;
+    package_default -> out_res_layout_v21_main_xml [color=red];
+
+    package_fr [shape=box,label="Assemble",color=blue];
+    package_fr -> out_table_fr_aligned;
+    package_fr -> out_res_layout_fr_main_xml;
+    package_fr -> out_res_layout_fr_v21_main_xml [color=red];
+
+    out_table_aligned -> align_tables;
+    out_table_fr_aligned -> align_tables;
+
+    align_tables [shape=box,label="Align",color=blue];
+    align_tables -> out_table;
+    align_tables -> out_fr_table;
+
+    out_table -> link_tables;
+
+    link_tables [shape=box,label="Link",color=blue];
+    link_tables -> out_values_table;
+    link_tables -> out_layout_table;
+
+    out_values_table -> compile_values;
+
+    compile_values [shape=box,label="Collect",color=blue];
+    compile_values -> res_values_strings_xml;
+    compile_values -> res_values_attrs_xml;
+
+    out_layout_table -> collect_xml;
+
+    collect_xml [shape=box,label="Collect",color=blue];
+    collect_xml -> res_layout_main_xml;
+
+    out_fr_table -> link_fr_tables;
+
+    link_fr_tables [shape=box,label="Link",color=blue];
+    link_fr_tables -> out_values_fr_table;
+    link_fr_tables -> out_layout_fr_table;
+
+    out_values_fr_table -> compile_values_fr;
+
+    compile_values_fr [shape=box,label="Compile",color=blue];
+    compile_values_fr -> res_values_fr_strings_xml;
+
+    out_layout_fr_table -> collect_xml_fr;
+
+    collect_xml_fr [shape=box,label="Collect",color=blue];
+    collect_xml_fr -> res_layout_fr_main_xml;
+
+    compile_res_layout_main_xml [shape=box,label="Compile",color=blue];
+
+    out_res_layout_main_xml -> compile_res_layout_main_xml;
+
+    out_res_layout_v21_main_xml -> compile_res_layout_main_xml [color=red];
+
+    compile_res_layout_main_xml -> res_layout_main_xml;
+    compile_res_layout_main_xml -> out_table_aligned;
+
+    compile_res_layout_fr_main_xml [shape=box,label="Compile",color=blue];
+
+    out_res_layout_fr_main_xml -> compile_res_layout_fr_main_xml;
+
+    out_res_layout_fr_v21_main_xml -> compile_res_layout_fr_main_xml [color=red];
+
+    compile_res_layout_fr_main_xml -> res_layout_fr_main_xml;
+    compile_res_layout_fr_main_xml -> out_table_fr_aligned;
+}
diff --git a/tools/aapt2/public_attr_map.py b/tools/aapt2/public_attr_map.py
new file mode 100644
index 0000000..92136a8
--- /dev/null
+++ b/tools/aapt2/public_attr_map.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+import sys
+import xml.etree.ElementTree as ET
+
+def findSdkLevelForAttribute(id):
+    intId = int(id, 16)
+    packageId = 0x000000ff & (intId >> 24)
+    typeId = 0x000000ff & (intId >> 16)
+    entryId = 0x0000ffff & intId
+
+    if packageId != 0x01 or typeId != 0x01:
+        return 0
+
+    levels = [(1, 0x021c), (2, 0x021d), (3, 0x0269), (4, 0x028d),
+              (5, 0x02ad), (6, 0x02b3), (7, 0x02b5), (8, 0x02bd),
+              (9, 0x02cb), (11, 0x0361), (12, 0x0366), (13, 0x03a6),
+              (16, 0x03ae), (17, 0x03cc), (18, 0x03da), (19, 0x03f1),
+              (20, 0x03f6), (21, 0x04ce)]
+    for level, attrEntryId in levels:
+        if entryId <= attrEntryId:
+            return level
+    return 22
+
+
+tree = None
+with open(sys.argv[1], 'rt') as f:
+    tree = ET.parse(f)
+
+attrs = []
+for node in tree.iter('public'):
+    if node.get('type') == 'attr':
+        sdkLevel = findSdkLevelForAttribute(node.get('id', '0'))
+        if sdkLevel > 1 and sdkLevel < 22:
+            attrs.append("{{ u\"{}\", {} }}".format(node.get('name'), sdkLevel))
+
+print "#include <string>"
+print "#include <unordered_map>"
+print
+print "namespace aapt {"
+print
+print "static std::unordered_map<std::u16string, size_t> sAttrMap = {"
+print ",\n    ".join(attrs)
+print "};"
+print
+print "size_t findAttributeSdkLevel(const std::u16string& name) {"
+print "    auto iter = sAttrMap.find(name);"
+print "    if (iter != sAttrMap.end()) {"
+print "        return iter->second;"
+print "    }"
+print "    return 0;"
+print "}"
+print
+print "} // namespace aapt"
+print
diff --git a/tools/aapt2/todo.txt b/tools/aapt2/todo.txt
new file mode 100644
index 0000000..acc8bfb
--- /dev/null
+++ b/tools/aapt2/todo.txt
@@ -0,0 +1,29 @@
+XML Files
+X Collect declared IDs
+X Build StringPool
+X Flatten
+
+Resource Table Operations
+X Build Resource Table (with StringPool) from XML.
+X Modify Resource Table.
+X - Copy and transform resources.
+X   - Pre-17/21 attr correction.
+X Perform analysis of types.
+X Flatten.
+X Assign resource IDs.
+X Assign public resource IDs.
+X Merge resource tables
+- Assign private attributes to different typespace.
+- Align resource tables
+
+Splits
+- Collect all resources (ids from layouts).
+- Generate resource table from base resources.
+- Generate resource table from individual resources of the required type.
+- Align resource tables (same type/name = same ID).
+
+Fat Apk
+X Collect all resources (ids from layouts).
+X Generate resource tables for all configurations.
+- Align individual resource tables.
+- Merge resource tables.
