//
// Copyright 2006 The Android Open Source Project
//
// Build resource files from raw assets.
//
#include "AaptAssets.h"
#include "AaptUtil.h"
#include "AaptXml.h"
#include "CacheUpdater.h"
#include "CrunchCache.h"
#include "FileFinder.h"
#include "Images.h"
#include "IndentPrinter.h"
#include "Main.h"
#include "ResourceTable.h"
#include "StringPool.h"
#include "Symbol.h"
#include "WorkQueue.h"
#include "XMLNode.h"

#include <algorithm>

// STATUST: mingw does seem to redefine UNKNOWN_ERROR from our enum value, so a cast is necessary.

#if !defined(_WIN32)
#  define ZD "%zd"
#  define ZD_TYPE ssize_t
#  define STATUST(x) x
#else
#  define ZD "%ld"
#  define ZD_TYPE long
#  define STATUST(x) (status_t)x
#endif

// Set to true for noisy debug output.
static const bool kIsDebug = false;

// Number of threads to use for preprocessing images.
static const size_t MAX_THREADS = 4;

// ==========================================================================
// ==========================================================================
// ==========================================================================

class PackageInfo
{
public:
    PackageInfo()
    {
    }
    ~PackageInfo()
    {
    }

    status_t parsePackage(const sp<AaptGroup>& grp);
};

// ==========================================================================
// ==========================================================================
// ==========================================================================

String8 parseResourceName(const String8& leaf)
{
    const char* firstDot = strchr(leaf.string(), '.');
    const char* str = leaf.string();

    if (firstDot) {
        return String8(str, firstDot-str);
    } else {
        return String8(str);
    }
}

ResourceTypeSet::ResourceTypeSet()
    :RefBase(),
     KeyedVector<String8,sp<AaptGroup> >()
{
}

FilePathStore::FilePathStore()
    :RefBase(),
     Vector<String8>()
{
}

class ResourceDirIterator
{
public:
    ResourceDirIterator(const sp<ResourceTypeSet>& set, const String8& resType)
        : mResType(resType), mSet(set), mSetPos(0), mGroupPos(0)
    {
        memset(&mParams, 0, sizeof(ResTable_config));
    }

    inline const sp<AaptGroup>& getGroup() const { return mGroup; }
    inline const sp<AaptFile>& getFile() const { return mFile; }

    inline const String8& getBaseName() const { return mBaseName; }
    inline const String8& getLeafName() const { return mLeafName; }
    inline String8 getPath() const { return mPath; }
    inline const ResTable_config& getParams() const { return mParams; }

    enum {
        EOD = 1
    };

    ssize_t next()
    {
        while (true) {
            sp<AaptGroup> group;
            sp<AaptFile> file;

            // Try to get next file in this current group.
            if (mGroup != NULL && mGroupPos < mGroup->getFiles().size()) {
                group = mGroup;
                file = group->getFiles().valueAt(mGroupPos++);

            // Try to get the next group/file in this directory
            } else if (mSetPos < mSet->size()) {
                mGroup = group = mSet->valueAt(mSetPos++);
                if (group->getFiles().size() < 1) {
                    continue;
                }
                file = group->getFiles().valueAt(0);
                mGroupPos = 1;

            // All done!
            } else {
                return EOD;
            }

            mFile = file;

            String8 leaf(group->getLeaf());
            mLeafName = String8(leaf);
            mParams = file->getGroupEntry().toParams();
            if (kIsDebug) {
                printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n",
                        group->getPath().string(), mParams.mcc, mParams.mnc,
                        mParams.language[0] ? mParams.language[0] : '-',
                        mParams.language[1] ? mParams.language[1] : '-',
                        mParams.country[0] ? mParams.country[0] : '-',
                        mParams.country[1] ? mParams.country[1] : '-',
                        mParams.orientation, mParams.uiMode,
                        mParams.density, mParams.touchscreen, mParams.keyboard,
                        mParams.inputFlags, mParams.navigation);
            }
            mPath = "res";
            mPath.appendPath(file->getGroupEntry().toDirName(mResType));
            mPath.appendPath(leaf);
            mBaseName = parseResourceName(leaf);
            if (mBaseName == "") {
                fprintf(stderr, "Error: malformed resource filename %s\n",
                        file->getPrintableSource().string());
                return UNKNOWN_ERROR;
            }

            if (kIsDebug) {
                printf("file name=%s\n", mBaseName.string());
            }

            return NO_ERROR;
        }
    }

private:
    String8 mResType;

    const sp<ResourceTypeSet> mSet;
    size_t mSetPos;

    sp<AaptGroup> mGroup;
    size_t mGroupPos;

    sp<AaptFile> mFile;
    String8 mBaseName;
    String8 mLeafName;
    String8 mPath;
    ResTable_config mParams;
};

class AnnotationProcessor {
public:
    AnnotationProcessor() : mDeprecated(false), mSystemApi(false) { }

    void preprocessComment(String8& comment) {
        if (comment.size() > 0) {
            if (comment.contains("@deprecated")) {
                mDeprecated = true;
            }
            if (comment.removeAll("@SystemApi")) {
                mSystemApi = true;
            }
        }
    }

    void printAnnotations(FILE* fp, const char* indentStr) {
        if (mDeprecated) {
            fprintf(fp, "%s@Deprecated\n", indentStr);
        }
        if (mSystemApi) {
            fprintf(fp, "%s@android.annotation.SystemApi\n", indentStr);
        }
    }

private:
    bool mDeprecated;
    bool mSystemApi;
};

// ==========================================================================
// ==========================================================================
// ==========================================================================

bool isValidResourceType(const String8& type)
{
    return type == "anim" || type == "animator" || type == "interpolator"
        || type == "transition"
        || type == "drawable" || type == "layout"
        || type == "values" || type == "xml" || type == "raw"
        || type == "color" || type == "menu" || type == "mipmap";
}

static status_t parsePackage(Bundle* bundle, const sp<AaptAssets>& assets,
    const sp<AaptGroup>& grp)
{
    if (grp->getFiles().size() != 1) {
        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
                grp->getFiles().valueAt(0)->getPrintableSource().string());
    }

    sp<AaptFile> file = grp->getFiles().valueAt(0);

    ResXMLTree block;
    status_t err = parseXMLResource(file, &block);
    if (err != NO_ERROR) {
        return err;
    }
    //printXMLBlock(&block);

    ResXMLTree::event_code_t code;
    while ((code=block.next()) != ResXMLTree::START_TAG
           && code != ResXMLTree::END_DOCUMENT
           && code != ResXMLTree::BAD_DOCUMENT) {
    }

    size_t len;
    if (code != ResXMLTree::START_TAG) {
        fprintf(stderr, "%s:%d: No start tag found\n",
                file->getPrintableSource().string(), block.getLineNumber());
        return UNKNOWN_ERROR;
    }
    if (strcmp16(block.getElementName(&len), String16("manifest").string()) != 0) {
        fprintf(stderr, "%s:%d: Invalid start tag %s, expected <manifest>\n",
                file->getPrintableSource().string(), block.getLineNumber(),
                String8(block.getElementName(&len)).string());
        return UNKNOWN_ERROR;
    }

    ssize_t nameIndex = block.indexOfAttribute(NULL, "package");
    if (nameIndex < 0) {
        fprintf(stderr, "%s:%d: <manifest> does not have package attribute.\n",
                file->getPrintableSource().string(), block.getLineNumber());
        return UNKNOWN_ERROR;
    }

    assets->setPackage(String8(block.getAttributeStringValue(nameIndex, &len)));

    ssize_t revisionCodeIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "revisionCode");
    if (revisionCodeIndex >= 0) {
        bundle->setRevisionCode(String8(block.getAttributeStringValue(revisionCodeIndex, &len)).string());
    }

    String16 uses_sdk16("uses-sdk");
    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
           && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            if (strcmp16(block.getElementName(&len), uses_sdk16.string()) == 0) {
                ssize_t minSdkIndex = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE,
                                                             "minSdkVersion");
                if (minSdkIndex >= 0) {
                    const char16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
                    const char* minSdk8 = strdup(String8(minSdk16).string());
                    bundle->setManifestMinSdkVersion(minSdk8);
                }
            }
        }
    }

    return NO_ERROR;
}

// ==========================================================================
// ==========================================================================
// ==========================================================================

static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,
                                  ResourceTable* table,
                                  const sp<ResourceTypeSet>& set,
                                  const char* resType)
{
    String8 type8(resType);
    String16 type16(resType);

    bool hasErrors = false;

    ResourceDirIterator it(set, String8(resType));
    ssize_t res;
    while ((res=it.next()) == NO_ERROR) {
        if (bundle->getVerbose()) {
            printf("    (new resource id %s from %s)\n",
                   it.getBaseName().string(), it.getFile()->getPrintableSource().string());
        }
        String16 baseName(it.getBaseName());
        const char16_t* str = baseName.string();
        const char16_t* const end = str + baseName.size();
        while (str < end) {
            if (!((*str >= 'a' && *str <= 'z')
                    || (*str >= '0' && *str <= '9')
                    || *str == '_' || *str == '.')) {
                fprintf(stderr, "%s: Invalid file name: must contain only [a-z0-9_.]\n",
                        it.getPath().string());
                hasErrors = true;
            }
            str++;
        }
        String8 resPath = it.getPath();
        resPath.convertToResPath();
        table->addEntry(SourcePos(it.getPath(), 0), String16(assets->getPackage()),
                        type16,
                        baseName,
                        String16(resPath),
                        NULL,
                        &it.getParams());
        assets->addResource(it.getLeafName(), resPath, it.getFile(), type8);
    }

    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}

class PreProcessImageWorkUnit : public WorkQueue::WorkUnit {
public:
    PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,
            const sp<AaptFile>& file, volatile bool* hasErrors) :
            mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {
    }

    virtual bool run() {
        status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);
        if (status) {
            *mHasErrors = true;
        }
        return true; // continue even if there are errors
    }

private:
    const Bundle* mBundle;
    sp<AaptAssets> mAssets;
    sp<AaptFile> mFile;
    volatile bool* mHasErrors;
};

static status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,
                          const sp<ResourceTypeSet>& set, const char* type)
{
    volatile bool hasErrors = false;
    ssize_t res = NO_ERROR;
    if (bundle->getUseCrunchCache() == false) {
        WorkQueue wq(MAX_THREADS, false);
        ResourceDirIterator it(set, String8(type));
        while ((res=it.next()) == NO_ERROR) {
            PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(
                    bundle, assets, it.getFile(), &hasErrors);
            status_t status = wq.schedule(w);
            if (status) {
                fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status);
                hasErrors = true;
                delete w;
                break;
            }
        }
        status_t status = wq.finish();
        if (status) {
            fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status);
            hasErrors = true;
        }
    }
    return (hasErrors || (res < NO_ERROR)) ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}

static void collect_files(const sp<AaptDir>& dir,
        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
{
    const DefaultKeyedVector<String8, sp<AaptGroup> >& groups = dir->getFiles();
    int N = groups.size();
    for (int i=0; i<N; i++) {
        String8 leafName = groups.keyAt(i);
        const sp<AaptGroup>& group = groups.valueAt(i);

        const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files
                = group->getFiles();

        if (files.size() == 0) {
            continue;
        }

        String8 resType = files.valueAt(0)->getResourceType();

        ssize_t index = resources->indexOfKey(resType);

        if (index < 0) {
            sp<ResourceTypeSet> set = new ResourceTypeSet();
            if (kIsDebug) {
                printf("Creating new resource type set for leaf %s with group %s (%p)\n",
                        leafName.string(), group->getPath().string(), group.get());
            }
            set->add(leafName, group);
            resources->add(resType, set);
        } else {
            sp<ResourceTypeSet> set = resources->valueAt(index);
            index = set->indexOfKey(leafName);
            if (index < 0) {
                if (kIsDebug) {
                    printf("Adding to resource type set for leaf %s group %s (%p)\n",
                            leafName.string(), group->getPath().string(), group.get());
                }
                set->add(leafName, group);
            } else {
                sp<AaptGroup> existingGroup = set->valueAt(index);
                if (kIsDebug) {
                    printf("Extending to resource type set for leaf %s group %s (%p)\n",
                            leafName.string(), group->getPath().string(), group.get());
                }
                for (size_t j=0; j<files.size(); j++) {
                    if (kIsDebug) {
                        printf("Adding file %s in group %s resType %s\n",
                                files.valueAt(j)->getSourceFile().string(),
                                files.keyAt(j).toDirName(String8()).string(),
                                resType.string());
                    }
                    existingGroup->addFile(files.valueAt(j));
                }
            }
        }
    }
}

static void collect_files(const sp<AaptAssets>& ass,
        KeyedVector<String8, sp<ResourceTypeSet> >* resources)
{
    const Vector<sp<AaptDir> >& dirs = ass->resDirs();
    int N = dirs.size();

    for (int i=0; i<N; i++) {
        sp<AaptDir> d = dirs.itemAt(i);
        if (kIsDebug) {
            printf("Collecting dir #%d %p: %s, leaf %s\n", i, d.get(), d->getPath().string(),
                    d->getLeaf().string());
        }
        collect_files(d, resources);

        // don't try to include the res dir
        if (kIsDebug) {
            printf("Removing dir leaf %s\n", d->getLeaf().string());
        }
        ass->removeDir(d->getLeaf());
    }
}

enum {
    ATTR_OKAY = -1,
    ATTR_NOT_FOUND = -2,
    ATTR_LEADING_SPACES = -3,
    ATTR_TRAILING_SPACES = -4
};
static int validateAttr(const String8& path, const ResTable& table,
        const ResXMLParser& parser,
        const char* ns, const char* attr, const char* validChars, bool required)
{
    size_t len;

    ssize_t index = parser.indexOfAttribute(ns, attr);
    const char16_t* str;
    Res_value value;
    if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) {
        const ResStringPool* pool = &parser.getStrings();
        if (value.dataType == Res_value::TYPE_REFERENCE) {
            uint32_t specFlags = 0;
            int strIdx;
            if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) {
                fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n",
                        path.string(), parser.getLineNumber(),
                        String8(parser.getElementName(&len)).string(), attr,
                        value.data);
                return ATTR_NOT_FOUND;
            }
            
            pool = table.getTableStringBlock(strIdx);
            #if 0
            if (pool != NULL) {
                str = pool->stringAt(value.data, &len);
            }
            printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr,
                    specFlags, strIdx, str != NULL ? String8(str).string() : "???");
            #endif
            if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) {
                fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n",
                        path.string(), parser.getLineNumber(),
                        String8(parser.getElementName(&len)).string(), attr,
                        specFlags);
                return ATTR_NOT_FOUND;
            }
        }
        if (value.dataType == Res_value::TYPE_STRING) {
            if (pool == NULL) {
                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n",
                        path.string(), parser.getLineNumber(),
                        String8(parser.getElementName(&len)).string(), attr);
                return ATTR_NOT_FOUND;
            }
            if ((str=pool->stringAt(value.data, &len)) == NULL) {
                fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n",
                        path.string(), parser.getLineNumber(),
                        String8(parser.getElementName(&len)).string(), attr);
                return ATTR_NOT_FOUND;
            }
        } else {
            fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n",
                    path.string(), parser.getLineNumber(),
                    String8(parser.getElementName(&len)).string(), attr,
                    value.dataType);
            return ATTR_NOT_FOUND;
        }
        if (validChars) {
            for (size_t i=0; i<len; i++) {
                char16_t c = str[i];
                const char* p = validChars;
                bool okay = false;
                while (*p) {
                    if (c == *p) {
                        okay = true;
                        break;
                    }
                    p++;
                }
                if (!okay) {
                    fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid character '%c'.\n",
                            path.string(), parser.getLineNumber(),
                            String8(parser.getElementName(&len)).string(), attr, (char)str[i]);
                    return (int)i;
                }
            }
        }
        if (*str == ' ') {
            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not start with a space.\n",
                    path.string(), parser.getLineNumber(),
                    String8(parser.getElementName(&len)).string(), attr);
            return ATTR_LEADING_SPACES;
        }
        if (len != 0 && str[len-1] == ' ') {
            fprintf(stderr, "%s:%d: Tag <%s> attribute %s can not end with a space.\n",
                    path.string(), parser.getLineNumber(),
                    String8(parser.getElementName(&len)).string(), attr);
            return ATTR_TRAILING_SPACES;
        }
        return ATTR_OKAY;
    }
    if (required) {
        fprintf(stderr, "%s:%d: Tag <%s> missing required attribute %s.\n",
                path.string(), parser.getLineNumber(),
                String8(parser.getElementName(&len)).string(), attr);
        return ATTR_NOT_FOUND;
    }
    return ATTR_OKAY;
}

static void checkForIds(const String8& path, ResXMLParser& parser)
{
    ResXMLTree::event_code_t code;
    while ((code=parser.next()) != ResXMLTree::END_DOCUMENT
           && code > ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            ssize_t index = parser.indexOfAttribute(NULL, "id");
            if (index >= 0) {
                fprintf(stderr, "%s:%d: warning: found plain 'id' attribute; did you mean the new 'android:id' name?\n",
                        path.string(), parser.getLineNumber());
            }
        }
    }
}

static bool applyFileOverlay(Bundle *bundle,
                             const sp<AaptAssets>& assets,
                             sp<ResourceTypeSet> *baseSet,
                             const char *resType)
{
    if (bundle->getVerbose()) {
        printf("applyFileOverlay for %s\n", resType);
    }

    // Replace any base level files in this category with any found from the overlay
    // Also add any found only in the overlay.
    sp<AaptAssets> overlay = assets->getOverlay();
    String8 resTypeString(resType);

    // work through the linked list of overlays
    while (overlay.get()) {
        KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();

        // get the overlay resources of the requested type
        ssize_t index = overlayRes->indexOfKey(resTypeString);
        if (index >= 0) {
            sp<ResourceTypeSet> overlaySet = overlayRes->valueAt(index);

            // for each of the resources, check for a match in the previously built
            // non-overlay "baseset".
            size_t overlayCount = overlaySet->size();
            for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
                if (bundle->getVerbose()) {
                    printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string());
                }
                ssize_t baseIndex = -1;
                if (baseSet->get() != NULL) {
                    baseIndex = (*baseSet)->indexOfKey(overlaySet->keyAt(overlayIndex));
                }
                if (baseIndex >= 0) {
                    // look for same flavor.  For a given file (strings.xml, for example)
                    // there may be a locale specific or other flavors - we want to match
                    // the same flavor.
                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
                    sp<AaptGroup> baseGroup = (*baseSet)->valueAt(baseIndex);

                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
                            overlayGroup->getFiles();
                    if (bundle->getVerbose()) {
                        DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
                                baseGroup->getFiles();
                        for (size_t i=0; i < baseFiles.size(); i++) {
                            printf("baseFile " ZD " has flavor %s\n", (ZD_TYPE) i,
                                    baseFiles.keyAt(i).toString().string());
                        }
                        for (size_t i=0; i < overlayFiles.size(); i++) {
                            printf("overlayFile " ZD " has flavor %s\n", (ZD_TYPE) i,
                                    overlayFiles.keyAt(i).toString().string());
                        }
                    }

                    size_t overlayGroupSize = overlayFiles.size();
                    for (size_t overlayGroupIndex = 0;
                            overlayGroupIndex<overlayGroupSize;
                            overlayGroupIndex++) {
                        ssize_t baseFileIndex =
                                baseGroup->getFiles().indexOfKey(overlayFiles.
                                keyAt(overlayGroupIndex));
                        if (baseFileIndex >= 0) {
                            if (bundle->getVerbose()) {
                                printf("found a match (" ZD ") for overlay file %s, for flavor %s\n",
                                        (ZD_TYPE) baseFileIndex,
                                        overlayGroup->getLeaf().string(),
                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
                            }
                            baseGroup->removeFile(baseFileIndex);
                        } else {
                            // didn't find a match fall through and add it..
                            if (true || bundle->getVerbose()) {
                                printf("nothing matches overlay file %s, for flavor %s\n",
                                        overlayGroup->getLeaf().string(),
                                        overlayFiles.keyAt(overlayGroupIndex).toString().string());
                            }
                        }
                        baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
                    }
                } else {
                    if (baseSet->get() == NULL) {
                        *baseSet = new ResourceTypeSet();
                        assets->getResources()->add(String8(resType), *baseSet);
                    }
                    // this group doesn't exist (a file that's only in the overlay)
                    (*baseSet)->add(overlaySet->keyAt(overlayIndex),
                            overlaySet->valueAt(overlayIndex));
                    // make sure all flavors are defined in the resources.
                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
                            overlayGroup->getFiles();
                    size_t overlayGroupSize = overlayFiles.size();
                    for (size_t overlayGroupIndex = 0;
                            overlayGroupIndex<overlayGroupSize;
                            overlayGroupIndex++) {
                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
                    }
                }
            }
            // this overlay didn't have resources for this type
        }
        // try next overlay
        overlay = overlay->getOverlay();
    }
    return true;
}

/*
 * Inserts an attribute in a given node.
 * If errorOnFailedInsert is true, and the attribute already exists, returns false.
 * If replaceExisting is true, the attribute will be updated if it already exists.
 * Returns true otherwise, even if the attribute already exists, and does not modify
 * the existing attribute's value.
 */
bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
        const char* attr8, const char* value, bool errorOnFailedInsert,
        bool replaceExisting)
{
    if (value == NULL) {
        return true;
    }

    const String16 ns(ns8);
    const String16 attr(attr8);

    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);
    if (existingEntry != NULL) {
        if (replaceExisting) {
            if (kIsDebug) {
                printf("Info: AndroidManifest.xml already defines %s (in %s);"
                        " overwriting existing value from manifest.\n",
                        String8(attr).string(), String8(ns).string());
            }
            existingEntry->string = String16(value);
            return true;
        }

        if (errorOnFailedInsert) {
            fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
                            " cannot insert new value %s.\n",
                    String8(attr).string(), String8(ns).string(), value);
            return false;
        }

        fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s);"
                        " using existing value in manifest.\n",
                String8(attr).string(), String8(ns).string());

        // don't stop the build.
        return true;
    }
    
    node->addAttribute(ns, attr, String16(value));
    return true;
}

/*
 * Inserts an attribute in a given node, only if the attribute does not
 * exist.
 * If errorOnFailedInsert is true, and the attribute already exists, returns false.
 * Returns true otherwise, even if the attribute already exists.
 */
bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
        const char* attr8, const char* value, bool errorOnFailedInsert)
{
    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);
}

static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
        const String16& attrName) {
    XMLNode::attribute_entry* attr = node->editAttribute(
            String16("http://schemas.android.com/apk/res/android"), attrName);
    if (attr != NULL) {
        String8 name(attr->string);

        // asdf     --> package.asdf
        // .asdf  .a.b  --> package.asdf package.a.b
        // asdf.adsf --> asdf.asdf
        String8 className;
        const char* p = name.string();
        const char* q = strchr(p, '.');
        if (p == q) {
            className += package;
            className += name;
        } else if (q == NULL) {
            className += package;
            className += ".";
            className += name;
        } else {
            className += name;
        }
        if (kIsDebug) {
            printf("Qualifying class '%s' to '%s'", name.string(), className.string());
        }
        attr->string.setTo(String16(className));
    }
}

status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
{
    root = root->searchElement(String16(), String16("manifest"));
    if (root == NULL) {
        fprintf(stderr, "No <manifest> tag.\n");
        return UNKNOWN_ERROR;
    }

    bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
    bool replaceVersion = bundle->getReplaceVersion();

    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {
        return UNKNOWN_ERROR;
    } else {
        const XMLNode::attribute_entry* attr = root->getAttribute(
                String16(RESOURCES_ANDROID_NAMESPACE), String16("versionCode"));
        if (attr != NULL) {
            bundle->setVersionCode(strdup(String8(attr->string).string()));
        }
    }

    if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {
        return UNKNOWN_ERROR;
    } else {
        const XMLNode::attribute_entry* attr = root->getAttribute(
                String16(RESOURCES_ANDROID_NAMESPACE), String16("versionName"));
        if (attr != NULL) {
            bundle->setVersionName(strdup(String8(attr->string).string()));
        }
    }
    
    sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
    if (bundle->getMinSdkVersion() != NULL
            || bundle->getTargetSdkVersion() != NULL
            || bundle->getMaxSdkVersion() != NULL) {
        if (vers == NULL) {
            vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
            root->insertChildAt(vers, 0);
        }
        
        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
                bundle->getMinSdkVersion(), errorOnFailedInsert)) {
            return UNKNOWN_ERROR;
        }
        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
                bundle->getTargetSdkVersion(), errorOnFailedInsert)) {
            return UNKNOWN_ERROR;
        }
        if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
                bundle->getMaxSdkVersion(), errorOnFailedInsert)) {
            return UNKNOWN_ERROR;
        }
    }

    if (vers != NULL) {
        const XMLNode::attribute_entry* attr = vers->getAttribute(
                String16(RESOURCES_ANDROID_NAMESPACE), String16("minSdkVersion"));
        if (attr != NULL) {
            bundle->setMinSdkVersion(strdup(String8(attr->string).string()));
        }
    }

    if (bundle->getPlatformBuildVersionCode() != "") {
        if (!addTagAttribute(root, "", "platformBuildVersionCode",
                    bundle->getPlatformBuildVersionCode(), errorOnFailedInsert, true)) {
            return UNKNOWN_ERROR;
        }
    }

    if (bundle->getPlatformBuildVersionName() != "") {
        if (!addTagAttribute(root, "", "platformBuildVersionName",
                    bundle->getPlatformBuildVersionName(), errorOnFailedInsert, true)) {
            return UNKNOWN_ERROR;
        }
    }

    if (bundle->getDebugMode()) {
        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
        if (application != NULL) {
            if (!addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true",
                    errorOnFailedInsert)) {
                return UNKNOWN_ERROR;
            }
        }
    }

    // Deal with manifest package name overrides
    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
    if (manifestPackageNameOverride != NULL) {
        // Update the actual package name
        XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package"));
        if (attr == NULL) {
            fprintf(stderr, "package name is required with --rename-manifest-package.\n");
            return UNKNOWN_ERROR;
        }
        String8 origPackage(attr->string);
        attr->string.setTo(String16(manifestPackageNameOverride));
        if (kIsDebug) {
            printf("Overriding package '%s' to be '%s'\n", origPackage.string(),
                    manifestPackageNameOverride);
        }

        // Make class names fully qualified
        sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
        if (application != NULL) {
            fullyQualifyClassName(origPackage, application, String16("name"));
            fullyQualifyClassName(origPackage, application, String16("backupAgent"));

            Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
            for (size_t i = 0; i < children.size(); i++) {
                sp<XMLNode> child = children.editItemAt(i);
                String8 tag(child->getElementName());
                if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
                    fullyQualifyClassName(origPackage, child, String16("name"));
                } else if (tag == "activity-alias") {
                    fullyQualifyClassName(origPackage, child, String16("name"));
                    fullyQualifyClassName(origPackage, child, String16("targetActivity"));
                }
            }
        }
    }

    // Deal with manifest package name overrides
    const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();
    if (instrumentationPackageNameOverride != NULL) {
        // Fix up instrumentation targets.
        Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());
        for (size_t i = 0; i < children.size(); i++) {
            sp<XMLNode> child = children.editItemAt(i);
            String8 tag(child->getElementName());
            if (tag == "instrumentation") {
                XMLNode::attribute_entry* attr = child->editAttribute(
                        String16("http://schemas.android.com/apk/res/android"), String16("targetPackage"));
                if (attr != NULL) {
                    attr->string.setTo(String16(instrumentationPackageNameOverride));
                }
            }
        }
    }
    
    // Generate split name if feature is present.
    const XMLNode::attribute_entry* attr = root->getAttribute(String16(), String16("featureName"));
    if (attr != NULL) {
        String16 splitName("feature_");
        splitName.append(attr->string);
        status_t err = root->addAttribute(String16(), String16("split"), splitName);
        if (err != NO_ERROR) {
            ALOGE("Failed to insert split name into AndroidManifest.xml");
            return err;
        }
    }

    return NO_ERROR;
}

static int32_t getPlatformAssetCookie(const AssetManager& assets) {
    // Find the system package (0x01). AAPT always generates attributes
    // with the type 0x01, so we're looking for the first attribute
    // resource in the system package.
    const ResTable& table = assets.getResources(true);
    Res_value val;
    ssize_t idx = table.getResource(0x01010000, &val, true);
    if (idx != NO_ERROR) {
        // Try as a bag.
        const ResTable::bag_entry* entry;
        ssize_t cnt = table.lockBag(0x01010000, &entry);
        if (cnt >= 0) {
            idx = entry->stringBlock;
        }
        table.unlockBag(entry);
    }

    if (idx < 0) {
        return 0;
    }
    return table.getTableCookie(idx);
}

enum {
    VERSION_CODE_ATTR = 0x0101021b,
    VERSION_NAME_ATTR = 0x0101021c,
};

static ssize_t extractPlatformBuildVersion(ResXMLTree& tree, Bundle* bundle) {
    size_t len;
    ResXMLTree::event_code_t code;
    while ((code = tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code != ResXMLTree::START_TAG) {
            continue;
        }

        const char16_t* ctag16 = tree.getElementName(&len);
        if (ctag16 == NULL) {
            fprintf(stderr, "ERROR: failed to get XML element name (bad string pool)\n");
            return UNKNOWN_ERROR;
        }

        String8 tag(ctag16, len);
        if (tag != "manifest") {
            continue;
        }

        String8 error;
        int32_t versionCode = AaptXml::getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);
        if (error != "") {
            fprintf(stderr, "ERROR: failed to get platform version code\n");
            return UNKNOWN_ERROR;
        }

        if (versionCode >= 0 && bundle->getPlatformBuildVersionCode() == "") {
            bundle->setPlatformBuildVersionCode(String8::format("%d", versionCode));
        }

        String8 versionName = AaptXml::getAttribute(tree, VERSION_NAME_ATTR, &error);
        if (error != "") {
            fprintf(stderr, "ERROR: failed to get platform version name\n");
            return UNKNOWN_ERROR;
        }

        if (versionName != "" && bundle->getPlatformBuildVersionName() == "") {
            bundle->setPlatformBuildVersionName(versionName);
        }
        return NO_ERROR;
    }

    fprintf(stderr, "ERROR: no <manifest> tag found in platform AndroidManifest.xml\n");
    return UNKNOWN_ERROR;
}

static ssize_t extractPlatformBuildVersion(AssetManager& assets, Bundle* bundle) {
    int32_t cookie = getPlatformAssetCookie(assets);
    if (cookie == 0) {
        // No platform was loaded.
        return NO_ERROR;
    }

    ResXMLTree tree;
    Asset* asset = assets.openNonAsset(cookie, "AndroidManifest.xml", Asset::ACCESS_STREAMING);
    if (asset == NULL) {
        fprintf(stderr, "ERROR: Platform AndroidManifest.xml not found\n");
        return UNKNOWN_ERROR;
    }

    ssize_t result = NO_ERROR;
    if (tree.setTo(asset->getBuffer(true), asset->getLength()) != NO_ERROR) {
        fprintf(stderr, "ERROR: Platform AndroidManifest.xml is corrupt\n");
        result = UNKNOWN_ERROR;
    } else {
        result = extractPlatformBuildVersion(tree, bundle);
    }

    delete asset;
    return result;
}

#define ASSIGN_IT(n) \
        do { \
            ssize_t index = resources->indexOfKey(String8(#n)); \
            if (index >= 0) { \
                n ## s = resources->valueAt(index); \
            } \
        } while (0)

status_t updatePreProcessedCache(Bundle* bundle)
{
    #if BENCHMARK
    fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n");
    long startPNGTime = clock();
    #endif /* BENCHMARK */

    String8 source(bundle->getResourceSourceDirs()[0]);
    String8 dest(bundle->getCrunchedOutputDir());

    FileFinder* ff = new SystemFileFinder();
    CrunchCache cc(source,dest,ff);

    CacheUpdater* cu = new SystemCacheUpdater(bundle);
    size_t numFiles = cc.crunch(cu);

    if (bundle->getVerbose())
        fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles);

    delete ff;
    delete cu;

    #if BENCHMARK
    fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n"
            ,(clock() - startPNGTime)/1000.0);
    #endif /* BENCHMARK */
    return 0;
}

status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& assets,
        const sp<ApkSplit>& split, sp<AaptFile>& outFile, ResourceTable* table) {
    const String8 filename("AndroidManifest.xml");
    const String16 androidPrefix("android");
    const String16 androidNSUri("http://schemas.android.com/apk/res/android");
    sp<XMLNode> root = XMLNode::newNamespace(filename, androidPrefix, androidNSUri);

    // Build the <manifest> tag
    sp<XMLNode> manifest = XMLNode::newElement(filename, String16(), String16("manifest"));

    // Add the 'package' attribute which is set to the package name.
    const char* packageName = assets->getPackage();
    const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
    if (manifestPackageNameOverride != NULL) {
        packageName = manifestPackageNameOverride;
    }
    manifest->addAttribute(String16(), String16("package"), String16(packageName));

    // Add the 'versionCode' attribute which is set to the original version code.
    if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "versionCode",
            bundle->getVersionCode(), true, true)) {
        return UNKNOWN_ERROR;
    }

    // Add the 'revisionCode' attribute, which is set to the original revisionCode.
    if (bundle->getRevisionCode().size() > 0) {
        if (!addTagAttribute(manifest, RESOURCES_ANDROID_NAMESPACE, "revisionCode",
                    bundle->getRevisionCode().string(), true, true)) {
            return UNKNOWN_ERROR;
        }
    }

    // Add the 'split' attribute which describes the configurations included.
    String8 splitName("config.");
    splitName.append(split->getPackageSafeName());
    manifest->addAttribute(String16(), String16("split"), String16(splitName));

    // Build an empty <application> tag (required).
    sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16("application"));

    // Add the 'hasCode' attribute which is never true for resource splits.
    if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, "hasCode",
            "false", true, true)) {
        return UNKNOWN_ERROR;
    }

    manifest->addChild(app);
    root->addChild(manifest);

    int err = compileXmlFile(bundle, assets, String16(), root, outFile, table);
    if (err < NO_ERROR) {
        return err;
    }
    outFile->setCompressionMethod(ZipEntry::kCompressDeflated);
    return NO_ERROR;
}

status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuilder>& builder)
{
    // First, look for a package file to parse.  This is required to
    // be able to generate the resource information.
    sp<AaptGroup> androidManifestFile =
            assets->getFiles().valueFor(String8("AndroidManifest.xml"));
    if (androidManifestFile == NULL) {
        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
        return UNKNOWN_ERROR;
    }

    status_t err = parsePackage(bundle, assets, androidManifestFile);
    if (err != NO_ERROR) {
        return err;
    }

    if (kIsDebug) {
        printf("Creating resources for package %s\n", assets->getPackage().string());
    }

    ResourceTable::PackageType packageType = ResourceTable::App;
    if (bundle->getBuildSharedLibrary()) {
        packageType = ResourceTable::SharedLibrary;
    } else if (bundle->getExtending()) {
        packageType = ResourceTable::System;
    } else if (!bundle->getFeatureOfPackage().isEmpty()) {
        packageType = ResourceTable::AppFeature;
    }

    ResourceTable table(bundle, String16(assets->getPackage()), packageType);
    err = table.addIncludedResources(bundle, assets);
    if (err != NO_ERROR) {
        return err;
    }

    if (kIsDebug) {
        printf("Found %d included resource packages\n", (int)table.size());
    }

    // Standard flags for compiled XML and optional UTF-8 encoding
    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;

    /* Only enable UTF-8 if the caller of aapt didn't specifically
     * request UTF-16 encoding and the parameters of this package
     * allow UTF-8 to be used.
     */
    if (!bundle->getUTF16StringsOption()) {
        xmlFlags |= XML_COMPILE_UTF8;
    }

    // --------------------------------------------------------------
    // First, gather all resource information.
    // --------------------------------------------------------------

    // resType -> leafName -> group
    KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
            new KeyedVector<String8, sp<ResourceTypeSet> >;
    collect_files(assets, resources);

    sp<ResourceTypeSet> drawables;
    sp<ResourceTypeSet> layouts;
    sp<ResourceTypeSet> anims;
    sp<ResourceTypeSet> animators;
    sp<ResourceTypeSet> interpolators;
    sp<ResourceTypeSet> transitions;
    sp<ResourceTypeSet> xmls;
    sp<ResourceTypeSet> raws;
    sp<ResourceTypeSet> colors;
    sp<ResourceTypeSet> menus;
    sp<ResourceTypeSet> mipmaps;

    ASSIGN_IT(drawable);
    ASSIGN_IT(layout);
    ASSIGN_IT(anim);
    ASSIGN_IT(animator);
    ASSIGN_IT(interpolator);
    ASSIGN_IT(transition);
    ASSIGN_IT(xml);
    ASSIGN_IT(raw);
    ASSIGN_IT(color);
    ASSIGN_IT(menu);
    ASSIGN_IT(mipmap);

    assets->setResources(resources);
    // now go through any resource overlays and collect their files
    sp<AaptAssets> current = assets->getOverlay();
    while(current.get()) {
        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
                new KeyedVector<String8, sp<ResourceTypeSet> >;
        current->setResources(resources);
        collect_files(current, resources);
        current = current->getOverlay();
    }
    // apply the overlay files to the base set
    if (!applyFileOverlay(bundle, assets, &drawables, "drawable") ||
            !applyFileOverlay(bundle, assets, &layouts, "layout") ||
            !applyFileOverlay(bundle, assets, &anims, "anim") ||
            !applyFileOverlay(bundle, assets, &animators, "animator") ||
            !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
            !applyFileOverlay(bundle, assets, &transitions, "transition") ||
            !applyFileOverlay(bundle, assets, &xmls, "xml") ||
            !applyFileOverlay(bundle, assets, &raws, "raw") ||
            !applyFileOverlay(bundle, assets, &colors, "color") ||
            !applyFileOverlay(bundle, assets, &menus, "menu") ||
            !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) {
        return UNKNOWN_ERROR;
    }

    bool hasErrors = false;

    if (drawables != NULL) {
        if (bundle->getOutputAPKFile() != NULL) {
            err = preProcessImages(bundle, assets, drawables, "drawable");
        }
        if (err == NO_ERROR) {
            err = makeFileResources(bundle, assets, &table, drawables, "drawable");
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        } else {
            hasErrors = true;
        }
    }

    if (mipmaps != NULL) {
        if (bundle->getOutputAPKFile() != NULL) {
            err = preProcessImages(bundle, assets, mipmaps, "mipmap");
        }
        if (err == NO_ERROR) {
            err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap");
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        } else {
            hasErrors = true;
        }
    }

    if (layouts != NULL) {
        err = makeFileResources(bundle, assets, &table, layouts, "layout");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (anims != NULL) {
        err = makeFileResources(bundle, assets, &table, anims, "anim");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (animators != NULL) {
        err = makeFileResources(bundle, assets, &table, animators, "animator");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (transitions != NULL) {
        err = makeFileResources(bundle, assets, &table, transitions, "transition");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (interpolators != NULL) {
        err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (xmls != NULL) {
        err = makeFileResources(bundle, assets, &table, xmls, "xml");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (raws != NULL) {
        err = makeFileResources(bundle, assets, &table, raws, "raw");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    // compile resources
    current = assets;
    while(current.get()) {
        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
                current->getResources();

        ssize_t index = resources->indexOfKey(String8("values"));
        if (index >= 0) {
            ResourceDirIterator it(resources->valueAt(index), String8("values"));
            ssize_t res;
            while ((res=it.next()) == NO_ERROR) {
                sp<AaptFile> file = it.getFile();
                res = compileResourceFile(bundle, assets, file, it.getParams(), 
                                          (current!=assets), &table);
                if (res != NO_ERROR) {
                    hasErrors = true;
                }
            }
        }
        current = current->getOverlay();
    }

    if (colors != NULL) {
        err = makeFileResources(bundle, assets, &table, colors, "color");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    if (menus != NULL) {
        err = makeFileResources(bundle, assets, &table, menus, "menu");
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    // --------------------------------------------------------------------
    // Assignment of resource IDs and initial generation of resource table.
    // --------------------------------------------------------------------

    if (table.hasResources()) {
        err = table.assignResourceIds();
        if (err < NO_ERROR) {
            return err;
        }
    }

    // --------------------------------------------------------------
    // Finally, we can now we can compile XML files, which may reference
    // resources.
    // --------------------------------------------------------------

    if (layouts != NULL) {
        ResourceDirIterator it(layouts, String8("layout"));
        while ((err=it.next()) == NO_ERROR) {
            String8 src = it.getFile()->getPrintableSource();
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err == NO_ERROR) {
                ResXMLTree block;
                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
                checkForIds(src, block);
            } else {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (anims != NULL) {
        ResourceDirIterator it(anims, String8("anim"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (animators != NULL) {
        ResourceDirIterator it(animators, String8("animator"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (interpolators != NULL) {
        ResourceDirIterator it(interpolators, String8("interpolator"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (transitions != NULL) {
        ResourceDirIterator it(transitions, String8("transition"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (xmls != NULL) {
        ResourceDirIterator it(xmls, String8("xml"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (drawables != NULL) {
        ResourceDirIterator it(drawables, String8("drawable"));
        while ((err=it.next()) == NO_ERROR) {
            err = postProcessImage(bundle, assets, &table, it.getFile());
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (colors != NULL) {
        ResourceDirIterator it(colors, String8("color"));
        while ((err=it.next()) == NO_ERROR) {
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err != NO_ERROR) {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    if (menus != NULL) {
        ResourceDirIterator it(menus, String8("menu"));
        while ((err=it.next()) == NO_ERROR) {
            String8 src = it.getFile()->getPrintableSource();
            err = compileXmlFile(bundle, assets, String16(it.getBaseName()),
                    it.getFile(), &table, xmlFlags);
            if (err == NO_ERROR) {
                ResXMLTree block;
                block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
                checkForIds(src, block);
            } else {
                hasErrors = true;
            }
        }

        if (err < NO_ERROR) {
            hasErrors = true;
        }
        err = NO_ERROR;
    }

    // Now compile any generated resources.
    std::queue<CompileResourceWorkItem>& workQueue = table.getWorkQueue();
    while (!workQueue.empty()) {
        CompileResourceWorkItem& workItem = workQueue.front();
        err = compileXmlFile(bundle, assets, workItem.resourceName, workItem.file, &table, xmlFlags);
        if (err == NO_ERROR) {
            assets->addResource(workItem.resPath.getPathLeaf(),
                    workItem.resPath,
                    workItem.file,
                    workItem.file->getResourceType());
        } else {
            hasErrors = true;
        }
        workQueue.pop();
    }

    if (table.validateLocalizations()) {
        hasErrors = true;
    }
    
    if (hasErrors) {
        return UNKNOWN_ERROR;
    }

    // If we're not overriding the platform build versions,
    // extract them from the platform APK.
    if (packageType != ResourceTable::System &&
            (bundle->getPlatformBuildVersionCode() == "" ||
            bundle->getPlatformBuildVersionName() == "")) {
        err = extractPlatformBuildVersion(assets->getAssetManager(), bundle);
        if (err != NO_ERROR) {
            return UNKNOWN_ERROR;
        }
    }

    const sp<AaptFile> manifestFile(androidManifestFile->getFiles().valueAt(0));
    String8 manifestPath(manifestFile->getPrintableSource());

    // Generate final compiled manifest file.
    manifestFile->clearData();
    sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);
    if (manifestTree == NULL) {
        return UNKNOWN_ERROR;
    }
    err = massageManifest(bundle, manifestTree);
    if (err < NO_ERROR) {
        return err;
    }
    err = compileXmlFile(bundle, assets, String16(), manifestTree, manifestFile, &table);
    if (err < NO_ERROR) {
        return err;
    }

    if (table.modifyForCompat(bundle) != NO_ERROR) {
        return UNKNOWN_ERROR;
    }

    //block.restart();
    //printXMLBlock(&block);

    // --------------------------------------------------------------
    // Generate the final resource table.
    // Re-flatten because we may have added new resource IDs
    // --------------------------------------------------------------


    ResTable finalResTable;
    sp<AaptFile> resFile;
    
    if (table.hasResources()) {
        sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
        err = table.addSymbols(symbols);
        if (err < NO_ERROR) {
            return err;
        }

        KeyedVector<Symbol, Vector<SymbolDefinition> > densityVaryingResources;
        if (builder->getSplits().size() > 1) {
            // Only look for density varying resources if we're generating
            // splits.
            table.getDensityVaryingResources(densityVaryingResources);
        }

        Vector<sp<ApkSplit> >& splits = builder->getSplits();
        const size_t numSplits = splits.size();
        for (size_t i = 0; i < numSplits; i++) {
            sp<ApkSplit>& split = splits.editItemAt(i);
            sp<AaptFile> flattenedTable = new AaptFile(String8("resources.arsc"),
                    AaptGroupEntry(), String8());
            err = table.flatten(bundle, split->getResourceFilter(),
                    flattenedTable, split->isBase());
            if (err != NO_ERROR) {
                fprintf(stderr, "Failed to generate resource table for split '%s'\n",
                        split->getPrintableName().string());
                return err;
            }
            split->addEntry(String8("resources.arsc"), flattenedTable);

            if (split->isBase()) {
                resFile = flattenedTable;
                err = finalResTable.add(flattenedTable->getData(), flattenedTable->getSize());
                if (err != NO_ERROR) {
                    fprintf(stderr, "Generated resource table is corrupt.\n");
                    return err;
                }
            } else {
                ResTable resTable;
                err = resTable.add(flattenedTable->getData(), flattenedTable->getSize());
                if (err != NO_ERROR) {
                    fprintf(stderr, "Generated resource table for split '%s' is corrupt.\n",
                            split->getPrintableName().string());
                    return err;
                }

                bool hasError = false;
                const std::set<ConfigDescription>& splitConfigs = split->getConfigs();
                for (std::set<ConfigDescription>::const_iterator iter = splitConfigs.begin();
                        iter != splitConfigs.end();
                        ++iter) {
                    const ConfigDescription& config = *iter;
                    if (AaptConfig::isDensityOnly(config)) {
                        // Each density only split must contain all
                        // density only resources.
                        Res_value val;
                        resTable.setParameters(&config);
                        const size_t densityVaryingResourceCount = densityVaryingResources.size();
                        for (size_t k = 0; k < densityVaryingResourceCount; k++) {
                            const Symbol& symbol = densityVaryingResources.keyAt(k);
                            ssize_t block = resTable.getResource(symbol.id, &val, true);
                            if (block < 0) {
                                // Maybe it's in the base?
                                finalResTable.setParameters(&config);
                                block = finalResTable.getResource(symbol.id, &val, true);
                            }

                            if (block < 0) {
                                hasError = true;
                                SourcePos().error("%s has no definition for density split '%s'",
                                        symbol.toString().string(), config.toString().string());

                                if (bundle->getVerbose()) {
                                    const Vector<SymbolDefinition>& defs = densityVaryingResources[k];
                                    const size_t defCount = std::min(size_t(5), defs.size());
                                    for (size_t d = 0; d < defCount; d++) {
                                        const SymbolDefinition& def = defs[d];
                                        def.source.error("%s has definition for %s",
                                                symbol.toString().string(), def.config.toString().string());
                                    }

                                    if (defCount < defs.size()) {
                                        SourcePos().error("and %d more ...", (int) (defs.size() - defCount));
                                    }
                                }
                            }
                        }
                    }
                }

                if (hasError) {
                    return UNKNOWN_ERROR;
                }

                // Generate the AndroidManifest for this split.
                sp<AaptFile> generatedManifest = new AaptFile(String8("AndroidManifest.xml"),
                        AaptGroupEntry(), String8());
                err = generateAndroidManifestForSplit(bundle, assets, split,
                        generatedManifest, &table);
                if (err != NO_ERROR) {
                    fprintf(stderr, "Failed to generate AndroidManifest.xml for split '%s'\n",
                            split->getPrintableName().string());
                    return err;
                }
                split->addEntry(String8("AndroidManifest.xml"), generatedManifest);
            }
        }

        if (bundle->getPublicOutputFile()) {
            FILE* fp = fopen(bundle->getPublicOutputFile(), "w+");
            if (fp == NULL) {
                fprintf(stderr, "ERROR: Unable to open public definitions output file %s: %s\n",
                        (const char*)bundle->getPublicOutputFile(), strerror(errno));
                return UNKNOWN_ERROR;
            }
            if (bundle->getVerbose()) {
                printf("  Writing public definitions to %s.\n", bundle->getPublicOutputFile());
            }
            table.writePublicDefinitions(String16(assets->getPackage()), fp);
            fclose(fp);
        }

        if (finalResTable.getTableCount() == 0 || resFile == NULL) {
            fprintf(stderr, "No resource table was generated.\n");
            return UNKNOWN_ERROR;
        }
    }

    // Perform a basic validation of the manifest file.  This time we
    // parse it with the comments intact, so that we can use them to
    // generate java docs...  so we are not going to write this one
    // back out to the final manifest data.
    sp<AaptFile> outManifestFile = new AaptFile(manifestFile->getSourceFile(),
            manifestFile->getGroupEntry(),
            manifestFile->getResourceType());
    err = compileXmlFile(bundle, assets, String16(), manifestFile,
            outManifestFile, &table,
            XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
            | XML_COMPILE_STRIP_WHITESPACE | XML_COMPILE_STRIP_RAW_VALUES);
    if (err < NO_ERROR) {
        return err;
    }
    ResXMLTree block;
    block.setTo(outManifestFile->getData(), outManifestFile->getSize(), true);
    String16 manifest16("manifest");
    String16 permission16("permission");
    String16 permission_group16("permission-group");
    String16 uses_permission16("uses-permission");
    String16 instrumentation16("instrumentation");
    String16 application16("application");
    String16 provider16("provider");
    String16 service16("service");
    String16 receiver16("receiver");
    String16 activity16("activity");
    String16 action16("action");
    String16 category16("category");
    String16 data16("scheme");
    String16 feature_group16("feature-group");
    String16 uses_feature16("uses-feature");
    const char* packageIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789";
    const char* packageIdentCharsWithTheStupid = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
    const char* classIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789$";
    const char* processIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:";
    const char* authoritiesIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-:;";
    const char* typeIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789:-/*+";
    const char* schemeIdentChars = "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ._0123456789-";
    ResXMLTree::event_code_t code;
    sp<AaptSymbols> permissionSymbols;
    sp<AaptSymbols> permissionGroupSymbols;
    while ((code=block.next()) != ResXMLTree::END_DOCUMENT
           && code > ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            size_t len;
            if (block.getElementNamespace(&len) != NULL) {
                continue;
            }
            if (strcmp16(block.getElementName(&len), manifest16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, NULL, "package",
                                 packageIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "sharedUserId", packageIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), permission16.string()) == 0
                    || strcmp16(block.getElementName(&len), permission_group16.string()) == 0) {
                const bool isGroup = strcmp16(block.getElementName(&len),
                        permission_group16.string()) == 0;
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", isGroup ? packageIdentCharsWithTheStupid
                                 : packageIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                SourcePos srcPos(manifestPath, block.getLineNumber());
                sp<AaptSymbols> syms;
                if (!isGroup) {
                    syms = permissionSymbols;
                    if (syms == NULL) {
                        sp<AaptSymbols> symbols =
                                assets->getSymbolsFor(String8("Manifest"));
                        syms = permissionSymbols = symbols->addNestedSymbol(
                                String8("permission"), srcPos);
                    }
                } else {
                    syms = permissionGroupSymbols;
                    if (syms == NULL) {
                        sp<AaptSymbols> symbols =
                                assets->getSymbolsFor(String8("Manifest"));
                        syms = permissionGroupSymbols = symbols->addNestedSymbol(
                                String8("permission_group"), srcPos);
                    }
                }
                size_t len;
                ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name");
                const char16_t* id = block.getAttributeStringValue(index, &len);
                if (id == NULL) {
                    fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", 
                            manifestPath.string(), block.getLineNumber(),
                            String8(block.getElementName(&len)).string());
                    hasErrors = true;
                    break;
                }
                String8 idStr(id);
                char* p = idStr.lockBuffer(idStr.size());
                char* e = p + idStr.size();
                bool begins_with_digit = true;  // init to true so an empty string fails
                while (e > p) {
                    e--;
                    if (*e >= '0' && *e <= '9') {
                      begins_with_digit = true;
                      continue;
                    }
                    if ((*e >= 'a' && *e <= 'z') ||
                        (*e >= 'A' && *e <= 'Z') ||
                        (*e == '_')) {
                      begins_with_digit = false;
                      continue;
                    }
                    if (isGroup && (*e == '-')) {
                        *e = '_';
                        begins_with_digit = false;
                        continue;
                    }
                    e++;
                    break;
                }
                idStr.unlockBuffer();
                // verify that we stopped because we hit a period or
                // the beginning of the string, and that the
                // identifier didn't begin with a digit.
                if (begins_with_digit || (e != p && *(e-1) != '.')) {
                  fprintf(stderr,
                          "%s:%d: Permission name <%s> is not a valid Java symbol\n",
                          manifestPath.string(), block.getLineNumber(), idStr.string());
                  hasErrors = true;
                }
                syms->addStringSymbol(String8(e), idStr, srcPos);
                const char16_t* cmt = block.getComment(&len);
                if (cmt != NULL && *cmt != 0) {
                    //printf("Comment of %s: %s\n", String8(e).string(),
                    //        String8(cmt).string());
                    syms->appendComment(String8(e), String16(cmt), srcPos);
                } else {
                    //printf("No comment for %s\n", String8(e).string());
                }
                syms->makeSymbolPublic(String8(e), srcPos);
            } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", packageIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), instrumentation16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", classIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "targetPackage",
                                 packageIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), application16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", classIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "permission",
                                 packageIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "process",
                                 processIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
                                 processIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), provider16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", classIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "authorities",
                                 authoritiesIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "permission",
                                 packageIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "process",
                                 processIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), service16.string()) == 0
                       || strcmp16(block.getElementName(&len), receiver16.string()) == 0
                       || strcmp16(block.getElementName(&len), activity16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block, RESOURCES_ANDROID_NAMESPACE,
                                 "name", classIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "permission",
                                 packageIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "process",
                                 processIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "taskAffinity",
                                 processIdentChars, false) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), action16.string()) == 0
                       || strcmp16(block.getElementName(&len), category16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "name",
                                 packageIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), data16.string()) == 0) {
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "mimeType",
                                 typeIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
                if (validateAttr(manifestPath, finalResTable, block,
                                 RESOURCES_ANDROID_NAMESPACE, "scheme",
                                 schemeIdentChars, true) != ATTR_OKAY) {
                    hasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), feature_group16.string()) == 0) {
                int depth = 1;
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                       && code > ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::START_TAG) {
                        depth++;
                        if (strcmp16(block.getElementName(&len), uses_feature16.string()) == 0) {
                            ssize_t idx = block.indexOfAttribute(
                                    RESOURCES_ANDROID_NAMESPACE, "required");
                            if (idx < 0) {
                                continue;
                            }

                            int32_t data = block.getAttributeData(idx);
                            if (data == 0) {
                                fprintf(stderr, "%s:%d: Tag <uses-feature> can not have "
                                        "android:required=\"false\" when inside a "
                                        "<feature-group> tag.\n",
                                        manifestPath.string(), block.getLineNumber());
                                hasErrors = true;
                            }
                        }
                    } else if (code == ResXMLTree::END_TAG) {
                        depth--;
                        if (depth == 0) {
                            break;
                        }
                    }
                }
            }
        }
    }

    if (hasErrors) {
        return UNKNOWN_ERROR;
    }

    if (resFile != NULL) {
        // These resources are now considered to be a part of the included
        // resources, for others to reference.
        err = assets->addIncludedResources(resFile);
        if (err < NO_ERROR) {
            fprintf(stderr, "ERROR: Unable to parse generated resources, aborting.\n");
            return err;
        }
    }
    
    return err;
}

static const char* getIndentSpace(int indent)
{
static const char whitespace[] =
"                                                                                       ";

    return whitespace + sizeof(whitespace) - 1 - indent*4;
}

static String8 flattenSymbol(const String8& symbol) {
    String8 result(symbol);
    ssize_t first;
    if ((first = symbol.find(":", 0)) >= 0
            || (first = symbol.find(".", 0)) >= 0) {
        size_t size = symbol.size();
        char* buf = result.lockBuffer(size);
        for (size_t i = first; i < size; i++) {
            if (buf[i] == ':' || buf[i] == '.') {
                buf[i] = '_';
            }
        }
        result.unlockBuffer(size);
    }
    return result;
}

static String8 getSymbolPackage(const String8& symbol, const sp<AaptAssets>& assets, bool pub) {
    ssize_t colon = symbol.find(":", 0);
    if (colon >= 0) {
        return String8(symbol.string(), colon);
    }
    return pub ? assets->getPackage() : assets->getSymbolsPrivatePackage();
}

static String8 getSymbolName(const String8& symbol) {
    ssize_t colon = symbol.find(":", 0);
    if (colon >= 0) {
        return String8(symbol.string() + colon + 1);
    }
    return symbol;
}

static String16 getAttributeComment(const sp<AaptAssets>& assets,
                                    const String8& name,
                                    String16* outTypeComment = NULL)
{
    sp<AaptSymbols> asym = assets->getSymbolsFor(String8("R"));
    if (asym != NULL) {
        //printf("Got R symbols!\n");
        asym = asym->getNestedSymbols().valueFor(String8("attr"));
        if (asym != NULL) {
            //printf("Got attrs symbols! comment %s=%s\n",
            //     name.string(), String8(asym->getComment(name)).string());
            if (outTypeComment != NULL) {
                *outTypeComment = asym->getTypeComment(name);
            }
            return asym->getComment(name);
        }
    }
    return String16();
}

static status_t writeResourceLoadedCallbackForLayoutClasses(
    FILE* fp, const sp<AaptAssets>& assets,
    const sp<AaptSymbols>& symbols, int indent, bool /* includePrivate */)
{
    String16 attr16("attr");
    String16 package16(assets->getPackage());

    const char* indentStr = getIndentSpace(indent);
    bool hasErrors = false;

    size_t i;
    size_t N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
        String8 nclassName(flattenSymbol(realClassName));

        fprintf(fp,
                "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n"
                "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n"
                "%s}\n",
                indentStr, nclassName.string(),
                getIndentSpace(indent+1), nclassName.string(), nclassName.string(),
                indentStr);
    }

    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

static status_t writeResourceLoadedCallback(
    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
    const sp<AaptSymbols>& symbols, const String8& className, int indent)
{
    size_t i;
    status_t err = NO_ERROR;

    size_t N = symbols->getSymbols().size();
    for (i=0; i<N; i++) {
        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
        if (sym.typeCode == AaptSymbolEntry::TYPE_UNKNOWN) {
            continue;
        }
        if (!assets->isJavaSymbol(sym, includePrivate)) {
            continue;
        }
        String8 flat_name(flattenSymbol(sym.name));
        fprintf(fp,
                "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n",
                getIndentSpace(indent), className.string(), flat_name.string(),
                className.string(), flat_name.string());
    }

    N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
        if (nclassName == "styleable") {
            err = writeResourceLoadedCallbackForLayoutClasses(
                    fp, assets, nsymbols, indent, includePrivate);
        } else {
            err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,
                    nclassName, indent);
        }
        if (err != NO_ERROR) {
            return err;
        }
    }

    return NO_ERROR;
}

static status_t writeLayoutClasses(
    FILE* fp, const sp<AaptAssets>& assets,
    const sp<AaptSymbols>& symbols, int indent, bool includePrivate, bool nonConstantId)
{
    const char* indentStr = getIndentSpace(indent);
    if (!includePrivate) {
        fprintf(fp, "%s/** @doconly */\n", indentStr);
    }
    fprintf(fp, "%spublic static final class styleable {\n", indentStr);
    indent++;

    String16 attr16("attr");
    String16 package16(assets->getPackage());

    indentStr = getIndentSpace(indent);
    bool hasErrors = false;

    size_t i;
    size_t N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
        String8 nclassName(flattenSymbol(realClassName));

        SortedVector<uint32_t> idents;
        Vector<uint32_t> origOrder;
        Vector<bool> publicFlags;

        size_t a;
        size_t NA = nsymbols->getSymbols().size();
        for (a=0; a<NA; a++) {
            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
                    ? sym.int32Val : 0;
            bool isPublic = true;
            if (code == 0) {
                String16 name16(sym.name);
                uint32_t typeSpecFlags;
                code = assets->getIncludedResources().identifierForName(
                    name16.string(), name16.size(),
                    attr16.string(), attr16.size(),
                    package16.string(), package16.size(), &typeSpecFlags);
                if (code == 0) {
                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
                            nclassName.string(), sym.name.string());
                    hasErrors = true;
                }
                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
            }
            idents.add(code);
            origOrder.add(code);
            publicFlags.add(isPublic);
        }

        NA = idents.size();

        String16 comment = symbols->getComment(realClassName);
        AnnotationProcessor ann;
        fprintf(fp, "%s/** ", indentStr);
        if (comment.size() > 0) {
            String8 cmt(comment);
            ann.preprocessComment(cmt);
            fprintf(fp, "%s\n", cmt.string());
        } else {
            fprintf(fp, "Attributes that can be used with a %s.\n", nclassName.string());
        }
        bool hasTable = false;
        for (a=0; a<NA; a++) {
            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
            if (pos >= 0) {
                if (!hasTable) {
                    hasTable = true;
                    fprintf(fp,
                            "%s   <p>Includes the following attributes:</p>\n"
                            "%s   <table>\n"
                            "%s   <colgroup align=\"left\" />\n"
                            "%s   <colgroup align=\"left\" />\n"
                            "%s   <tr><th>Attribute</th><th>Description</th></tr>\n",
                            indentStr,
                            indentStr,
                            indentStr,
                            indentStr,
                            indentStr);
                }
                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
                if (!publicFlags.itemAt(a) && !includePrivate) {
                    continue;
                }
                String8 name8(sym.name);
                String16 comment(sym.comment);
                if (comment.size() <= 0) {
                    comment = getAttributeComment(assets, name8);
                }
                if (comment.size() > 0) {
                    const char16_t* p = comment.string();
                    while (*p != 0 && *p != '.') {
                        if (*p == '{') {
                            while (*p != 0 && *p != '}') {
                                p++;
                            }
                        } else {
                            p++;
                        }
                    }
                    if (*p == '.') {
                        p++;
                    }
                    comment = String16(comment.string(), p-comment.string());
                }
                fprintf(fp, "%s   <tr><td><code>{@link #%s_%s %s:%s}</code></td><td>%s</td></tr>\n",
                        indentStr, nclassName.string(),
                        flattenSymbol(name8).string(),
                        getSymbolPackage(name8, assets, true).string(),
                        getSymbolName(name8).string(),
                        String8(comment).string());
            }
        }
        if (hasTable) {
            fprintf(fp, "%s   </table>\n", indentStr);
        }
        for (a=0; a<NA; a++) {
            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
            if (pos >= 0) {
                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
                if (!publicFlags.itemAt(a) && !includePrivate) {
                    continue;
                }
                fprintf(fp, "%s   @see #%s_%s\n",
                        indentStr, nclassName.string(),
                        flattenSymbol(sym.name).string());
            }
        }
        fprintf(fp, "%s */\n", getIndentSpace(indent));

        ann.printAnnotations(fp, indentStr);
        
        fprintf(fp,
                "%spublic static final int[] %s = {\n"
                "%s",
                indentStr, nclassName.string(),
                getIndentSpace(indent+1));

        for (a=0; a<NA; a++) {
            if (a != 0) {
                if ((a&3) == 0) {
                    fprintf(fp, ",\n%s", getIndentSpace(indent+1));
                } else {
                    fprintf(fp, ", ");
                }
            }
            fprintf(fp, "0x%08x", idents[a]);
        }

        fprintf(fp, "\n%s};\n", indentStr);

        for (a=0; a<NA; a++) {
            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
            if (pos >= 0) {
                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
                if (!publicFlags.itemAt(a) && !includePrivate) {
                    continue;
                }
                String8 name8(sym.name);
                String16 comment(sym.comment);
                String16 typeComment;
                if (comment.size() <= 0) {
                    comment = getAttributeComment(assets, name8, &typeComment);
                } else {
                    getAttributeComment(assets, name8, &typeComment);
                }

                uint32_t typeSpecFlags = 0;
                String16 name16(sym.name);
                assets->getIncludedResources().identifierForName(
                    name16.string(), name16.size(),
                    attr16.string(), attr16.size(),
                    package16.string(), package16.size(), &typeSpecFlags);
                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
                const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;

                AnnotationProcessor ann;
                fprintf(fp, "%s/**\n", indentStr);
                if (comment.size() > 0) {
                    String8 cmt(comment);
                    ann.preprocessComment(cmt);
                    fprintf(fp, "%s  <p>\n%s  @attr description\n", indentStr, indentStr);
                    fprintf(fp, "%s  %s\n", indentStr, cmt.string());
                } else {
                    fprintf(fp,
                            "%s  <p>This symbol is the offset where the {@link %s.R.attr#%s}\n"
                            "%s  attribute's value can be found in the {@link #%s} array.\n",
                            indentStr,
                            getSymbolPackage(name8, assets, pub).string(),
                            getSymbolName(name8).string(),
                            indentStr, nclassName.string());
                }
                if (typeComment.size() > 0) {
                    String8 cmt(typeComment);
                    ann.preprocessComment(cmt);
                    fprintf(fp, "\n\n%s  %s\n", indentStr, cmt.string());
                }
                if (comment.size() > 0) {
                    if (pub) {
                        fprintf(fp,
                                "%s  <p>This corresponds to the global attribute\n"
                                "%s  resource symbol {@link %s.R.attr#%s}.\n",
                                indentStr, indentStr,
                                getSymbolPackage(name8, assets, true).string(),
                                getSymbolName(name8).string());
                    } else {
                        fprintf(fp,
                                "%s  <p>This is a private symbol.\n", indentStr);
                    }
                }
                fprintf(fp, "%s  @attr name %s:%s\n", indentStr,
                        getSymbolPackage(name8, assets, pub).string(),
                        getSymbolName(name8).string());
                fprintf(fp, "%s*/\n", indentStr);
                ann.printAnnotations(fp, indentStr);

                const char * id_format = nonConstantId ?
                        "%spublic static int %s_%s = %d;\n" :
                        "%spublic static final int %s_%s = %d;\n";

                fprintf(fp,
                        id_format,
                        indentStr, nclassName.string(),
                        flattenSymbol(name8).string(), (int)pos);
            }
        }
    }

    indent--;
    fprintf(fp, "%s};\n", getIndentSpace(indent));
    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}

static status_t writeTextLayoutClasses(
    FILE* fp, const sp<AaptAssets>& assets,
    const sp<AaptSymbols>& symbols, bool includePrivate)
{
    String16 attr16("attr");
    String16 package16(assets->getPackage());

    bool hasErrors = false;

    size_t i;
    size_t N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 realClassName(symbols->getNestedSymbols().keyAt(i));
        String8 nclassName(flattenSymbol(realClassName));

        SortedVector<uint32_t> idents;
        Vector<uint32_t> origOrder;
        Vector<bool> publicFlags;

        size_t a;
        size_t NA = nsymbols->getSymbols().size();
        for (a=0; a<NA; a++) {
            const AaptSymbolEntry& sym(nsymbols->getSymbols().valueAt(a));
            int32_t code = sym.typeCode == AaptSymbolEntry::TYPE_INT32
                    ? sym.int32Val : 0;
            bool isPublic = true;
            if (code == 0) {
                String16 name16(sym.name);
                uint32_t typeSpecFlags;
                code = assets->getIncludedResources().identifierForName(
                    name16.string(), name16.size(),
                    attr16.string(), attr16.size(),
                    package16.string(), package16.size(), &typeSpecFlags);
                if (code == 0) {
                    fprintf(stderr, "ERROR: In <declare-styleable> %s, unable to find attribute %s\n",
                            nclassName.string(), sym.name.string());
                    hasErrors = true;
                }
                isPublic = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
            }
            idents.add(code);
            origOrder.add(code);
            publicFlags.add(isPublic);
        }

        NA = idents.size();

        fprintf(fp, "int[] styleable %s {", nclassName.string());

        for (a=0; a<NA; a++) {
            if (a != 0) {
                fprintf(fp, ",");
            }
            fprintf(fp, " 0x%08x", idents[a]);
        }

        fprintf(fp, " }\n");

        for (a=0; a<NA; a++) {
            ssize_t pos = idents.indexOf(origOrder.itemAt(a));
            if (pos >= 0) {
                const AaptSymbolEntry& sym = nsymbols->getSymbols().valueAt(a);
                if (!publicFlags.itemAt(a) && !includePrivate) {
                    continue;
                }
                String8 name8(sym.name);
                String16 comment(sym.comment);
                String16 typeComment;
                if (comment.size() <= 0) {
                    comment = getAttributeComment(assets, name8, &typeComment);
                } else {
                    getAttributeComment(assets, name8, &typeComment);
                }

                uint32_t typeSpecFlags = 0;
                String16 name16(sym.name);
                assets->getIncludedResources().identifierForName(
                    name16.string(), name16.size(),
                    attr16.string(), attr16.size(),
                    package16.string(), package16.size(), &typeSpecFlags);
                //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
                //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
                //const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;

                fprintf(fp,
                        "int styleable %s_%s %d\n",
                        nclassName.string(),
                        flattenSymbol(name8).string(), (int)pos);
            }
        }
    }

    return hasErrors ? STATUST(UNKNOWN_ERROR) : NO_ERROR;
}

static status_t writeSymbolClass(
    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
    const sp<AaptSymbols>& symbols, const String8& className, int indent,
    bool nonConstantId, bool emitCallback)
{
    fprintf(fp, "%spublic %sfinal class %s {\n",
            getIndentSpace(indent),
            indent != 0 ? "static " : "", className.string());
    indent++;

    size_t i;
    status_t err = NO_ERROR;

    const char * id_format = nonConstantId ?
            "%spublic static int %s=0x%08x;\n" :
            "%spublic static final int %s=0x%08x;\n";

    size_t N = symbols->getSymbols().size();
    for (i=0; i<N; i++) {
        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
            continue;
        }
        if (!assets->isJavaSymbol(sym, includePrivate)) {
            continue;
        }
        String8 name8(sym.name);
        String16 comment(sym.comment);
        bool haveComment = false;
        AnnotationProcessor ann;
        if (comment.size() > 0) {
            haveComment = true;
            String8 cmt(comment);
            ann.preprocessComment(cmt);
            fprintf(fp,
                    "%s/** %s\n",
                    getIndentSpace(indent), cmt.string());
        } else if (sym.isPublic && !includePrivate) {
            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
                assets->getPackage().string(), className.string(),
                String8(sym.name).string());
        }
        String16 typeComment(sym.typeComment);
        if (typeComment.size() > 0) {
            String8 cmt(typeComment);
            ann.preprocessComment(cmt);
            if (!haveComment) {
                haveComment = true;
                fprintf(fp,
                        "%s/** %s\n", getIndentSpace(indent), cmt.string());
            } else {
                fprintf(fp,
                        "%s %s\n", getIndentSpace(indent), cmt.string());
            }
        }
        if (haveComment) {
            fprintf(fp,"%s */\n", getIndentSpace(indent));
        }
        ann.printAnnotations(fp, getIndentSpace(indent));
        fprintf(fp, id_format,
                getIndentSpace(indent),
                flattenSymbol(name8).string(), (int)sym.int32Val);
    }

    for (i=0; i<N; i++) {
        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
        if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) {
            continue;
        }
        if (!assets->isJavaSymbol(sym, includePrivate)) {
            continue;
        }
        String8 name8(sym.name);
        String16 comment(sym.comment);
        AnnotationProcessor ann;
        if (comment.size() > 0) {
            String8 cmt(comment);
            ann.preprocessComment(cmt);
            fprintf(fp,
                    "%s/** %s\n"
                     "%s */\n",
                    getIndentSpace(indent), cmt.string(),
                    getIndentSpace(indent));
        } else if (sym.isPublic && !includePrivate) {
            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
                assets->getPackage().string(), className.string(),
                String8(sym.name).string());
        }
        ann.printAnnotations(fp, getIndentSpace(indent));
        fprintf(fp, "%spublic static final String %s=\"%s\";\n",
                getIndentSpace(indent),
                flattenSymbol(name8).string(), sym.stringVal.string());
    }

    sp<AaptSymbols> styleableSymbols;

    N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
        if (nclassName == "styleable") {
            styleableSymbols = nsymbols;
        } else {
            err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName,
                    indent, nonConstantId, false);
        }
        if (err != NO_ERROR) {
            return err;
        }
    }

    if (styleableSymbols != NULL) {
        err = writeLayoutClasses(fp, assets, styleableSymbols, indent, includePrivate, nonConstantId);
        if (err != NO_ERROR) {
            return err;
        }
    }

    if (emitCallback) {
        fprintf(fp, "%spublic static void onResourcesLoaded(int packageId) {\n",
                getIndentSpace(indent));
        writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);
        fprintf(fp, "%s}\n", getIndentSpace(indent));
    }

    indent--;
    fprintf(fp, "%s}\n", getIndentSpace(indent));
    return NO_ERROR;
}

static status_t writeTextSymbolClass(
    FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
    const sp<AaptSymbols>& symbols, const String8& className)
{
    size_t i;
    status_t err = NO_ERROR;

    size_t N = symbols->getSymbols().size();
    for (i=0; i<N; i++) {
        const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
        if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) {
            continue;
        }

        if (!assets->isJavaSymbol(sym, includePrivate)) {
            continue;
        }

        String8 name8(sym.name);
        fprintf(fp, "int %s %s 0x%08x\n",
                className.string(),
                flattenSymbol(name8).string(), (int)sym.int32Val);
    }

    N = symbols->getNestedSymbols().size();
    for (i=0; i<N; i++) {
        sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
        String8 nclassName(symbols->getNestedSymbols().keyAt(i));
        if (nclassName == "styleable") {
            err = writeTextLayoutClasses(fp, assets, nsymbols, includePrivate);
        } else {
            err = writeTextSymbolClass(fp, assets, includePrivate, nsymbols, nclassName);
        }
        if (err != NO_ERROR) {
            return err;
        }
    }

    return NO_ERROR;
}

status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
    const String8& package, bool includePrivate, bool emitCallback)
{
    if (!bundle->getRClassDir()) {
        return NO_ERROR;
    }

    const char* textSymbolsDest = bundle->getOutputTextSymbols();

    String8 R("R");
    const size_t N = assets->getSymbols().size();
    for (size_t i=0; i<N; i++) {
        sp<AaptSymbols> symbols = assets->getSymbols().valueAt(i);
        String8 className(assets->getSymbols().keyAt(i));
        String8 dest(bundle->getRClassDir());

        if (bundle->getMakePackageDirs()) {
            String8 pkg(package);
            const char* last = pkg.string();
            const char* s = last-1;
            do {
                s++;
                if (s > last && (*s == '.' || *s == 0)) {
                    String8 part(last, s-last);
                    dest.appendPath(part);
#ifdef HAVE_MS_C_RUNTIME
                    _mkdir(dest.string());
#else
                    mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
#endif
                    last = s+1;
                }
            } while (*s);
        }
        dest.appendPath(className);
        dest.append(".java");
        FILE* fp = fopen(dest.string(), "w+");
        if (fp == NULL) {
            fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
                    dest.string(), strerror(errno));
            return UNKNOWN_ERROR;
        }
        if (bundle->getVerbose()) {
            printf("  Writing symbols for class %s.\n", className.string());
        }

        fprintf(fp,
            "/* 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"
            "package %s;\n\n", package.string());

        status_t err = writeSymbolClass(fp, assets, includePrivate, symbols,
                className, 0, bundle->getNonConstantId(), emitCallback);
        fclose(fp);
        if (err != NO_ERROR) {
            return err;
        }

        if (textSymbolsDest != NULL && R == className) {
            String8 textDest(textSymbolsDest);
            textDest.appendPath(className);
            textDest.append(".txt");

            FILE* fp = fopen(textDest.string(), "w+");
            if (fp == NULL) {
                fprintf(stderr, "ERROR: Unable to open text symbol file %s: %s\n",
                        textDest.string(), strerror(errno));
                return UNKNOWN_ERROR;
            }
            if (bundle->getVerbose()) {
                printf("  Writing text symbols for class %s.\n", className.string());
            }

            status_t err = writeTextSymbolClass(fp, assets, includePrivate, symbols,
                    className);
            fclose(fp);
            if (err != NO_ERROR) {
                return err;
            }
        }

        // If we were asked to generate a dependency file, we'll go ahead and add this R.java
        // as a target in the dependency file right next to it.
        if (bundle->getGenDependencies() && R == className) {
            // Add this R.java to the dependency file
            String8 dependencyFile(bundle->getRClassDir());
            dependencyFile.appendPath("R.java.d");

            FILE *fp = fopen(dependencyFile.string(), "a");
            fprintf(fp,"%s \\\n", dest.string());
            fclose(fp);
        }
    }

    return NO_ERROR;
}


class ProguardKeepSet
{
public:
    // { rule --> { file locations } }
    KeyedVector<String8, SortedVector<String8> > rules;

    void add(const String8& rule, const String8& where);
};

void ProguardKeepSet::add(const String8& rule, const String8& where)
{
    ssize_t index = rules.indexOfKey(rule);
    if (index < 0) {
        index = rules.add(rule, SortedVector<String8>());
    }
    rules.editValueAt(index).add(where);
}

void
addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,
        const char* pkg, const String8& srcName, int line)
{
    String8 className(inClassName);
    if (pkg != NULL) {
        // asdf     --> package.asdf
        // .asdf  .a.b  --> package.asdf package.a.b
        // asdf.adsf --> asdf.asdf
        const char* p = className.string();
        const char* q = strchr(p, '.');
        if (p == q) {
            className = pkg;
            className.append(inClassName);
        } else if (q == NULL) {
            className = pkg;
            className.append(".");
            className.append(inClassName);
        }
    }

    String8 rule("-keep class ");
    rule += className;
    rule += " { <init>(...); }";

    String8 location("view ");
    location += srcName;
    char lineno[20];
    sprintf(lineno, ":%d", line);
    location += lineno;

    keep->add(rule, location);
}

void
addProguardKeepMethodRule(ProguardKeepSet* keep, const String8& memberName,
        const char* /* pkg */, const String8& srcName, int line)
{
    String8 rule("-keepclassmembers class * { *** ");
    rule += memberName;
    rule += "(...); }";

    String8 location("onClick ");
    location += srcName;
    char lineno[20];
    sprintf(lineno, ":%d", line);
    location += lineno;

    keep->add(rule, location);
}

status_t
writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
{
    status_t err;
    ResXMLTree tree;
    size_t len;
    ResXMLTree::event_code_t code;
    int depth = 0;
    bool inApplication = false;
    String8 error;
    sp<AaptGroup> assGroup;
    sp<AaptFile> assFile;
    String8 pkg;

    // First, look for a package file to parse.  This is required to
    // be able to generate the resource information.
    assGroup = assets->getFiles().valueFor(String8("AndroidManifest.xml"));
    if (assGroup == NULL) {
        fprintf(stderr, "ERROR: No AndroidManifest.xml file found.\n");
        return -1;
    }

    if (assGroup->getFiles().size() != 1) {
        fprintf(stderr, "warning: Multiple AndroidManifest.xml files found, using %s\n",
                assGroup->getFiles().valueAt(0)->getPrintableSource().string());
    }

    assFile = assGroup->getFiles().valueAt(0);

    err = parseXMLResource(assFile, &tree);
    if (err != NO_ERROR) {
        return err;
    }

    tree.restart();

    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::END_TAG) {
            if (/* name == "Application" && */ depth == 2) {
                inApplication = false;
            }
            depth--;
            continue;
        }
        if (code != ResXMLTree::START_TAG) {
            continue;
        }
        depth++;
        String8 tag(tree.getElementName(&len));
        // printf("Depth %d tag %s\n", depth, tag.string());
        bool keepTag = false;
        if (depth == 1) {
            if (tag != "manifest") {
                fprintf(stderr, "ERROR: manifest does not start with <manifest> tag\n");
                return -1;
            }
            pkg = AaptXml::getAttribute(tree, NULL, "package");
        } else if (depth == 2) {
            if (tag == "application") {
                inApplication = true;
                keepTag = true;

                String8 agent = AaptXml::getAttribute(tree,
                        "http://schemas.android.com/apk/res/android",
                        "backupAgent", &error);
                if (agent.length() > 0) {
                    addProguardKeepRule(keep, agent, pkg.string(),
                            assFile->getPrintableSource(), tree.getLineNumber());
                }
            } else if (tag == "instrumentation") {
                keepTag = true;
            }
        }
        if (!keepTag && inApplication && depth == 3) {
            if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
                keepTag = true;
            }
        }
        if (keepTag) {
            String8 name = AaptXml::getAttribute(tree,
                    "http://schemas.android.com/apk/res/android", "name", &error);
            if (error != "") {
                fprintf(stderr, "ERROR: %s\n", error.string());
                return -1;
            }
            if (name.length() > 0) {
                addProguardKeepRule(keep, name, pkg.string(),
                        assFile->getPrintableSource(), tree.getLineNumber());
            }
        }
    }

    return NO_ERROR;
}

struct NamespaceAttributePair {
    const char* ns;
    const char* attr;

    NamespaceAttributePair(const char* n, const char* a) : ns(n), attr(a) {}
    NamespaceAttributePair() : ns(NULL), attr(NULL) {}
};

status_t
writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,
        const Vector<String8>& startTags, const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs)
{
    status_t err;
    ResXMLTree tree;
    size_t len;
    ResXMLTree::event_code_t code;

    err = parseXMLResource(layoutFile, &tree);
    if (err != NO_ERROR) {
        return err;
    }

    tree.restart();

    if (!startTags.isEmpty()) {
        bool haveStart = false;
        while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
            if (code != ResXMLTree::START_TAG) {
                continue;
            }
            String8 tag(tree.getElementName(&len));
            const size_t numStartTags = startTags.size();
            for (size_t i = 0; i < numStartTags; i++) {
                if (tag == startTags[i]) {
                    haveStart = true;
                }
            }
            break;
        }
        if (!haveStart) {
            return NO_ERROR;
        }
    }

    while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code != ResXMLTree::START_TAG) {
            continue;
        }
        String8 tag(tree.getElementName(&len));

        // If there is no '.', we'll assume that it's one of the built in names.
        if (strchr(tag.string(), '.')) {
            addProguardKeepRule(keep, tag, NULL,
                    layoutFile->getPrintableSource(), tree.getLineNumber());
        } else if (tagAttrPairs != NULL) {
            ssize_t tagIndex = tagAttrPairs->indexOfKey(tag);
            if (tagIndex >= 0) {
                const Vector<NamespaceAttributePair>& nsAttrVector = tagAttrPairs->valueAt(tagIndex);
                for (size_t i = 0; i < nsAttrVector.size(); i++) {
                    const NamespaceAttributePair& nsAttr = nsAttrVector[i];

                    ssize_t attrIndex = tree.indexOfAttribute(nsAttr.ns, nsAttr.attr);
                    if (attrIndex < 0) {
                        // fprintf(stderr, "%s:%d: <%s> does not have attribute %s:%s.\n",
                        //        layoutFile->getPrintableSource().string(), tree.getLineNumber(),
                        //        tag.string(), nsAttr.ns, nsAttr.attr);
                    } else {
                        size_t len;
                        addProguardKeepRule(keep,
                                            String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
                                            layoutFile->getPrintableSource(), tree.getLineNumber());
                    }
                }
            }
        }
        ssize_t attrIndex = tree.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "onClick");
        if (attrIndex >= 0) {
            size_t len;
            addProguardKeepMethodRule(keep,
                                String8(tree.getAttributeStringValue(attrIndex, &len)), NULL,
                                layoutFile->getPrintableSource(), tree.getLineNumber());
        }
    }

    return NO_ERROR;
}

static void addTagAttrPair(KeyedVector<String8, Vector<NamespaceAttributePair> >* dest,
        const char* tag, const char* ns, const char* attr) {
    String8 tagStr(tag);
    ssize_t index = dest->indexOfKey(tagStr);

    if (index < 0) {
        Vector<NamespaceAttributePair> vector;
        vector.add(NamespaceAttributePair(ns, attr));
        dest->add(tagStr, vector);
    } else {
        dest->editValueAt(index).add(NamespaceAttributePair(ns, attr));
    }
}

status_t
writeProguardForLayouts(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
{
    status_t err;
    const char* kClass = "class";
    const char* kFragment = "fragment";
    const String8 kTransition("transition");
    const String8 kTransitionPrefix("transition-");

    // tag:attribute pairs that should be checked in layout files.
    KeyedVector<String8, Vector<NamespaceAttributePair> > kLayoutTagAttrPairs;
    addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, kClass);
    addTagAttrPair(&kLayoutTagAttrPairs, kFragment, NULL, kClass);
    addTagAttrPair(&kLayoutTagAttrPairs, kFragment, RESOURCES_ANDROID_NAMESPACE, "name");

    // tag:attribute pairs that should be checked in xml files.
    KeyedVector<String8, Vector<NamespaceAttributePair> > kXmlTagAttrPairs;
    addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, kFragment);
    addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, kFragment);

    // tag:attribute pairs that should be checked in transition files.
    KeyedVector<String8, Vector<NamespaceAttributePair> > kTransitionTagAttrPairs;
    addTagAttrPair(&kTransitionTagAttrPairs, kTransition.string(), NULL, kClass);
    addTagAttrPair(&kTransitionTagAttrPairs, "pathMotion", NULL, kClass);

    const Vector<sp<AaptDir> >& dirs = assets->resDirs();
    const size_t K = dirs.size();
    for (size_t k=0; k<K; k++) {
        const sp<AaptDir>& d = dirs.itemAt(k);
        const String8& dirName = d->getLeaf();
        Vector<String8> startTags;
        const KeyedVector<String8, Vector<NamespaceAttributePair> >* tagAttrPairs = NULL;
        if ((dirName == String8("layout")) || (strncmp(dirName.string(), "layout-", 7) == 0)) {
            tagAttrPairs = &kLayoutTagAttrPairs;
        } else if ((dirName == String8("xml")) || (strncmp(dirName.string(), "xml-", 4) == 0)) {
            startTags.add(String8("PreferenceScreen"));
            startTags.add(String8("preference-headers"));
            tagAttrPairs = &kXmlTagAttrPairs;
        } else if ((dirName == String8("menu")) || (strncmp(dirName.string(), "menu-", 5) == 0)) {
            startTags.add(String8("menu"));
            tagAttrPairs = NULL;
        } else if (dirName == kTransition || (strncmp(dirName.string(), kTransitionPrefix.string(),
                        kTransitionPrefix.size()) == 0)) {
            tagAttrPairs = &kTransitionTagAttrPairs;
        } else {
            continue;
        }

        const KeyedVector<String8,sp<AaptGroup> > groups = d->getFiles();
        const size_t N = groups.size();
        for (size_t i=0; i<N; i++) {
            const sp<AaptGroup>& group = groups.valueAt(i);
            const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& files = group->getFiles();
            const size_t M = files.size();
            for (size_t j=0; j<M; j++) {
                err = writeProguardForXml(keep, files.valueAt(j), startTags, tagAttrPairs);
                if (err < 0) {
                    return err;
                }
            }
        }
    }
    // Handle the overlays
    sp<AaptAssets> overlay = assets->getOverlay();
    if (overlay.get()) {
        return writeProguardForLayouts(keep, overlay);
    }

    return NO_ERROR;
}

status_t
writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)
{
    status_t err = -1;

    if (!bundle->getProguardFile()) {
        return NO_ERROR;
    }

    ProguardKeepSet keep;

    err = writeProguardForAndroidManifest(&keep, assets);
    if (err < 0) {
        return err;
    }

    err = writeProguardForLayouts(&keep, assets);
    if (err < 0) {
        return err;
    }

    FILE* fp = fopen(bundle->getProguardFile(), "w+");
    if (fp == NULL) {
        fprintf(stderr, "ERROR: Unable to open class file %s: %s\n",
                bundle->getProguardFile(), strerror(errno));
        return UNKNOWN_ERROR;
    }

    const KeyedVector<String8, SortedVector<String8> >& rules = keep.rules;
    const size_t N = rules.size();
    for (size_t i=0; i<N; i++) {
        const SortedVector<String8>& locations = rules.valueAt(i);
        const size_t M = locations.size();
        for (size_t j=0; j<M; j++) {
            fprintf(fp, "# %s\n", locations.itemAt(j).string());
        }
        fprintf(fp, "%s\n\n", rules.keyAt(i).string());
    }
    fclose(fp);

    return err;
}

// Loops through the string paths and writes them to the file pointer
// Each file path is written on its own line with a terminating backslash.
status_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)
{
    status_t deps = -1;
    for (size_t file_i = 0; file_i < files->size(); ++file_i) {
        // Add the full file path to the dependency file
        fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
        deps++;
    }
    return deps;
}

status_t
writeDependencyPreReqs(Bundle* /* bundle */, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
{
    status_t deps = -1;
    deps += writePathsToFile(assets->getFullResPaths(), fp);
    if (includeRaw) {
        deps += writePathsToFile(assets->getFullAssetPaths(), fp);
    }
    return deps;
}
