//
// Copyright 2006 The Android Open Source Project
//
// Build resource files from raw assets.
//

#include "ResourceTable.h"

#include "XMLNode.h"

#include <utils/ByteOrder.h>
#include <utils/ResourceTypes.h>
#include <stdarg.h>

#define NOISY(x) //x

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<AaptFile>& target,
                        ResourceTable* table,
                        int options)
{
    sp<XMLNode> root = XMLNode::parse(target);
    if (root == NULL) {
        return UNKNOWN_ERROR;
    }
    
    return compileXmlFile(assets, root, target, table, options);
}

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<AaptFile>& target,
                        const sp<AaptFile>& outTarget,
                        ResourceTable* table,
                        int options)
{
    sp<XMLNode> root = XMLNode::parse(target);
    if (root == NULL) {
        return UNKNOWN_ERROR;
    }
    
    return compileXmlFile(assets, root, outTarget, table, options);
}

status_t compileXmlFile(const sp<AaptAssets>& assets,
                        const sp<XMLNode>& root,
                        const sp<AaptFile>& target,
                        ResourceTable* table,
                        int options)
{
    if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
        root->removeWhitespace(true, NULL);
    } else  if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
        root->removeWhitespace(false, NULL);
    }

    if ((options&XML_COMPILE_UTF8) != 0) {
        root->setUTF8(true);
    }

    bool hasErrors = false;
    
    if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
        status_t err = root->assignResourceIds(assets, table);
        if (err != NO_ERROR) {
            hasErrors = true;
        }
    }

    status_t err = root->parseValues(assets, table);
    if (err != NO_ERROR) {
        hasErrors = true;
    }

    if (hasErrors) {
        return UNKNOWN_ERROR;
    }
    
    NOISY(printf("Input XML Resource:\n"));
    NOISY(root->print());
    err = root->flatten(target,
            (options&XML_COMPILE_STRIP_COMMENTS) != 0,
            (options&XML_COMPILE_STRIP_RAW_VALUES) != 0);
    if (err != NO_ERROR) {
        return err;
    }

    NOISY(printf("Output XML Resource:\n"));
    NOISY(ResXMLTree tree;
        tree.setTo(target->getData(), target->getSize());
        printXMLBlock(&tree));

    target->setCompressionMethod(ZipEntry::kCompressDeflated);
    
    return err;
}

#undef NOISY
#define NOISY(x) //x

struct flag_entry
{
    const char16_t* name;
    size_t nameLen;
    uint32_t value;
    const char* description;
};

static const char16_t referenceArray[] =
    { 'r', 'e', 'f', 'e', 'r', 'e', 'n', 'c', 'e' };
static const char16_t stringArray[] =
    { 's', 't', 'r', 'i', 'n', 'g' };
static const char16_t integerArray[] =
    { 'i', 'n', 't', 'e', 'g', 'e', 'r' };
static const char16_t booleanArray[] =
    { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
static const char16_t colorArray[] =
    { 'c', 'o', 'l', 'o', 'r' };
static const char16_t floatArray[] =
    { 'f', 'l', 'o', 'a', 't' };
static const char16_t dimensionArray[] =
    { 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n' };
static const char16_t fractionArray[] =
    { 'f', 'r', 'a', 'c', 't', 'i', 'o', 'n' };
static const char16_t enumArray[] =
    { 'e', 'n', 'u', 'm' };
static const char16_t flagsArray[] =
    { 'f', 'l', 'a', 'g', 's' };

static const flag_entry gFormatFlags[] = {
    { referenceArray, sizeof(referenceArray)/2, ResTable_map::TYPE_REFERENCE,
      "a reference to another resource, in the form \"<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>\"\n"
      "or to a theme attribute in the form \"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\"."},
    { stringArray, sizeof(stringArray)/2, ResTable_map::TYPE_STRING,
      "a string value, using '\\\\;' to escape characters such as '\\\\n' or '\\\\uxxxx' for a unicode character." },
    { integerArray, sizeof(integerArray)/2, ResTable_map::TYPE_INTEGER,
      "an integer value, such as \"<code>100</code>\"." },
    { booleanArray, sizeof(booleanArray)/2, ResTable_map::TYPE_BOOLEAN,
      "a boolean value, either \"<code>true</code>\" or \"<code>false</code>\"." },
    { colorArray, sizeof(colorArray)/2, ResTable_map::TYPE_COLOR,
      "a color value, in the form of \"<code>#<i>rgb</i></code>\", \"<code>#<i>argb</i></code>\",\n"
      "\"<code>#<i>rrggbb</i></code>\", or \"<code>#<i>aarrggbb</i></code>\"." },
    { floatArray, sizeof(floatArray)/2, ResTable_map::TYPE_FLOAT,
      "a floating point value, such as \"<code>1.2</code>\"."},
    { dimensionArray, sizeof(dimensionArray)/2, ResTable_map::TYPE_DIMENSION,
      "a dimension value, which is a floating point number appended with a unit such as \"<code>14.5sp</code>\".\n"
      "Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),\n"
      "in (inches), mm (millimeters)." },
    { fractionArray, sizeof(fractionArray)/2, ResTable_map::TYPE_FRACTION,
      "a fractional value, which is a floating point number appended with either % or %p, such as \"<code>14.5%</code>\".\n"
      "The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to\n"
      "some parent container." },
    { enumArray, sizeof(enumArray)/2, ResTable_map::TYPE_ENUM, NULL },
    { flagsArray, sizeof(flagsArray)/2, ResTable_map::TYPE_FLAGS, NULL },
    { NULL, 0, 0, NULL }
};

static const char16_t suggestedArray[] = { 's', 'u', 'g', 'g', 'e', 's', 't', 'e', 'd' };

static const flag_entry l10nRequiredFlags[] = {
    { suggestedArray, sizeof(suggestedArray)/2, ResTable_map::L10N_SUGGESTED, NULL },
    { NULL, 0, 0, NULL }
};

static const char16_t nulStr[] = { 0 };

static uint32_t parse_flags(const char16_t* str, size_t len,
                             const flag_entry* flags, bool* outError = NULL)
{
    while (len > 0 && isspace(*str)) {
        str++;
        len--;
    }
    while (len > 0 && isspace(str[len-1])) {
        len--;
    }

    const char16_t* const end = str + len;
    uint32_t value = 0;

    while (str < end) {
        const char16_t* div = str;
        while (div < end && *div != '|') {
            div++;
        }

        const flag_entry* cur = flags;
        while (cur->name) {
            if (strzcmp16(cur->name, cur->nameLen, str, div-str) == 0) {
                value |= cur->value;
                break;
            }
            cur++;
        }

        if (!cur->name) {
            if (outError) *outError = true;
            return 0;
        }

        str = div < end ? div+1 : div;
    }

    if (outError) *outError = false;
    return value;
}

static String16 mayOrMust(int type, int flags)
{
    if ((type&(~flags)) == 0) {
        return String16("<p>Must");
    }
    
    return String16("<p>May");
}

static void appendTypeInfo(ResourceTable* outTable, const String16& pkg,
        const String16& typeName, const String16& ident, int type,
        const flag_entry* flags)
{
    bool hadType = false;
    while (flags->name) {
        if ((type&flags->value) != 0 && flags->description != NULL) {
            String16 fullMsg(mayOrMust(type, flags->value));
            fullMsg.append(String16(" be "));
            fullMsg.append(String16(flags->description));
            outTable->appendTypeComment(pkg, typeName, ident, fullMsg);
            hadType = true;
        }
        flags++;
    }
    if (hadType && (type&ResTable_map::TYPE_REFERENCE) == 0) {
        outTable->appendTypeComment(pkg, typeName, ident,
                String16("<p>This may also be a reference to a resource (in the form\n"
                         "\"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>\") or\n"
                         "theme attribute (in the form\n"
                         "\"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>\")\n"
                         "containing a value of this type."));
    }
}

struct PendingAttribute
{
    const String16 myPackage;
    const SourcePos sourcePos;
    const bool appendComment;
    int32_t type;
    String16 ident;
    String16 comment;
    bool hasErrors;
    bool added;
    
    PendingAttribute(String16 _package, const sp<AaptFile>& in,
            ResXMLTree& block, bool _appendComment)
        : myPackage(_package)
        , sourcePos(in->getPrintableSource(), block.getLineNumber())
        , appendComment(_appendComment)
        , type(ResTable_map::TYPE_ANY)
        , hasErrors(false)
        , added(false)
    {
    }
    
    status_t createIfNeeded(ResourceTable* outTable)
    {
        if (added || hasErrors) {
            return NO_ERROR;
        }
        added = true;

        String16 attr16("attr");
        
        if (outTable->hasBagOrEntry(myPackage, attr16, ident)) {
            sourcePos.error("Attribute \"%s\" has already been defined\n",
                    String8(ident).string());
            hasErrors = true;
            return UNKNOWN_ERROR;
        }
        
        char numberStr[16];
        sprintf(numberStr, "%d", type);
        status_t err = outTable->addBag(sourcePos, myPackage,
                attr16, ident, String16(""),
                String16("^type"),
                String16(numberStr), NULL, NULL);
        if (err != NO_ERROR) {
            hasErrors = true;
            return err;
        }
        outTable->appendComment(myPackage, attr16, ident, comment, appendComment);
        //printf("Attribute %s comment: %s\n", String8(ident).string(),
        //     String8(comment).string());
        return err;
    }
};

static status_t compileAttribute(const sp<AaptFile>& in,
                                 ResXMLTree& block,
                                 const String16& myPackage,
                                 ResourceTable* outTable,
                                 String16* outIdent = NULL,
                                 bool inStyleable = false)
{
    PendingAttribute attr(myPackage, in, block, inStyleable);
    
    const String16 attr16("attr");
    const String16 id16("id");

    // Attribute type constants.
    const String16 enum16("enum");
    const String16 flag16("flag");

    ResXMLTree::event_code_t code;
    size_t len;
    status_t err;
    
    ssize_t identIdx = block.indexOfAttribute(NULL, "name");
    if (identIdx >= 0) {
        attr.ident = String16(block.getAttributeStringValue(identIdx, &len));
        if (outIdent) {
            *outIdent = attr.ident;
        }
    } else {
        attr.sourcePos.error("A 'name' attribute is required for <attr>\n");
        attr.hasErrors = true;
    }

    attr.comment = String16(
            block.getComment(&len) ? block.getComment(&len) : nulStr);

    ssize_t typeIdx = block.indexOfAttribute(NULL, "format");
    if (typeIdx >= 0) {
        String16 typeStr = String16(block.getAttributeStringValue(typeIdx, &len));
        attr.type = parse_flags(typeStr.string(), typeStr.size(), gFormatFlags);
        if (attr.type == 0) {
            attr.sourcePos.error("Tag <attr> 'format' attribute value \"%s\" not valid\n",
                    String8(typeStr).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
    } else if (!inStyleable) {
        // Attribute definitions outside of styleables always define the
        // attribute as a generic value.
        attr.createIfNeeded(outTable);
    }

    //printf("Attribute %s: type=0x%08x\n", String8(attr.ident).string(), attr.type);

    ssize_t minIdx = block.indexOfAttribute(NULL, "min");
    if (minIdx >= 0) {
        String16 val = String16(block.getAttributeStringValue(minIdx, &len));
        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
            attr.sourcePos.error("Tag <attr> 'min' attribute must be a number, not \"%s\"\n",
                    String8(val).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^min"), String16(val), NULL, NULL);
            if (err != NO_ERROR) {
                attr.hasErrors = true;
            }
        }
    }

    ssize_t maxIdx = block.indexOfAttribute(NULL, "max");
    if (maxIdx >= 0) {
        String16 val = String16(block.getAttributeStringValue(maxIdx, &len));
        if (!ResTable::stringToInt(val.string(), val.size(), NULL)) {
            attr.sourcePos.error("Tag <attr> 'max' attribute must be a number, not \"%s\"\n",
                    String8(val).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^max"), String16(val), NULL, NULL);
            attr.hasErrors = true;
        }
    }

    if ((minIdx >= 0 || maxIdx >= 0) && (attr.type&ResTable_map::TYPE_INTEGER) == 0) {
        attr.sourcePos.error("Tag <attr> must have format=integer attribute if using max or min\n");
        attr.hasErrors = true;
    }

    ssize_t l10nIdx = block.indexOfAttribute(NULL, "localization");
    if (l10nIdx >= 0) {
        const uint16_t* str = block.getAttributeStringValue(l10nIdx, &len);
        bool error;
        uint32_t l10n_required = parse_flags(str, len, l10nRequiredFlags, &error);
        if (error) {
            attr.sourcePos.error("Tag <attr> 'localization' attribute value \"%s\" not valid\n",
                    String8(str).string());
            attr.hasErrors = true;
        }
        attr.createIfNeeded(outTable);
        if (!attr.hasErrors) {
            char buf[11];
            sprintf(buf, "%d", l10n_required);
            err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                    String16(""), String16("^l10n"), String16(buf), NULL, NULL);
            if (err != NO_ERROR) {
                attr.hasErrors = true;
            }
        }
    }

    String16 enumOrFlagsComment;
    
    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            uint32_t localType = 0;
            if (strcmp16(block.getElementName(&len), enum16.string()) == 0) {
                localType = ResTable_map::TYPE_ENUM;
            } else if (strcmp16(block.getElementName(&len), flag16.string()) == 0) {
                localType = ResTable_map::TYPE_FLAGS;
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("Tag <%s> can not appear inside <attr>, only <enum> or <flag>\n",
                        String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }

            attr.createIfNeeded(outTable);
            
            if (attr.type == ResTable_map::TYPE_ANY) {
                // No type was explicitly stated, so supplying enum tags
                // implicitly creates an enum or flag.
                attr.type = 0;
            }

            if ((attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) == 0) {
                // Wasn't originally specified as an enum, so update its type.
                attr.type |= localType;
                if (!attr.hasErrors) {
                    char numberStr[16];
                    sprintf(numberStr, "%d", attr.type);
                    err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                            myPackage, attr16, attr.ident, String16(""),
                            String16("^type"), String16(numberStr), NULL, NULL, true);
                    if (err != NO_ERROR) {
                        attr.hasErrors = true;
                    }
                }
            } else if ((uint32_t)(attr.type&(ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS)) != localType) {
                if (localType == ResTable_map::TYPE_ENUM) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("<enum> attribute can not be used inside a flags format\n");
                    attr.hasErrors = true;
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("<flag> attribute can not be used inside a enum format\n");
                    attr.hasErrors = true;
                }
            }

            String16 itemIdent;
            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
            if (itemIdentIdx >= 0) {
                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("A 'name' attribute is required for <enum> or <flag>\n");
                attr.hasErrors = true;
            }

            String16 value;
            ssize_t valueIdx = block.indexOfAttribute(NULL, "value");
            if (valueIdx >= 0) {
                value = String16(block.getAttributeStringValue(valueIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("A 'value' attribute is required for <enum> or <flag>\n");
                attr.hasErrors = true;
            }
            if (!attr.hasErrors && !ResTable::stringToInt(value.string(), value.size(), NULL)) {
                SourcePos(in->getPrintableSource(), block.getLineNumber())
                        .error("Tag <enum> or <flag> 'value' attribute must be a number,"
                        " not \"%s\"\n",
                        String8(value).string());
                attr.hasErrors = true;
            }

            // Make sure an id is defined for this enum/flag identifier...
            if (!attr.hasErrors && !outTable->hasBagOrEntry(itemIdent, &id16, &myPackage)) {
                err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                                         myPackage, id16, itemIdent, String16(), NULL);
                if (err != NO_ERROR) {
                    attr.hasErrors = true;
                }
            }

            if (!attr.hasErrors) {
                if (enumOrFlagsComment.size() == 0) {
                    enumOrFlagsComment.append(mayOrMust(attr.type,
                            ResTable_map::TYPE_ENUM|ResTable_map::TYPE_FLAGS));
                    enumOrFlagsComment.append((attr.type&ResTable_map::TYPE_ENUM)
                                       ? String16(" be one of the following constant values.")
                                       : String16(" be one or more (separated by '|') of the following constant values."));
                    enumOrFlagsComment.append(String16("</p>\n<table>\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<colgroup align=\"left\" />\n"
                                                "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>"));
                }
                
                enumOrFlagsComment.append(String16("\n<tr><td><code>"));
                enumOrFlagsComment.append(itemIdent);
                enumOrFlagsComment.append(String16("</code></td><td>"));
                enumOrFlagsComment.append(value);
                enumOrFlagsComment.append(String16("</td><td>"));
                if (block.getComment(&len)) {
                    enumOrFlagsComment.append(String16(block.getComment(&len)));
                }
                enumOrFlagsComment.append(String16("</td></tr>"));
                
                err = outTable->addBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
                                       myPackage,
                                       attr16, attr.ident, String16(""),
                                       itemIdent, value, NULL, NULL, false, true);
                if (err != NO_ERROR) {
                    attr.hasErrors = true;
                }
            }
        } else if (code == ResXMLTree::END_TAG) {
            if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
                break;
            }
            if ((attr.type&ResTable_map::TYPE_ENUM) != 0) {
                if (strcmp16(block.getElementName(&len), enum16.string()) != 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("Found tag </%s> where </enum> is expected\n",
                            String8(block.getElementName(&len)).string());
                    return UNKNOWN_ERROR;
                }
            } else {
                if (strcmp16(block.getElementName(&len), flag16.string()) != 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber())
                            .error("Found tag </%s> where </flag> is expected\n",
                            String8(block.getElementName(&len)).string());
                    return UNKNOWN_ERROR;
                }
            }
        }
    }
    
    if (!attr.hasErrors && attr.added) {
        appendTypeInfo(outTable, myPackage, attr16, attr.ident, attr.type, gFormatFlags);
    }
    
    if (!attr.hasErrors && enumOrFlagsComment.size() > 0) {
        enumOrFlagsComment.append(String16("\n</table>"));
        outTable->appendTypeComment(myPackage, attr16, attr.ident, enumOrFlagsComment);
    }


    return NO_ERROR;
}

bool localeIsDefined(const ResTable_config& config)
{
    return config.locale == 0;
}

status_t parseAndAddBag(Bundle* bundle,
                        const sp<AaptFile>& in,
                        ResXMLTree* block,
                        const ResTable_config& config,
                        const String16& myPackage,
                        const String16& curType,
                        const String16& ident,
                        const String16& parentIdent,
                        const String16& itemIdent,
                        int32_t curFormat,
                        bool isFormatted,
                        bool pseudolocalize,
                        const bool overwrite,
                        ResourceTable* outTable)
{
    status_t err;
    const String16 item16("item");
    
    String16 str;
    Vector<StringPool::entry_style_span> spans;
    err = parseStyledString(bundle, in->getPrintableSource().string(),
                            block, item16, &str, &spans, isFormatted,
                            pseudolocalize);
    if (err != NO_ERROR) {
        return err;
    }
    
    NOISY(printf("Adding resource bag entry l=%c%c c=%c%c orien=%d d=%d "
                 " pid=%s, bag=%s, id=%s: %s\n",
                 config.language[0], config.language[1],
                 config.country[0], config.country[1],
                 config.orientation, config.density,
                 String8(parentIdent).string(),
                 String8(ident).string(),
                 String8(itemIdent).string(),
                 String8(str).string()));

    err = outTable->addBag(SourcePos(in->getPrintableSource(), block->getLineNumber()),
                           myPackage, curType, ident, parentIdent, itemIdent, str,
                           &spans, &config, overwrite, false, curFormat);
    return err;
}


status_t parseAndAddEntry(Bundle* bundle,
                        const sp<AaptFile>& in,
                        ResXMLTree* block,
                        const ResTable_config& config,
                        const String16& myPackage,
                        const String16& curType,
                        const String16& ident,
                        const String16& curTag,
                        bool curIsStyled,
                        int32_t curFormat,
                        bool isFormatted,
                        bool pseudolocalize,
                        const bool overwrite,
                        ResourceTable* outTable)
{
    status_t err;

    String16 str;
    Vector<StringPool::entry_style_span> spans;
    err = parseStyledString(bundle, in->getPrintableSource().string(), block,
                            curTag, &str, curIsStyled ? &spans : NULL,
                            isFormatted, pseudolocalize);

    if (err < NO_ERROR) { 
        return err;
    }

    NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
                 config.language[0], config.language[1],
                 config.country[0], config.country[1],
                 config.orientation, config.density,
                 String8(ident).string(), String8(str).string()));

    err = outTable->addEntry(SourcePos(in->getPrintableSource(), block->getLineNumber()),
                             myPackage, curType, ident, str, &spans, &config,
                             false, curFormat, overwrite);

    return err;
}

status_t compileResourceFile(Bundle* bundle,
                             const sp<AaptAssets>& assets,
                             const sp<AaptFile>& in,
                             const ResTable_config& defParams,
                             const bool overwrite,
                             ResourceTable* outTable)
{
    ResXMLTree block;
    status_t err = parseXMLResource(in, &block, false, true);
    if (err != NO_ERROR) {
        return err;
    }

    // Top-level tag.
    const String16 resources16("resources");

    // Identifier declaration tags.
    const String16 declare_styleable16("declare-styleable");
    const String16 attr16("attr");

    // Data creation organizational tags.
    const String16 string16("string");
    const String16 drawable16("drawable");
    const String16 color16("color");
    const String16 bool16("bool");
    const String16 integer16("integer");
    const String16 dimen16("dimen");
    const String16 fraction16("fraction");
    const String16 style16("style");
    const String16 plurals16("plurals");
    const String16 array16("array");
    const String16 string_array16("string-array");
    const String16 integer_array16("integer-array");
    const String16 public16("public");
    const String16 public_padding16("public-padding");
    const String16 private_symbols16("private-symbols");
    const String16 add_resource16("add-resource");
    const String16 skip16("skip");
    const String16 eat_comment16("eat-comment");

    // Data creation tags.
    const String16 bag16("bag");
    const String16 item16("item");

    // Attribute type constants.
    const String16 enum16("enum");

    // plural values
    const String16 other16("other");
    const String16 quantityOther16("^other");
    const String16 zero16("zero");
    const String16 quantityZero16("^zero");
    const String16 one16("one");
    const String16 quantityOne16("^one");
    const String16 two16("two");
    const String16 quantityTwo16("^two");
    const String16 few16("few");
    const String16 quantityFew16("^few");
    const String16 many16("many");
    const String16 quantityMany16("^many");

    // useful attribute names and special values
    const String16 name16("name");
    const String16 translatable16("translatable");
    const String16 formatted16("formatted");
    const String16 false16("false");

    const String16 myPackage(assets->getPackage());

    bool hasErrors = false;

    bool fileIsTranslatable = true;
    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
        fileIsTranslatable = false;
    }

    DefaultKeyedVector<String16, uint32_t> nextPublicId(0);

    ResXMLTree::event_code_t code;
    do {
        code = block.next();
    } while (code == ResXMLTree::START_NAMESPACE);

    size_t len;
    if (code != ResXMLTree::START_TAG) {
        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                "No start tag found\n");
        return UNKNOWN_ERROR;
    }
    if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                "Invalid start tag %s\n", String8(block.getElementName(&len)).string());
        return UNKNOWN_ERROR;
    }

    ResTable_config curParams(defParams);

    ResTable_config pseudoParams(curParams);
        pseudoParams.language[0] = 'z';
        pseudoParams.language[1] = 'z';
        pseudoParams.country[0] = 'Z';
        pseudoParams.country[1] = 'Z';

    while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
        if (code == ResXMLTree::START_TAG) {
            const String16* curTag = NULL;
            String16 curType;
            int32_t curFormat = ResTable_map::TYPE_ANY;
            bool curIsBag = false;
            bool curIsBagReplaceOnOverwrite = false;
            bool curIsStyled = false;
            bool curIsPseudolocalizable = false;
            bool curIsFormatted = fileIsTranslatable;
            bool localHasErrors = false;

            if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 type;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <public>\n");
                    hasErrors = localHasErrors = true;
                }
                type = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <public>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                uint32_t ident = 0;
                ssize_t identIdx = block.indexOfAttribute(NULL, "id");
                if (identIdx >= 0) {
                    const char16_t* identStr = block.getAttributeStringValue(identIdx, &len);
                    Res_value identValue;
                    if (!ResTable::stringToInt(identStr, len, &identValue)) {
                        srcPos.error("Given 'id' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(identIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        ident = identValue.data;
                        nextPublicId.replaceValueFor(type, ident+1);
                    }
                } else if (nextPublicId.indexOfKey(type) < 0) {
                    srcPos.error("No 'id' attribute supplied <public>,"
                            " and no previous id defined in this file.\n");
                    hasErrors = localHasErrors = true;
                } else if (!localHasErrors) {
                    ident = nextPublicId.valueFor(type);
                    nextPublicId.replaceValueFor(type, ident+1);
                }

                if (!localHasErrors) {
                    err = outTable->addPublic(srcPos, myPackage, type, name, ident);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                    }
                }
                if (!localHasErrors) {
                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
                    }
                    if (symbols != NULL) {
                        symbols->makeSymbolPublic(String8(name), srcPos);
                        String16 comment(
                            block.getComment(&len) ? block.getComment(&len) : nulStr);
                        symbols->appendComment(String8(name), comment, srcPos);
                    } else {
                        srcPos.error("Unable to create symbols!\n");
                        hasErrors = localHasErrors = true;
                    }
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), public16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 type;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }
                type = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                uint32_t start = 0;
                ssize_t startIdx = block.indexOfAttribute(NULL, "start");
                if (startIdx >= 0) {
                    const char16_t* startStr = block.getAttributeStringValue(startIdx, &len);
                    Res_value startValue;
                    if (!ResTable::stringToInt(startStr, len, &startValue)) {
                        srcPos.error("Given 'start' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(startIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        start = startValue.data;
                    }
                } else if (nextPublicId.indexOfKey(type) < 0) {
                    srcPos.error("No 'start' attribute supplied <public-padding>,"
                            " and no previous id defined in this file.\n");
                    hasErrors = localHasErrors = true;
                } else if (!localHasErrors) {
                    start = nextPublicId.valueFor(type);
                }

                uint32_t end = 0;
                ssize_t endIdx = block.indexOfAttribute(NULL, "end");
                if (endIdx >= 0) {
                    const char16_t* endStr = block.getAttributeStringValue(endIdx, &len);
                    Res_value endValue;
                    if (!ResTable::stringToInt(endStr, len, &endValue)) {
                        srcPos.error("Given 'end' attribute is not an integer: %s\n",
                                String8(block.getAttributeStringValue(endIdx, &len)).string());
                        hasErrors = localHasErrors = true;
                    } else {
                        end = endValue.data;
                    }
                } else {
                    srcPos.error("No 'end' attribute supplied <public-padding>\n");
                    hasErrors = localHasErrors = true;
                }

                if (end >= start) {
                    nextPublicId.replaceValueFor(type, end+1);
                } else {
                    srcPos.error("Padding start '%ul' is after end '%ul'\n",
                            start, end);
                    hasErrors = localHasErrors = true;
                }
                
                String16 comment(
                    block.getComment(&len) ? block.getComment(&len) : nulStr);
                for (uint32_t curIdent=start; curIdent<=end; curIdent++) {
                    if (localHasErrors) {
                        break;
                    }
                    String16 curName(name);
                    char buf[64];
                    sprintf(buf, "%d", (int)(end-curIdent+1));
                    curName.append(String16(buf));
                    
                    err = outTable->addEntry(srcPos, myPackage, type, curName,
                                             String16("padding"), NULL, &curParams, false,
                                             ResTable_map::TYPE_STRING, overwrite);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                        break;
                    }
                    err = outTable->addPublic(srcPos, myPackage, type,
                            curName, curIdent);
                    if (err < NO_ERROR) {
                        hasErrors = localHasErrors = true;
                        break;
                    }
                    sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(type), srcPos);
                    }
                    if (symbols != NULL) {
                        symbols->makeSymbolPublic(String8(curName), srcPos);
                        symbols->appendComment(String8(curName), comment, srcPos);
                    } else {
                        srcPos.error("Unable to create symbols!\n");
                        hasErrors = localHasErrors = true;
                    }
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), public_padding16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
                String16 pkg;
                ssize_t pkgIdx = block.indexOfAttribute(NULL, "package");
                if (pkgIdx < 0) {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'package' attribute is required for <private-symbols>\n");
                    hasErrors = localHasErrors = true;
                }
                pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
                if (!localHasErrors) {
                    assets->setSymbolsPrivatePackage(String8(pkg));
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
            
                String16 typeName;
                ssize_t typeIdx = block.indexOfAttribute(NULL, "type");
                if (typeIdx < 0) {
                    srcPos.error("A 'type' attribute is required for <add-resource>\n");
                    hasErrors = localHasErrors = true;
                }
                typeName = String16(block.getAttributeStringValue(typeIdx, &len));

                String16 name;
                ssize_t nameIdx = block.indexOfAttribute(NULL, "name");
                if (nameIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <add-resource>\n");
                    hasErrors = localHasErrors = true;
                }
                name = String16(block.getAttributeStringValue(nameIdx, &len));

                outTable->canAddEntry(srcPos, myPackage, typeName, name);

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
                            break;
                        }
                    }
                }
                continue;
                
            } else if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
                SourcePos srcPos(in->getPrintableSource(), block.getLineNumber());
                                
                String16 ident;
                ssize_t identIdx = block.indexOfAttribute(NULL, "name");
                if (identIdx < 0) {
                    srcPos.error("A 'name' attribute is required for <declare-styleable>\n");
                    hasErrors = localHasErrors = true;
                }
                ident = String16(block.getAttributeStringValue(identIdx, &len));

                sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
                if (!localHasErrors) {
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8("styleable"), srcPos);
                    }
                    sp<AaptSymbols> styleSymbols = symbols;
                    if (symbols != NULL) {
                        symbols = symbols->addNestedSymbol(String8(ident), srcPos);
                    }
                    if (symbols == NULL) {
                        srcPos.error("Unable to create symbols!\n");
                        return UNKNOWN_ERROR;
                    }
                    
                    String16 comment(
                        block.getComment(&len) ? block.getComment(&len) : nulStr);
                    styleSymbols->appendComment(String8(ident), comment, srcPos);
                } else {
                    symbols = NULL;
                }

                while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                    if (code == ResXMLTree::START_TAG) {
                        if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                                   && code != ResXMLTree::BAD_DOCUMENT) {
                                if (code == ResXMLTree::END_TAG) {
                                    if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
                                        break;
                                    }
                                }
                            }
                            continue;
                        } else if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                            while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                                   && code != ResXMLTree::BAD_DOCUMENT) {
                                if (code == ResXMLTree::END_TAG) {
                                    if (strcmp16(block.getElementName(&len), eat_comment16.string()) == 0) {
                                        break;
                                    }
                                }
                            }
                            continue;
                        } else if (strcmp16(block.getElementName(&len), attr16.string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <%s> can not appear inside <declare-styleable>, only <attr>\n",
                                    String8(block.getElementName(&len)).string());
                            return UNKNOWN_ERROR;
                        }

                        String16 comment(
                            block.getComment(&len) ? block.getComment(&len) : nulStr);
                        String16 itemIdent;
                        err = compileAttribute(in, block, myPackage, outTable, &itemIdent, true);
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }

                        if (symbols != NULL) {
                            SourcePos srcPos(String8(in->getPrintableSource()), block.getLineNumber());
                            symbols->addSymbol(String8(itemIdent), 0, srcPos);
                            symbols->appendComment(String8(itemIdent), comment, srcPos);
                            //printf("Attribute %s comment: %s\n", String8(itemIdent).string(),
                            //     String8(comment).string());
                        }
                    } else if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), declare_styleable16.string()) == 0) {
                            break;
                        }

                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                "Found tag </%s> where </attr> is expected\n",
                                String8(block.getElementName(&len)).string());
                        return UNKNOWN_ERROR;
                    }
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), attr16.string()) == 0) {
                err = compileAttribute(in, block, myPackage, outTable, NULL);
                if (err != NO_ERROR) {
                    hasErrors = true;
                }
                continue;

            } else if (strcmp16(block.getElementName(&len), item16.string()) == 0) {
                curTag = &item16;
                ssize_t attri = block.indexOfAttribute(NULL, "type");
                if (attri >= 0) {
                    curType = String16(block.getAttributeStringValue(attri, &len));
                    ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
                    if (formatIdx >= 0) {
                        String16 formatStr = String16(block.getAttributeStringValue(
                                formatIdx, &len));
                        curFormat = parse_flags(formatStr.string(), formatStr.size(),
                                                gFormatFlags);
                        if (curFormat == 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <item> 'format' attribute value \"%s\" not valid\n",
                                    String8(formatStr).string());
                            hasErrors = localHasErrors = true;
                        }
                    }
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'type' attribute is required for <item>\n");
                    hasErrors = localHasErrors = true;
                }
                curIsStyled = true;
            } else if (strcmp16(block.getElementName(&len), string16.string()) == 0) {
                // Note the existence and locale of every string we process
                char rawLocale[16];
                curParams.getLocale(rawLocale);
                String8 locale(rawLocale);
                String16 name;
                String16 translatable;
                String16 formatted;

                size_t n = block.getAttributeCount();
                for (size_t i = 0; i < n; i++) {
                    size_t length;
                    const uint16_t* attr = block.getAttributeName(i, &length);
                    if (strcmp16(attr, name16.string()) == 0) {
                        name.setTo(block.getAttributeStringValue(i, &length));
                    } else if (strcmp16(attr, translatable16.string()) == 0) {
                        translatable.setTo(block.getAttributeStringValue(i, &length));
                    } else if (strcmp16(attr, formatted16.string()) == 0) {
                        formatted.setTo(block.getAttributeStringValue(i, &length));
                    }
                }
                
                if (name.size() > 0) {
                    if (translatable == false16) {
                        curIsFormatted = false;
                        // Untranslatable strings must only exist in the default [empty] locale
                        if (locale.size() > 0) {
                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
                                    " in locale '%s'\n", String8(name).string(),
                                    bundle->getResourceSourceDirs()[0],
                                    locale.string());
                            // hasErrors = localHasErrors = true;
                        } else {
                            // Intentionally empty block:
                            //
                            // Don't add untranslatable strings to the localization table; that
                            // way if we later see localizations of them, they'll be flagged as
                            // having no default translation.
                        }
                    } else {
                        outTable->addLocalization(name, locale);
                    }

                    if (formatted == false16) {
                        curIsFormatted = false;
                    }
                }

                curTag = &string16;
                curType = string16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
                curIsStyled = true;
                curIsPseudolocalizable = true;
            } else if (strcmp16(block.getElementName(&len), drawable16.string()) == 0) {
                curTag = &drawable16;
                curType = drawable16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
            } else if (strcmp16(block.getElementName(&len), color16.string()) == 0) {
                curTag = &color16;
                curType = color16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_COLOR;
            } else if (strcmp16(block.getElementName(&len), bool16.string()) == 0) {
                curTag = &bool16;
                curType = bool16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_BOOLEAN;
            } else if (strcmp16(block.getElementName(&len), integer16.string()) == 0) {
                curTag = &integer16;
                curType = integer16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
            } else if (strcmp16(block.getElementName(&len), dimen16.string()) == 0) {
                curTag = &dimen16;
                curType = dimen16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_DIMENSION;
            } else if (strcmp16(block.getElementName(&len), fraction16.string()) == 0) {
                curTag = &fraction16;
                curType = fraction16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_FRACTION;
            } else if (strcmp16(block.getElementName(&len), bag16.string()) == 0) {
                curTag = &bag16;
                curIsBag = true;
                ssize_t attri = block.indexOfAttribute(NULL, "type");
                if (attri >= 0) {
                    curType = String16(block.getAttributeStringValue(attri, &len));
                } else {
                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                            "A 'type' attribute is required for <bag>\n");
                    hasErrors = localHasErrors = true;
                }
            } else if (strcmp16(block.getElementName(&len), style16.string()) == 0) {
                curTag = &style16;
                curType = style16;
                curIsBag = true;
            } else if (strcmp16(block.getElementName(&len), plurals16.string()) == 0) {
                curTag = &plurals16;
                curType = plurals16;
                curIsBag = true;
            } else if (strcmp16(block.getElementName(&len), array16.string()) == 0) {
                curTag = &array16;
                curType = array16;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
                ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
                if (formatIdx >= 0) {
                    String16 formatStr = String16(block.getAttributeStringValue(
                            formatIdx, &len));
                    curFormat = parse_flags(formatStr.string(), formatStr.size(),
                                            gFormatFlags);
                    if (curFormat == 0) {
                        SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                "Tag <array> 'format' attribute value \"%s\" not valid\n",
                                String8(formatStr).string());
                        hasErrors = localHasErrors = true;
                    }
                }
            } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
                curTag = &string_array16;
                curType = array16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
                curIsPseudolocalizable = true;
            } else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
                curTag = &integer_array16;
                curType = array16;
                curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
                curIsBag = true;
                curIsBagReplaceOnOverwrite = true;
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "Found tag %s where item is expected\n",
                        String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }

            String16 ident;
            ssize_t identIdx = block.indexOfAttribute(NULL, "name");
            if (identIdx >= 0) {
                ident = String16(block.getAttributeStringValue(identIdx, &len));
            } else {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "A 'name' attribute is required for <%s>\n",
                        String8(*curTag).string());
                hasErrors = localHasErrors = true;
            }

            String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr);
            
            if (curIsBag) {
                // Figure out the parent of this bag...
                String16 parentIdent;
                ssize_t parentIdentIdx = block.indexOfAttribute(NULL, "parent");
                if (parentIdentIdx >= 0) {
                    parentIdent = String16(block.getAttributeStringValue(parentIdentIdx, &len));
                } else {
                    ssize_t sep = ident.findLast('.');
                    if (sep >= 0) {
                        parentIdent.setTo(ident, sep);
                    }
                }

                if (!localHasErrors) {
                    err = outTable->startBag(SourcePos(in->getPrintableSource(),
                            block.getLineNumber()), myPackage, curType, ident,
                            parentIdent, &curParams,
                            overwrite, curIsBagReplaceOnOverwrite);
                    if (err != NO_ERROR) {
                        hasErrors = localHasErrors = true;
                    }
                }
                
                ssize_t elmIndex = 0;
                char elmIndexStr[14];
                while ((code=block.next()) != ResXMLTree::END_DOCUMENT
                        && code != ResXMLTree::BAD_DOCUMENT) {

                    if (code == ResXMLTree::START_TAG) {
                        if (strcmp16(block.getElementName(&len), item16.string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Tag <%s> can not appear inside <%s>, only <item>\n",
                                    String8(block.getElementName(&len)).string(),
                                    String8(*curTag).string());
                            return UNKNOWN_ERROR;
                        }

                        String16 itemIdent;
                        if (curType == array16) {
                            sprintf(elmIndexStr, "^index_%d", (int)elmIndex++);
                            itemIdent = String16(elmIndexStr);
                        } else if (curType == plurals16) {
                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "quantity");
                            if (itemIdentIdx >= 0) {
                                String16 quantity16(block.getAttributeStringValue(itemIdentIdx, &len));
                                if (quantity16 == other16) {
                                    itemIdent = quantityOther16;
                                }
                                else if (quantity16 == zero16) {
                                    itemIdent = quantityZero16;
                                }
                                else if (quantity16 == one16) {
                                    itemIdent = quantityOne16;
                                }
                                else if (quantity16 == two16) {
                                    itemIdent = quantityTwo16;
                                }
                                else if (quantity16 == few16) {
                                    itemIdent = quantityFew16;
                                }
                                else if (quantity16 == many16) {
                                    itemIdent = quantityMany16;
                                }
                                else {
                                    SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                            "Illegal 'quantity' attribute is <item> inside <plurals>\n");
                                    hasErrors = localHasErrors = true;
                                }
                            } else {
                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                        "A 'quantity' attribute is required for <item> inside <plurals>\n");
                                hasErrors = localHasErrors = true;
                            }
                        } else {
                            ssize_t itemIdentIdx = block.indexOfAttribute(NULL, "name");
                            if (itemIdentIdx >= 0) {
                                itemIdent = String16(block.getAttributeStringValue(itemIdentIdx, &len));
                            } else {
                                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                        "A 'name' attribute is required for <item>\n");
                                hasErrors = localHasErrors = true;
                            }
                        }

                        ResXMLParser::ResXMLPosition parserPosition;
                        block.getPosition(&parserPosition);

                        err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
                                false, overwrite, outTable);
                        if (err == NO_ERROR) {
                            if (curIsPseudolocalizable && localeIsDefined(curParams)
                                    && bundle->getPseudolocalize()) {
                                // pseudolocalize here
#if 1
                                block.setPosition(parserPosition);
                                err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
                                        curType, ident, parentIdent, itemIdent, curFormat,
                                        curIsFormatted, true, overwrite, outTable);
#endif
                            }
                        } 
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }
                    } else if (code == ResXMLTree::END_TAG) {
                        if (strcmp16(block.getElementName(&len), curTag->string()) != 0) {
                            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                                    "Found tag </%s> where </%s> is expected\n",
                                    String8(block.getElementName(&len)).string(),
                                    String8(*curTag).string());
                            return UNKNOWN_ERROR;
                        }
                        break;
                    }
                }
            } else {
                ResXMLParser::ResXMLPosition parserPosition;
                block.getPosition(&parserPosition);

                err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
                        *curTag, curIsStyled, curFormat, curIsFormatted,
                        false, overwrite, outTable);

                if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
                    hasErrors = localHasErrors = true;
                }
                else if (err == NO_ERROR) {
                    if (curIsPseudolocalizable && localeIsDefined(curParams)
                            && bundle->getPseudolocalize()) {
                        // pseudolocalize here
                        block.setPosition(parserPosition);
                        err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
                                ident, *curTag, curIsStyled, curFormat,
                                curIsFormatted, true, overwrite, outTable);
                        if (err != NO_ERROR) {
                            hasErrors = localHasErrors = true;
                        }
                    }
                }
            }

#if 0
            if (comment.size() > 0) {
                printf("Comment for @%s:%s/%s: %s\n", String8(myPackage).string(),
                       String8(curType).string(), String8(ident).string(),
                       String8(comment).string());
            }
#endif
            if (!localHasErrors) {
                outTable->appendComment(myPackage, curType, ident, comment, false);
            }
        }
        else if (code == ResXMLTree::END_TAG) {
            if (strcmp16(block.getElementName(&len), resources16.string()) != 0) {
                SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                        "Unexpected end tag %s\n", String8(block.getElementName(&len)).string());
                return UNKNOWN_ERROR;
            }
        }
        else if (code == ResXMLTree::START_NAMESPACE || code == ResXMLTree::END_NAMESPACE) {
        }
        else if (code == ResXMLTree::TEXT) {
            if (isWhitespace(block.getText(&len))) {
                continue;
            }
            SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
                    "Found text \"%s\" where item tag is expected\n",
                    String8(block.getText(&len)).string());
            return UNKNOWN_ERROR;
        }
    }

    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

ResourceTable::ResourceTable(Bundle* bundle, const String16& assetsPackage)
    : mAssetsPackage(assetsPackage), mNextPackageId(1), mHaveAppPackage(false),
      mIsAppPackage(!bundle->getExtending()),
      mNumLocal(0),
      mBundle(bundle)
{
}

status_t ResourceTable::addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets)
{
    status_t err = assets->buildIncludedResources(bundle);
    if (err != NO_ERROR) {
        return err;
    }

    // For future reference to included resources.
    mAssets = assets;

    const ResTable& incl = assets->getIncludedResources();

    // Retrieve all the packages.
    const size_t N = incl.getBasePackageCount();
    for (size_t phase=0; phase<2; phase++) {
        for (size_t i=0; i<N; i++) {
            String16 name(incl.getBasePackageName(i));
            uint32_t id = incl.getBasePackageId(i);
            // First time through: only add base packages (id
            // is not 0); second time through add the other
            // packages.
            if (phase != 0) {
                if (id != 0) {
                    // Skip base packages -- already one.
                    id = 0;
                } else {
                    // Assign a dynamic id.
                    id = mNextPackageId;
                }
            } else if (id != 0) {
                if (id == 127) {
                    if (mHaveAppPackage) {
                        fprintf(stderr, "Included resources have two application packages!\n");
                        return UNKNOWN_ERROR;
                    }
                    mHaveAppPackage = true;
                }
                if (mNextPackageId > id) {
                    fprintf(stderr, "Included base package ID %d already in use!\n", id);
                    return UNKNOWN_ERROR;
                }
            }
            if (id != 0) {
                NOISY(printf("Including package %s with ID=%d\n",
                             String8(name).string(), id));
                sp<Package> p = new Package(name, id);
                mPackages.add(name, p);
                mOrderedPackages.add(p);

                if (id >= mNextPackageId) {
                    mNextPackageId = id+1;
                }
            }
        }
    }

    // Every resource table always has one first entry, the bag attributes.
    const SourcePos unknown(String8("????"), 0);
    sp<Type> attr = getType(mAssetsPackage, String16("attr"), unknown);

    return NO_ERROR;
}

status_t ResourceTable::addPublic(const SourcePos& sourcePos,
                                  const String16& package,
                                  const String16& type,
                                  const String16& name,
                                  const uint32_t ident)
{
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        sourcePos.error("Error declaring public resource %s/%s for included package %s\n",
                String8(type).string(), String8(name).string(),
                String8(package).string());
        return UNKNOWN_ERROR;
    }

    sp<Type> t = getType(package, type, sourcePos);
    if (t == NULL) {
        return UNKNOWN_ERROR;
    }
    return t->addPublic(sourcePos, name, ident);
}

status_t ResourceTable::addEntry(const SourcePos& sourcePos,
                                 const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 const String16& value,
                                 const Vector<StringPool::entry_style_span>* style,
                                 const ResTable_config* params,
                                 const bool doSetIndex,
                                 const int32_t format,
                                 const bool overwrite)
{
    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }
    
#if 0
    if (name == String16("left")) {
        printf("Adding entry left: file=%s, line=%d, type=%s, value=%s\n",
               sourcePos.file.string(), sourcePos.line, String8(type).string(),
               String8(value).string());
    }
#endif

    sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
                           params, doSetIndex);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }
    status_t err = e->setItem(sourcePos, value, style, format, overwrite);
    if (err == NO_ERROR) {
        mNumLocal++;
    }
    return err;
}

status_t ResourceTable::startBag(const SourcePos& sourcePos,
                                 const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 const String16& bagParent,
                                 const ResTable_config* params,
                                 bool overlay,
                                 bool replace, bool isId)
{
    status_t result = NO_ERROR;

    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
    .identifierForName(name.string(), name.size(),
                       type.string(), type.size(),
                       package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }
    
#if 0
    if (name == String16("left")) {
        printf("Adding bag left: file=%s, line=%d, type=%s\n",
               sourcePos.file.striing(), sourcePos.line, String8(type).string());
    }
#endif
    if (overlay && !mBundle->getAutoAddOverlay() && !hasBagOrEntry(package, type, name)) {
        bool canAdd = false;
        sp<Package> p = mPackages.valueFor(package);
        if (p != NULL) {
            sp<Type> t = p->getTypes().valueFor(type);
            if (t != NULL) {
                if (t->getCanAddEntries().indexOf(name) >= 0) {
                    canAdd = true;
                }
            }
        }
        if (!canAdd) {
            sourcePos.error("Resource does not already exist in overlay at '%s'; use <add-resource> to add.\n",
                            String8(name).string());
            return UNKNOWN_ERROR;
        }
    }
    sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }
    
    // If a parent is explicitly specified, set it.
    if (bagParent.size() > 0) {
        String16 curPar = e->getParent();
        if (curPar.size() > 0 && curPar != bagParent) {
            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
                            String8(e->getParent()).string(),
                            String8(bagParent).string());
            return UNKNOWN_ERROR;
        }
        e->setParent(bagParent);
    }

    if ((result = e->makeItABag(sourcePos)) != NO_ERROR) {
        return result;
    }

    if (overlay && replace) { 
        return e->emptyBag(sourcePos);
    }
    return result;
}

status_t ResourceTable::addBag(const SourcePos& sourcePos,
                               const String16& package,
                               const String16& type,
                               const String16& name,
                               const String16& bagParent,
                               const String16& bagKey,
                               const String16& value,
                               const Vector<StringPool::entry_style_span>* style,
                               const ResTable_config* params,
                               bool replace, bool isId, const int32_t format)
{
    // Check for adding entries in other packages...  for now we do
    // nothing.  We need to do the right thing here to support skinning.
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return NO_ERROR;
    }

#if 0
    if (name == String16("left")) {
        printf("Adding bag left: file=%s, line=%d, type=%s\n",
               sourcePos.file.striing(), sourcePos.line, String8(type).string());
    }
#endif
    sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
    if (e == NULL) {
        return UNKNOWN_ERROR;
    }

    // If a parent is explicitly specified, set it.
    if (bagParent.size() > 0) {
        String16 curPar = e->getParent();
        if (curPar.size() > 0 && curPar != bagParent) {
            sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n",
                    String8(e->getParent()).string(),
                    String8(bagParent).string());
            return UNKNOWN_ERROR;
        }
        e->setParent(bagParent);
    }

    const bool first = e->getBag().indexOfKey(bagKey) < 0;
    status_t err = e->addToBag(sourcePos, bagKey, value, style, replace, isId, format);
    if (err == NO_ERROR && first) {
        mNumLocal++;
    }
    return err;
}

bool ResourceTable::hasBagOrEntry(const String16& package,
                                  const String16& type,
                                  const String16& name) const
{
    // First look for this in the included resources...
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size());
    if (rid != 0) {
        return true;
    }

    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) return true;
        }
    }

    return false;
}

bool ResourceTable::hasBagOrEntry(const String16& ref,
                                  const String16* defType,
                                  const String16* defPackage)
{
    String16 package, type, name;
    if (!ResTable::expandResourceRef(ref.string(), ref.size(), &package, &type, &name,
                defType, defPackage ? defPackage:&mAssetsPackage, NULL)) {
        return false;
    }
    return hasBagOrEntry(package, type, name);
}

bool ResourceTable::appendComment(const String16& package,
                                  const String16& type,
                                  const String16& name,
                                  const String16& comment,
                                  bool onlyIfEmpty)
{
    if (comment.size() <= 0) {
        return true;
    }

    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) {
                c->appendComment(comment, onlyIfEmpty);
                return true;
            }
        }
    }
    return false;
}

bool ResourceTable::appendTypeComment(const String16& package,
                                      const String16& type,
                                      const String16& name,
                                      const String16& comment)
{
    if (comment.size() <= 0) {
        return true;
    }
    
    sp<Package> p = mPackages.valueFor(package);
    if (p != NULL) {
        sp<Type> t = p->getTypes().valueFor(type);
        if (t != NULL) {
            sp<ConfigList> c =  t->getConfigs().valueFor(name);
            if (c != NULL) {
                c->appendTypeComment(comment);
                return true;
            }
        }
    }
    return false;
}

void ResourceTable::canAddEntry(const SourcePos& pos,
        const String16& package, const String16& type, const String16& name)
{
    sp<Type> t = getType(package, type, pos);
    if (t != NULL) {
        t->canAddEntry(name);
    }
}

size_t ResourceTable::size() const {
    return mPackages.size();
}

size_t ResourceTable::numLocalResources() const {
    return mNumLocal;
}

bool ResourceTable::hasResources() const {
    return mNumLocal > 0;
}

sp<AaptFile> ResourceTable::flatten(Bundle* bundle)
{
    sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
    status_t err = flatten(bundle, data);
    return err == NO_ERROR ? data : NULL;
}

inline uint32_t ResourceTable::getResId(const sp<Package>& p,
                                        const sp<Type>& t,
                                        uint32_t nameId)
{
    return makeResId(p->getAssignedId(), t->getIndex(), nameId);
}

uint32_t ResourceTable::getResId(const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 bool onlyPublic) const
{
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) return 0;

    // First look for this in the included resources...
    uint32_t specFlags = 0;
    uint32_t rid = mAssets->getIncludedResources()
        .identifierForName(name.string(), name.size(),
                           type.string(), type.size(),
                           package.string(), package.size(),
                           &specFlags);
    if (rid != 0) {
        if (onlyPublic) {
            if ((specFlags & ResTable_typeSpec::SPEC_PUBLIC) == 0) {
                return 0;
            }
        }
        
        if (Res_INTERNALID(rid)) {
            return rid;
        }
        return Res_MAKEID(p->getAssignedId()-1,
                          Res_GETTYPE(rid),
                          Res_GETENTRY(rid));
    }

    sp<Type> t = p->getTypes().valueFor(type);
    if (t == NULL) return 0;
    sp<ConfigList> c =  t->getConfigs().valueFor(name);
    if (c == NULL) return 0;
    int32_t ei = c->getEntryIndex();
    if (ei < 0) return 0;
    return getResId(p, t, ei);
}

uint32_t ResourceTable::getResId(const String16& ref,
                                 const String16* defType,
                                 const String16* defPackage,
                                 const char** outErrorMsg,
                                 bool onlyPublic) const
{
    String16 package, type, name;
    if (!ResTable::expandResourceRef(
        ref.string(), ref.size(), &package, &type, &name,
        defType, defPackage ? defPackage:&mAssetsPackage,
        outErrorMsg)) {
        NOISY(printf("Expanding resource: ref=%s\n",
                     String8(ref).string()));
        NOISY(printf("Expanding resource: defType=%s\n",
                     defType ? String8(*defType).string() : "NULL"));
        NOISY(printf("Expanding resource: defPackage=%s\n",
                     defPackage ? String8(*defPackage).string() : "NULL"));
        NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string()));
        NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=0\n",
                     String8(package).string(), String8(type).string(),
                     String8(name).string()));
        return 0;
    }
    uint32_t res = getResId(package, type, name, onlyPublic);
    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
                 String8(package).string(), String8(type).string(),
                 String8(name).string(), res));
    if (res == 0) {
        if (outErrorMsg)
            *outErrorMsg = "No resource found that matches the given name";
    }
    return res;
}

bool ResourceTable::isValidResourceName(const String16& s)
{
    const char16_t* p = s.string();
    bool first = true;
    while (*p) {
        if ((*p >= 'a' && *p <= 'z')
            || (*p >= 'A' && *p <= 'Z')
            || *p == '_'
            || (!first && *p >= '0' && *p <= '9')) {
            first = false;
            p++;
            continue;
        }
        return false;
    }
    return true;
}

bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
                                  const String16& str,
                                  bool preserveSpaces, bool coerceType,
                                  uint32_t attrID,
                                  const Vector<StringPool::entry_style_span>* style,
                                  String16* outStr, void* accessorCookie,
                                  uint32_t attrType)
{
    String16 finalStr;

    bool res = true;
    if (style == NULL || style->size() == 0) {
        // Text is not styled so it can be any type...  let's figure it out.
        res = mAssets->getIncludedResources()
            .stringToValue(outValue, &finalStr, str.string(), str.size(), preserveSpaces,
                            coerceType, attrID, NULL, &mAssetsPackage, this,
                           accessorCookie, attrType);
    } else {
        // Styled text can only be a string, and while collecting the style
        // information we have already processed that string!
        outValue->size = sizeof(Res_value);
        outValue->res0 = 0;
        outValue->dataType = outValue->TYPE_STRING;
        outValue->data = 0;
        finalStr = str;
    }

    if (!res) {
        return false;
    }

    if (outValue->dataType == outValue->TYPE_STRING) {
        // Should do better merging styles.
        if (pool) {
            if (style != NULL && style->size() > 0) {
                outValue->data = pool->add(finalStr, *style);
            } else {
                outValue->data = pool->add(finalStr, true);
            }
        } else {
            // Caller will fill this in later.
            outValue->data = 0;
        }
    
        if (outStr) {
            *outStr = finalStr;
        }

    }

    return true;
}

uint32_t ResourceTable::getCustomResource(
    const String16& package, const String16& type, const String16& name) const
{
    //printf("getCustomResource: %s %s %s\n", String8(package).string(),
    //       String8(type).string(), String8(name).string());
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) return 0;
    sp<Type> t = p->getTypes().valueFor(type);
    if (t == NULL) return 0;
    sp<ConfigList> c =  t->getConfigs().valueFor(name);
    if (c == NULL) return 0;
    int32_t ei = c->getEntryIndex();
    if (ei < 0) return 0;
    return getResId(p, t, ei);
}

uint32_t ResourceTable::getCustomResourceWithCreation(
        const String16& package, const String16& type, const String16& name,
        const bool createIfNotFound)
{
    uint32_t resId = getCustomResource(package, type, name);
    if (resId != 0 || !createIfNotFound) {
        return resId;
    }
    String16 value("false");

    status_t status = addEntry(mCurrentXmlPos, package, type, name, value, NULL, NULL, true);
    if (status == NO_ERROR) {
        resId = getResId(package, type, name);
        return resId;
    }
    return 0;
}

uint32_t ResourceTable::getRemappedPackage(uint32_t origPackage) const
{
    return origPackage;
}

bool ResourceTable::getAttributeType(uint32_t attrID, uint32_t* outType)
{
    //printf("getAttributeType #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_TYPE, &value)) {
        //printf("getAttributeType #%08x (%s): #%08x\n", attrID,
        //       String8(getEntry(attrID)->getName()).string(), value.data);
        *outType = value.data;
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeMin(uint32_t attrID, uint32_t* outMin)
{
    //printf("getAttributeMin #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_MIN, &value)) {
        *outMin = value.data;
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeMax(uint32_t attrID, uint32_t* outMax)
{
    //printf("getAttributeMax #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_MAX, &value)) {
        *outMax = value.data;
        return true;
    }
    return false;
}

uint32_t ResourceTable::getAttributeL10N(uint32_t attrID)
{
    //printf("getAttributeL10N #%08x\n", attrID);
    Res_value value;
    if (getItemValue(attrID, ResTable_map::ATTR_L10N, &value)) {
        return value.data;
    }
    return ResTable_map::L10N_NOT_REQUIRED;
}

bool ResourceTable::getLocalizationSetting()
{
    return mBundle->getRequireLocalization();
}

void ResourceTable::reportError(void* accessorCookie, const char* fmt, ...)
{
    if (accessorCookie != NULL && fmt != NULL) {
        AccessorCookie* ac = (AccessorCookie*)accessorCookie;
        int retval=0;
        char buf[1024];
        va_list ap;
        va_start(ap, fmt);
        retval = vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);
        ac->sourcePos.error("Error: %s (at '%s' with value '%s').\n",
                            buf, ac->attr.string(), ac->value.string());
    }
}

bool ResourceTable::getAttributeKeys(
    uint32_t attrID, Vector<String16>* outKeys)
{
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();
        for (size_t i=0; i<N; i++) {
            const String16& key = e->getBag().keyAt(i);
            if (key.size() > 0 && key.string()[0] != '^') {
                outKeys->add(key);
            }
        }
        return true;
    }
    return false;
}

bool ResourceTable::getAttributeEnum(
    uint32_t attrID, const char16_t* name, size_t nameLen,
    Res_value* outValue)
{
    //printf("getAttributeEnum #%08x %s\n", attrID, String8(name, nameLen).string());
    String16 nameStr(name, nameLen);
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();
        for (size_t i=0; i<N; i++) {
            //printf("Comparing %s to %s\n", String8(name, nameLen).string(),
            //       String8(e->getBag().keyAt(i)).string());
            if (e->getBag().keyAt(i) == nameStr) {
                return getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, outValue);
            }
        }
    }
    return false;
}

bool ResourceTable::getAttributeFlags(
    uint32_t attrID, const char16_t* name, size_t nameLen,
    Res_value* outValue)
{
    outValue->dataType = Res_value::TYPE_INT_HEX;
    outValue->data = 0;

    //printf("getAttributeFlags #%08x %s\n", attrID, String8(name, nameLen).string());
    String16 nameStr(name, nameLen);
    sp<const Entry> e = getEntry(attrID);
    if (e != NULL) {
        const size_t N = e->getBag().size();

        const char16_t* end = name + nameLen;
        const char16_t* pos = name;
        bool failed = false;
        while (pos < end && !failed) {
            const char16_t* start = pos;
            end++;
            while (pos < end && *pos != '|') {
                pos++;
            }

            String16 nameStr(start, pos-start);
            size_t i;
            for (i=0; i<N; i++) {
                //printf("Comparing \"%s\" to \"%s\"\n", String8(nameStr).string(),
                //       String8(e->getBag().keyAt(i)).string());
                if (e->getBag().keyAt(i) == nameStr) {
                    Res_value val;
                    bool got = getItemValue(attrID, e->getBag().valueAt(i).bagKeyId, &val);
                    if (!got) {
                        return false;
                    }
                    //printf("Got value: 0x%08x\n", val.data);
                    outValue->data |= val.data;
                    break;
                }
            }

            if (i >= N) {
                // Didn't find this flag identifier.
                return false;
            }
            if (pos < end) {
                pos++;
            }
        }

        return true;
    }
    return false;
}

status_t ResourceTable::assignResourceIds()
{
    const size_t N = mOrderedPackages.size();
    size_t pi;
    status_t firstError = NO_ERROR;

    // First generate all bag attributes and assign indices.
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p == NULL || p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        status_t err = p->applyPublicTypeOrder();
        if (err != NO_ERROR && firstError == NO_ERROR) {
            firstError = err;
        }

        // Generate attributes...
        const size_t N = p->getOrderedTypes().size();
        size_t ti;
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    status_t err = e->generateAttributes(this, p->getName());
                    if (err != NO_ERROR && firstError == NO_ERROR) {
                        firstError = err;
                    }
                }
            }
        }

        const SourcePos unknown(String8("????"), 0);
        sp<Type> attr = p->getType(String16("attr"), unknown);

        // Assign indices...
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            err = t->applyPublicEntryOrder();
            if (err != NO_ERROR && firstError == NO_ERROR) {
                firstError = err;
            }

            const size_t N = t->getOrderedConfigs().size();
            t->setIndex(ti+1);

            LOG_ALWAYS_FATAL_IF(ti == 0 && attr != t,
                                "First type is not attr!");

            for (size_t ei=0; ei<N; ei++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ei);
                if (c == NULL) {
                    continue;
                }
                c->setEntryIndex(ei);
            }
        }

        // Assign resource IDs to keys in bags...
        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                //printf("Ordered config #%d: %p\n", ci, c.get());
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    status_t err = e->assignResourceIds(this, p->getName());
                    if (err != NO_ERROR && firstError == NO_ERROR) {
                        firstError = err;
                    }
                }
            }
        }
    }
    return firstError;
}

status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) {
    const size_t N = mOrderedPackages.size();
    size_t pi;

    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        const size_t N = p->getOrderedTypes().size();
        size_t ti;

        for (ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                continue;
            }
            const size_t N = t->getOrderedConfigs().size();
            sp<AaptSymbols> typeSymbols;
            typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos());
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                uint32_t rid = getResId(p, t, ci);
                if (rid == 0) {
                    return UNKNOWN_ERROR;
                }
                if (Res_GETPACKAGE(rid) == (size_t)(p->getAssignedId()-1)) {
                    typeSymbols->addSymbol(String8(c->getName()), rid, c->getPos());
                    
                    String16 comment(c->getComment());
                    typeSymbols->appendComment(String8(c->getName()), comment, c->getPos());
                    //printf("Type symbol %s comment: %s\n", String8(e->getName()).string(),
                    //     String8(comment).string());
                    comment = c->getTypeComment();
                    typeSymbols->appendTypeComment(String8(c->getName()), comment);
                } else {
#if 0
                    printf("**** NO MATCH: 0x%08x vs 0x%08x\n",
                           Res_GETPACKAGE(rid), p->getAssignedId());
#endif
                }
            }
        }
    }
    return NO_ERROR;
}


void
ResourceTable::addLocalization(const String16& name, const String8& locale)
{
    mLocalizations[name].insert(locale);
}


/*!
 * Flag various sorts of localization problems.  '+' indicates checks already implemented;
 * '-' indicates checks that will be implemented in the future.
 *
 * + A localized string for which no default-locale version exists => warning
 * + A string for which no version in an explicitly-requested locale exists => warning
 * + A localized translation of an translateable="false" string => warning
 * - A localized string not provided in every locale used by the table
 */
status_t
ResourceTable::validateLocalizations(void)
{
    status_t err = NO_ERROR;
    const String8 defaultLocale;

    // For all strings...
    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
         nameIter != mLocalizations.end();
         nameIter++) {
        const set<String8>& configSet = nameIter->second;   // naming convenience

        // Look for strings with no default localization
        if (configSet.count(defaultLocale) == 0) {
            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
            for (set<String8>::iterator locales = configSet.begin();
                 locales != configSet.end();
                 locales++) {
                fprintf(stdout, " %s", (*locales).string());
            }
            fprintf(stdout, "\n");
            // !!! TODO: throw an error here in some circumstances
        }

        // Check that all requested localizations are present for this string
        if (mBundle->getConfigurations() != NULL && mBundle->getRequireLocalization()) {
            const char* allConfigs = mBundle->getConfigurations();
            const char* start = allConfigs;
            const char* comma;
            
            do {
                String8 config;
                comma = strchr(start, ',');
                if (comma != NULL) {
                    config.setTo(start, comma - start);
                    start = comma + 1;
                } else {
                    config.setTo(start);
                }

                // don't bother with the pseudolocale "zz_ZZ"
                if (config != "zz_ZZ") {
                    if (configSet.find(config) == configSet.end()) {
                        // okay, no specific localization found.  it's possible that we are
                        // requiring a specific regional localization [e.g. de_DE] but there is an
                        // available string in the generic language localization [e.g. de];
                        // consider that string to have fulfilled the localization requirement.
                        String8 region(config.string(), 2);
                        if (configSet.find(region) == configSet.end()) {
                            if (configSet.count(defaultLocale) == 0) {
                                fprintf(stdout, "aapt: warning: "
                                        "**** string '%s' has no default or required localization "
                                        "for '%s' in %s\n",
                                        String8(nameIter->first).string(),
                                        config.string(),
                                        mBundle->getResourceSourceDirs()[0]);
                            }
                        }
                    }
                }
           } while (comma != NULL);
        }
    }

    return err;
}


status_t
ResourceFilter::parse(const char* arg)
{
    if (arg == NULL) {
        return 0;
    }

    const char* p = arg;
    const char* q;

    while (true) {
        q = strchr(p, ',');
        if (q == NULL) {
            q = p + strlen(p);
        }

        String8 part(p, q-p);

        if (part == "zz_ZZ") {
            mContainsPseudo = true;
        }
        int axis;
        uint32_t value;
        if (AaptGroupEntry::parseNamePart(part, &axis, &value)) {
            fprintf(stderr, "Invalid configuration: %s\n", arg);
            fprintf(stderr, "                       ");
            for (int i=0; i<p-arg; i++) {
                fprintf(stderr, " ");
            }
            for (int i=0; i<q-p; i++) {
                fprintf(stderr, "^");
            }
            fprintf(stderr, "\n");
            return 1;
        }

        ssize_t index = mData.indexOfKey(axis);
        if (index < 0) {
            mData.add(axis, SortedVector<uint32_t>());
        }
        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
        sv.add(value);
        // if it's a locale with a region, also match an unmodified locale of the
        // same language
        if (axis == AXIS_LANGUAGE) {
            if (value & 0xffff0000) {
                sv.add(value & 0x0000ffff);
            }
        }
        p = q;
        if (!*p) break;
        p++;
    }

    return NO_ERROR;
}

bool
ResourceFilter::match(int axis, uint32_t value)
{
    if (value == 0) {
        // they didn't specify anything so take everything
        return true;
    }
    ssize_t index = mData.indexOfKey(axis);
    if (index < 0) {
        // we didn't request anything on this axis so take everything
        return true;
    }
    const SortedVector<uint32_t>& sv = mData.valueAt(index);
    return sv.indexOf(value) >= 0;
}

bool
ResourceFilter::match(const ResTable_config& config)
{
    if (config.locale) {
        uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16)
                | (config.language[1] << 8) | (config.language[0]);
        if (!match(AXIS_LANGUAGE, locale)) {
            return false;
        }
    }
    if (!match(AXIS_ORIENTATION, config.orientation)) {
        return false;
    }
    if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) {
        return false;
    }
    if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) {
        return false;
    }
    if (!match(AXIS_DENSITY, config.density)) {
        return false;
    }
    if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) {
        return false;
    }
    if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) {
        return false;
    }
    if (!match(AXIS_KEYBOARD, config.keyboard)) {
        return false;
    }
    if (!match(AXIS_NAVIGATION, config.navigation)) {
        return false;
    }
    if (!match(AXIS_SCREENSIZE, config.screenSize)) {
        return false;
    }
    if (!match(AXIS_VERSION, config.version)) {
        return false;
    }
    return true;
}

status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
{
    ResourceFilter filter;
    status_t err = filter.parse(bundle->getConfigurations());
    if (err != NO_ERROR) {
        return err;
    }

    const size_t N = mOrderedPackages.size();
    size_t pi;

    bool useUTF8 = !bundle->getWantUTF16() && bundle->isMinSdkAtLeast(SDK_FROYO);

    // Iterate through all data, collecting all values (strings,
    // references, etc).
    StringPool valueStrings = StringPool(false, useUTF8);
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        StringPool typeStrings = StringPool(false, useUTF8);
        StringPool keyStrings = StringPool(false, useUTF8);

        const size_t N = p->getOrderedTypes().size();
        for (size_t ti=0; ti<N; ti++) {
            sp<Type> t = p->getOrderedTypes().itemAt(ti);
            if (t == NULL) {
                typeStrings.add(String16("<empty>"), false);
                continue;
            }
            typeStrings.add(t->getName(), false);

            const size_t N = t->getOrderedConfigs().size();
            for (size_t ci=0; ci<N; ci++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
                if (c == NULL) {
                    continue;
                }
                const size_t N = c->getEntries().size();
                for (size_t ei=0; ei<N; ei++) {
                    ConfigDescription config = c->getEntries().keyAt(ei);
                    if (!filter.match(config)) {
                        continue;
                    }
                    sp<Entry> e = c->getEntries().valueAt(ei);
                    if (e == NULL) {
                        continue;
                    }
                    e->setNameIndex(keyStrings.add(e->getName(), true));
                    status_t err = e->prepareFlatten(&valueStrings, this);
                    if (err != NO_ERROR) {
                        return err;
                    }
                }
            }
        }

        p->setTypeStrings(typeStrings.createStringBlock());
        p->setKeyStrings(keyStrings.createStringBlock());
    }

    ssize_t strAmt = 0;
    
    // Now build the array of package chunks.
    Vector<sp<AaptFile> > flatPackages;
    for (pi=0; pi<N; pi++) {
        sp<Package> p = mOrderedPackages.itemAt(pi);
        if (p->getTypes().size() == 0) {
            // Empty, skip!
            continue;
        }

        const size_t N = p->getTypeStrings().size();

        const size_t baseSize = sizeof(ResTable_package);

        // Start the package data.
        sp<AaptFile> data = new AaptFile(String8(), AaptGroupEntry(), String8());
        ResTable_package* header = (ResTable_package*)data->editData(baseSize);
        if (header == NULL) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_package\n");
            return NO_MEMORY;
        }
        memset(header, 0, sizeof(*header));
        header->header.type = htods(RES_TABLE_PACKAGE_TYPE);
        header->header.headerSize = htods(sizeof(*header));
        header->id = htodl(p->getAssignedId());
        strcpy16_htod(header->name, p->getName().string());

        // Write the string blocks.
        const size_t typeStringsStart = data->getSize();
        sp<AaptFile> strFile = p->getTypeStringsData();
        ssize_t amt = data->writeData(strFile->getData(), strFile->getSize());
        #if PRINT_STRING_METRICS
        fprintf(stderr, "**** type strings: %d\n", amt);
        #endif
        strAmt += amt;
        if (amt < 0) {
            return amt;
        }
        const size_t keyStringsStart = data->getSize();
        strFile = p->getKeyStringsData();
        amt = data->writeData(strFile->getData(), strFile->getSize());
        #if PRINT_STRING_METRICS
        fprintf(stderr, "**** key strings: %d\n", amt);
        #endif
        strAmt += amt;
        if (amt < 0) {
            return amt;
        }

        // Build the type chunks inside of this package.
        for (size_t ti=0; ti<N; ti++) {
            // Retrieve them in the same order as the type string block.
            size_t len;
            String16 typeName(p->getTypeStrings().stringAt(ti, &len));
            sp<Type> t = p->getTypes().valueFor(typeName);
            LOG_ALWAYS_FATAL_IF(t == NULL && typeName != String16("<empty>"),
                                "Type name %s not found",
                                String8(typeName).string());

            const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
            
            // First write the typeSpec chunk, containing information about
            // each resource entry in this type.
            {
                const size_t typeSpecSize = sizeof(ResTable_typeSpec) + sizeof(uint32_t)*N;
                const size_t typeSpecStart = data->getSize();
                ResTable_typeSpec* tsHeader = (ResTable_typeSpec*)
                    (((uint8_t*)data->editData(typeSpecStart+typeSpecSize)) + typeSpecStart);
                if (tsHeader == NULL) {
                    fprintf(stderr, "ERROR: out of memory creating ResTable_typeSpec\n");
                    return NO_MEMORY;
                }
                memset(tsHeader, 0, sizeof(*tsHeader));
                tsHeader->header.type = htods(RES_TABLE_TYPE_SPEC_TYPE);
                tsHeader->header.headerSize = htods(sizeof(*tsHeader));
                tsHeader->header.size = htodl(typeSpecSize);
                tsHeader->id = ti+1;
                tsHeader->entryCount = htodl(N);
                
                uint32_t* typeSpecFlags = (uint32_t*)
                    (((uint8_t*)data->editData())
                        + typeSpecStart + sizeof(ResTable_typeSpec));
                memset(typeSpecFlags, 0, sizeof(uint32_t)*N);
                        
                for (size_t ei=0; ei<N; ei++) {
                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
                    if (cl->getPublic()) {
                        typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC);
                    }
                    const size_t CN = cl->getEntries().size();
                    for (size_t ci=0; ci<CN; ci++) {
                        if (!filter.match(cl->getEntries().keyAt(ci))) {
                            continue;
                        }
                        for (size_t cj=ci+1; cj<CN; cj++) {
                            if (!filter.match(cl->getEntries().keyAt(cj))) {
                                continue;
                            }
                            typeSpecFlags[ei] |= htodl(
                                cl->getEntries().keyAt(ci).diff(cl->getEntries().keyAt(cj)));
                        }
                    }
                }
            }
            
            // We need to write one type chunk for each configuration for
            // which we have entries in this type.
            const size_t NC = t->getUniqueConfigs().size();
            
            const size_t typeSize = sizeof(ResTable_type) + sizeof(uint32_t)*N;
            
            for (size_t ci=0; ci<NC; ci++) {
                ConfigDescription config = t->getUniqueConfigs().itemAt(ci);

                NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      ti+1,
                      config.mcc, config.mnc,
                      config.language[0] ? config.language[0] : '-',
                      config.language[1] ? config.language[1] : '-',
                      config.country[0] ? config.country[0] : '-',
                      config.country[1] ? config.country[1] : '-',
                      config.orientation,
                      config.uiMode,
                      config.touchscreen,
                      config.density,
                      config.keyboard,
                      config.inputFlags,
                      config.navigation,
                      config.screenWidth,
                      config.screenHeight));
                      
                if (!filter.match(config)) {
                    continue;
                }
                
                const size_t typeStart = data->getSize();

                ResTable_type* tHeader = (ResTable_type*)
                    (((uint8_t*)data->editData(typeStart+typeSize)) + typeStart);
                if (tHeader == NULL) {
                    fprintf(stderr, "ERROR: out of memory creating ResTable_type\n");
                    return NO_MEMORY;
                }

                memset(tHeader, 0, sizeof(*tHeader));
                tHeader->header.type = htods(RES_TABLE_TYPE_TYPE);
                tHeader->header.headerSize = htods(sizeof(*tHeader));
                tHeader->id = ti+1;
                tHeader->entryCount = htodl(N);
                tHeader->entriesStart = htodl(typeSize);
                tHeader->config = config;
                NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
                     "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      ti+1,
                      tHeader->config.mcc, tHeader->config.mnc,
                      tHeader->config.language[0] ? tHeader->config.language[0] : '-',
                      tHeader->config.language[1] ? tHeader->config.language[1] : '-',
                      tHeader->config.country[0] ? tHeader->config.country[0] : '-',
                      tHeader->config.country[1] ? tHeader->config.country[1] : '-',
                      tHeader->config.orientation,
                      tHeader->config.uiMode,
                      tHeader->config.touchscreen,
                      tHeader->config.density,
                      tHeader->config.keyboard,
                      tHeader->config.inputFlags,
                      tHeader->config.navigation,
                      tHeader->config.screenWidth,
                      tHeader->config.screenHeight));
                tHeader->config.swapHtoD();

                // Build the entries inside of this type.
                for (size_t ei=0; ei<N; ei++) {
                    sp<ConfigList> cl = t->getOrderedConfigs().itemAt(ei);
                    sp<Entry> e = cl->getEntries().valueFor(config);

                    // Set the offset for this entry in its type.
                    uint32_t* index = (uint32_t*)
                        (((uint8_t*)data->editData())
                            + typeStart + sizeof(ResTable_type));
                    if (e != NULL) {
                        index[ei] = htodl(data->getSize()-typeStart-typeSize);

                        // Create the entry.
                        ssize_t amt = e->flatten(bundle, data, cl->getPublic());
                        if (amt < 0) {
                            return amt;
                        }
                    } else {
                        index[ei] = htodl(ResTable_type::NO_ENTRY);
                    }
                }

                // Fill in the rest of the type information.
                tHeader = (ResTable_type*)
                    (((uint8_t*)data->editData()) + typeStart);
                tHeader->header.size = htodl(data->getSize()-typeStart);
            }
        }

        // Fill in the rest of the package information.
        header = (ResTable_package*)data->editData();
        header->header.size = htodl(data->getSize());
        header->typeStrings = htodl(typeStringsStart);
        header->lastPublicType = htodl(p->getTypeStrings().size());
        header->keyStrings = htodl(keyStringsStart);
        header->lastPublicKey = htodl(p->getKeyStrings().size());

        flatPackages.add(data);
    }

    // And now write out the final chunks.
    const size_t dataStart = dest->getSize();

    {
        // blah
        ResTable_header header;
        memset(&header, 0, sizeof(header));
        header.header.type = htods(RES_TABLE_TYPE);
        header.header.headerSize = htods(sizeof(header));
        header.packageCount = htodl(flatPackages.size());
        status_t err = dest->writeData(&header, sizeof(header));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_header\n");
            return err;
        }
    }
    
    ssize_t strStart = dest->getSize();
    err = valueStrings.writeStringBlock(dest);
    if (err != NO_ERROR) {
        return err;
    }

    ssize_t amt = (dest->getSize()-strStart);
    strAmt += amt;
    #if PRINT_STRING_METRICS
    fprintf(stderr, "**** value strings: %d\n", amt);
    fprintf(stderr, "**** total strings: %d\n", strAmt);
    #endif
    
    for (pi=0; pi<flatPackages.size(); pi++) {
        err = dest->writeData(flatPackages[pi]->getData(),
                              flatPackages[pi]->getSize());
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating package chunk for ResTable_header\n");
            return err;
        }
    }

    ResTable_header* header = (ResTable_header*)
        (((uint8_t*)dest->getData()) + dataStart);
    header->header.size = htodl(dest->getSize() - dataStart);

    NOISY(aout << "Resource table:"
          << HexDump(dest->getData(), dest->getSize()) << endl);

    #if PRINT_STRING_METRICS
    fprintf(stderr, "**** total resource table size: %d / %d%% strings\n",
        dest->getSize(), (strAmt*100)/dest->getSize());
    #endif
    
    return NO_ERROR;
}

void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp)
{
    fprintf(fp,
    "<!-- This file contains <public> resource definitions for all\n"
    "     resources that were generated from the source data. -->\n"
    "\n"
    "<resources>\n");

    writePublicDefinitions(package, fp, true);
    writePublicDefinitions(package, fp, false);

    fprintf(fp,
    "\n"
    "</resources>\n");
}

void ResourceTable::writePublicDefinitions(const String16& package, FILE* fp, bool pub)
{
    bool didHeader = false;

    sp<Package> pkg = mPackages.valueFor(package);
    if (pkg != NULL) {
        const size_t NT = pkg->getOrderedTypes().size();
        for (size_t i=0; i<NT; i++) {
            sp<Type> t = pkg->getOrderedTypes().itemAt(i);
            if (t == NULL) {
                continue;
            }

            bool didType = false;

            const size_t NC = t->getOrderedConfigs().size();
            for (size_t j=0; j<NC; j++) {
                sp<ConfigList> c = t->getOrderedConfigs().itemAt(j);
                if (c == NULL) {
                    continue;
                }

                if (c->getPublic() != pub) {
                    continue;
                }

                if (!didType) {
                    fprintf(fp, "\n");
                    didType = true;
                }
                if (!didHeader) {
                    if (pub) {
                        fprintf(fp,"  <!-- PUBLIC SECTION.  These resources have been declared public.\n");
                        fprintf(fp,"       Changes to these definitions will break binary compatibility. -->\n\n");
                    } else {
                        fprintf(fp,"  <!-- PRIVATE SECTION.  These resources have not been declared public.\n");
                        fprintf(fp,"       You can make them public my moving these lines into a file in res/values. -->\n\n");
                    }
                    didHeader = true;
                }
                if (!pub) {
                    const size_t NE = c->getEntries().size();
                    for (size_t k=0; k<NE; k++) {
                        const SourcePos& pos = c->getEntries().valueAt(k)->getPos();
                        if (pos.file != "") {
                            fprintf(fp,"  <!-- Declared at %s:%d -->\n",
                                    pos.file.string(), pos.line);
                        }
                    }
                }
                fprintf(fp, "  <public type=\"%s\" name=\"%s\" id=\"0x%08x\" />\n",
                        String8(t->getName()).string(),
                        String8(c->getName()).string(),
                        getResId(pkg, t, c->getEntryIndex()));
            }
        }
    }
}

ResourceTable::Item::Item(const SourcePos& _sourcePos,
                          bool _isId,
                          const String16& _value,
                          const Vector<StringPool::entry_style_span>* _style,
                          int32_t _format)
    : sourcePos(_sourcePos)
    , isId(_isId)
    , value(_value)
    , format(_format)
    , bagKeyId(0)
    , evaluating(false)
{
    if (_style) {
        style = *_style;
    }
}

status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
{
    if (mType == TYPE_BAG) {
        return NO_ERROR;
    }
    if (mType == TYPE_UNKNOWN) {
        mType = TYPE_BAG;
        return NO_ERROR;
    }
    sourcePos.error("Resource entry %s is already defined as a single item.\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(),
                    mItem.sourcePos.file.string(), mItem.sourcePos.line);
    return UNKNOWN_ERROR;
}

status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
                                       const String16& value,
                                       const Vector<StringPool::entry_style_span>* style,
                                       int32_t format,
                                       const bool overwrite)
{
    Item item(sourcePos, false, value, style);

    if (mType == TYPE_BAG) {
        const Item& item(mBag.valueAt(0));
        sourcePos.error("Resource entry %s is already defined as a bag.\n"
                        "%s:%d: Originally defined here.\n",
                        String8(mName).string(),
                        item.sourcePos.file.string(), item.sourcePos.line);
        return UNKNOWN_ERROR;
    }
    if ( (mType != TYPE_UNKNOWN) && (overwrite == false) ) {
        sourcePos.error("Resource entry %s is already defined.\n"
                        "%s:%d: Originally defined here.\n",
                        String8(mName).string(),
                        mItem.sourcePos.file.string(), mItem.sourcePos.line);
        return UNKNOWN_ERROR;
    }

    mType = TYPE_ITEM;
    mItem = item;
    mItemFormat = format;
    return NO_ERROR;
}

status_t ResourceTable::Entry::addToBag(const SourcePos& sourcePos,
                                        const String16& key, const String16& value,
                                        const Vector<StringPool::entry_style_span>* style,
                                        bool replace, bool isId, int32_t format)
{
    status_t err = makeItABag(sourcePos);
    if (err != NO_ERROR) {
        return err;
    }

    Item item(sourcePos, isId, value, style, format);
    
    // XXX NOTE: there is an error if you try to have a bag with two keys,
    // one an attr and one an id, with the same name.  Not something we
    // currently ever have to worry about.
    ssize_t origKey = mBag.indexOfKey(key);
    if (origKey >= 0) {
        if (!replace) {
            const Item& item(mBag.valueAt(origKey));
            sourcePos.error("Resource entry %s already has bag item %s.\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(), String8(key).string(),
                    item.sourcePos.file.string(), item.sourcePos.line);
            return UNKNOWN_ERROR;
        }
        //printf("Replacing %s with %s\n",
        //       String8(mBag.valueFor(key).value).string(), String8(value).string());
        mBag.replaceValueFor(key, item);
    }

    mBag.add(key, item);
    return NO_ERROR;
}

status_t ResourceTable::Entry::emptyBag(const SourcePos& sourcePos)
{
    status_t err = makeItABag(sourcePos);
    if (err != NO_ERROR) {
        return err;
    }

    mBag.clear();
    return NO_ERROR;
}

status_t ResourceTable::Entry::generateAttributes(ResourceTable* table,
                                                  const String16& package)
{
    const String16 attr16("attr");
    const String16 id16("id");
    const size_t N = mBag.size();
    for (size_t i=0; i<N; i++) {
        const String16& key = mBag.keyAt(i);
        const Item& it = mBag.valueAt(i);
        if (it.isId) {
            if (!table->hasBagOrEntry(key, &id16, &package)) {
                String16 value("false");
                status_t err = table->addEntry(SourcePos(String8("<generated>"), 0), package,
                                               id16, key, value);
                if (err != NO_ERROR) {
                    return err;
                }
            }
        } else if (!table->hasBagOrEntry(key, &attr16, &package)) {

#if 1
//             fprintf(stderr, "ERROR: Bag attribute '%s' has not been defined.\n",
//                     String8(key).string());
//             const Item& item(mBag.valueAt(i));
//             fprintf(stderr, "Referenced from file %s line %d\n",
//                     item.sourcePos.file.string(), item.sourcePos.line);
//             return UNKNOWN_ERROR;
#else
            char numberStr[16];
            sprintf(numberStr, "%d", ResTable_map::TYPE_ANY);
            status_t err = table->addBag(SourcePos("<generated>", 0), package,
                                         attr16, key, String16(""),
                                         String16("^type"),
                                         String16(numberStr), NULL, NULL);
            if (err != NO_ERROR) {
                return err;
            }
#endif
        }
    }
    return NO_ERROR;
}

status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
                                                 const String16& package)
{
    bool hasErrors = false;
    
    if (mType == TYPE_BAG) {
        const char* errorMsg;
        const String16 style16("style");
        const String16 attr16("attr");
        const String16 id16("id");
        mParentId = 0;
        if (mParent.size() > 0) {
            mParentId = table->getResId(mParent, &style16, NULL, &errorMsg);
            if (mParentId == 0) {
                mPos.error("Error retrieving parent for item: %s '%s'.\n",
                        errorMsg, String8(mParent).string());
                hasErrors = true;
            }
        }
        const size_t N = mBag.size();
        for (size_t i=0; i<N; i++) {
            const String16& key = mBag.keyAt(i);
            Item& it = mBag.editValueAt(i);
            it.bagKeyId = table->getResId(key,
                    it.isId ? &id16 : &attr16, NULL, &errorMsg);
            //printf("Bag key of %s: #%08x\n", String8(key).string(), it.bagKeyId);
            if (it.bagKeyId == 0) {
                it.sourcePos.error("Error: %s: %s '%s'.\n", errorMsg,
                        String8(it.isId ? id16 : attr16).string(),
                        String8(key).string());
                hasErrors = true;
            }
        }
    }
    return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}

status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table)
{
    if (mType == TYPE_ITEM) {
        Item& it = mItem;
        AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
        if (!table->stringToValue(&it.parsedValue, strings,
                                  it.value, false, true, 0,
                                  &it.style, NULL, &ac, mItemFormat)) {
            return UNKNOWN_ERROR;
        }
    } else if (mType == TYPE_BAG) {
        const size_t N = mBag.size();
        for (size_t i=0; i<N; i++) {
            const String16& key = mBag.keyAt(i);
            Item& it = mBag.editValueAt(i);
            AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
            if (!table->stringToValue(&it.parsedValue, strings,
                                      it.value, false, true, it.bagKeyId,
                                      &it.style, NULL, &ac, it.format)) {
                return UNKNOWN_ERROR;
            }
        }
    } else {
        mPos.error("Error: entry %s is not a single item or a bag.\n",
                   String8(mName).string());
        return UNKNOWN_ERROR;
    }
    return NO_ERROR;
}

ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
{
    size_t amt = 0;
    ResTable_entry header;
    memset(&header, 0, sizeof(header));
    header.size = htods(sizeof(header));
    const type ty = this != NULL ? mType : TYPE_ITEM;
    if (this != NULL) {
        if (ty == TYPE_BAG) {
            header.flags |= htods(header.FLAG_COMPLEX);
        }
        if (isPublic) {
            header.flags |= htods(header.FLAG_PUBLIC);
        }
        header.key.index = htodl(mNameIndex);
    }
    if (ty != TYPE_BAG) {
        status_t err = data->writeData(&header, sizeof(header));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
            return err;
        }

        const Item& it = mItem;
        Res_value par;
        memset(&par, 0, sizeof(par));
        par.size = htods(it.parsedValue.size);
        par.dataType = it.parsedValue.dataType;
        par.res0 = it.parsedValue.res0;
        par.data = htodl(it.parsedValue.data);
        #if 0
        printf("Writing item (%s): type=%d, data=0x%x, res0=0x%x\n",
               String8(mName).string(), it.parsedValue.dataType,
               it.parsedValue.data, par.res0);
        #endif
        err = data->writeData(&par, it.parsedValue.size);
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating Res_value\n");
            return err;
        }
        amt += it.parsedValue.size;
    } else {
        size_t N = mBag.size();
        size_t i;
        // Create correct ordering of items.
        KeyedVector<uint32_t, const Item*> items;
        for (i=0; i<N; i++) {
            const Item& it = mBag.valueAt(i);
            items.add(it.bagKeyId, &it);
        }
        N = items.size();
        
        ResTable_map_entry mapHeader;
        memcpy(&mapHeader, &header, sizeof(header));
        mapHeader.size = htods(sizeof(mapHeader));
        mapHeader.parent.ident = htodl(mParentId);
        mapHeader.count = htodl(N);
        status_t err = data->writeData(&mapHeader, sizeof(mapHeader));
        if (err != NO_ERROR) {
            fprintf(stderr, "ERROR: out of memory creating ResTable_entry\n");
            return err;
        }

        for (i=0; i<N; i++) {
            const Item& it = *items.valueAt(i);
            ResTable_map map;
            map.name.ident = htodl(it.bagKeyId);
            map.value.size = htods(it.parsedValue.size);
            map.value.dataType = it.parsedValue.dataType;
            map.value.res0 = it.parsedValue.res0;
            map.value.data = htodl(it.parsedValue.data);
            err = data->writeData(&map, sizeof(map));
            if (err != NO_ERROR) {
                fprintf(stderr, "ERROR: out of memory creating Res_value\n");
                return err;
            }
            amt += sizeof(map);
        }
    }
    return amt;
}

void ResourceTable::ConfigList::appendComment(const String16& comment,
                                              bool onlyIfEmpty)
{
    if (comment.size() <= 0) {
        return;
    }
    if (onlyIfEmpty && mComment.size() > 0) {
        return;
    }
    if (mComment.size() > 0) {
        mComment.append(String16("\n"));
    }
    mComment.append(comment);
}

void ResourceTable::ConfigList::appendTypeComment(const String16& comment)
{
    if (comment.size() <= 0) {
        return;
    }
    if (mTypeComment.size() > 0) {
        mTypeComment.append(String16("\n"));
    }
    mTypeComment.append(comment);
}

status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
                                        const String16& name,
                                        const uint32_t ident)
{
    #if 0
    int32_t entryIdx = Res_GETENTRY(ident);
    if (entryIdx < 0) {
        sourcePos.error("Public resource %s/%s has an invalid 0 identifier (0x%08x).\n",
                String8(mName).string(), String8(name).string(), ident);
        return UNKNOWN_ERROR;
    }
    #endif

    int32_t typeIdx = Res_GETTYPE(ident);
    if (typeIdx >= 0) {
        typeIdx++;
        if (mPublicIndex > 0 && mPublicIndex != typeIdx) {
            sourcePos.error("Public resource %s/%s has conflicting type codes for its"
                    " public identifiers (0x%x vs 0x%x).\n",
                    String8(mName).string(), String8(name).string(),
                    mPublicIndex, typeIdx);
            return UNKNOWN_ERROR;
        }
        mPublicIndex = typeIdx;
    }

    if (mFirstPublicSourcePos == NULL) {
        mFirstPublicSourcePos = new SourcePos(sourcePos);
    }

    if (mPublic.indexOfKey(name) < 0) {
        mPublic.add(name, Public(sourcePos, String16(), ident));
    } else {
        Public& p = mPublic.editValueFor(name);
        if (p.ident != ident) {
            sourcePos.error("Public resource %s/%s has conflicting public identifiers"
                    " (0x%08x vs 0x%08x).\n"
                    "%s:%d: Originally defined here.\n",
                    String8(mName).string(), String8(name).string(), p.ident, ident,
                    p.sourcePos.file.string(), p.sourcePos.line);
            return UNKNOWN_ERROR;
        }
    }

    return NO_ERROR;
}

void ResourceTable::Type::canAddEntry(const String16& name)
{
    mCanAddEntries.add(name);
}

sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
                                                       const SourcePos& sourcePos,
                                                       const ResTable_config* config,
                                                       bool doSetIndex,
                                                       bool overlay,
                                                       bool autoAddOverlay)
{
    int pos = -1;
    sp<ConfigList> c = mConfigs.valueFor(entry);
    if (c == NULL) {
        if (overlay && !autoAddOverlay && mCanAddEntries.indexOf(entry) < 0) {
            sourcePos.error("Resource at %s appears in overlay but not"
                            " in the base package; use <add-resource> to add.\n",
                            String8(entry).string());
            return NULL;
        }
        c = new ConfigList(entry, sourcePos);
        mConfigs.add(entry, c);
        pos = (int)mOrderedConfigs.size();
        mOrderedConfigs.add(c);
        if (doSetIndex) {
            c->setEntryIndex(pos);
        }
    }
    
    ConfigDescription cdesc;
    if (config) cdesc = *config;
    
    sp<Entry> e = c->getEntries().valueFor(cdesc);
    if (e == NULL) {
        if (config != NULL) {
            NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
                    "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
                      sourcePos.file.string(), sourcePos.line,
                      config->mcc, config->mnc,
                      config->language[0] ? config->language[0] : '-',
                      config->language[1] ? config->language[1] : '-',
                      config->country[0] ? config->country[0] : '-',
                      config->country[1] ? config->country[1] : '-',
                      config->orientation,
                      config->touchscreen,
                      config->density,
                      config->keyboard,
                      config->inputFlags,
                      config->navigation,
                      config->screenWidth,
                      config->screenHeight));
        } else {
            NOISY(printf("New entry at %s:%d: NULL config\n",
                      sourcePos.file.string(), sourcePos.line));
        }
        e = new Entry(entry, sourcePos);
        c->addEntry(cdesc, e);
        /*
        if (doSetIndex) {
            if (pos < 0) {
                for (pos=0; pos<(int)mOrderedConfigs.size(); pos++) {
                    if (mOrderedConfigs[pos] == c) {
                        break;
                    }
                }
                if (pos >= (int)mOrderedConfigs.size()) {
                    sourcePos.error("Internal error: config not found in mOrderedConfigs when adding entry");
                    return NULL;
                }
            }
            e->setEntryIndex(pos);
        }
        */
    }
    
    mUniqueConfigs.add(cdesc);
    
    return e;
}

status_t ResourceTable::Type::applyPublicEntryOrder()
{
    size_t N = mOrderedConfigs.size();
    Vector<sp<ConfigList> > origOrder(mOrderedConfigs);
    bool hasError = false;

    size_t i;
    for (i=0; i<N; i++) {
        mOrderedConfigs.replaceAt(NULL, i);
    }

    const size_t NP = mPublic.size();
    //printf("Ordering %d configs from %d public defs\n", N, NP);
    size_t j;
    for (j=0; j<NP; j++) {
        const String16& name = mPublic.keyAt(j);
        const Public& p = mPublic.valueAt(j);
        int32_t idx = Res_GETENTRY(p.ident);
        //printf("Looking for entry \"%s\"/\"%s\" (0x%08x) in %d...\n",
        //       String8(mName).string(), String8(name).string(), p.ident, N);
        bool found = false;
        for (i=0; i<N; i++) {
            sp<ConfigList> e = origOrder.itemAt(i);
            //printf("#%d: \"%s\"\n", i, String8(e->getName()).string());
            if (e->getName() == name) {
                if (idx >= (int32_t)mOrderedConfigs.size()) {
                    p.sourcePos.error("Public entry identifier 0x%x entry index "
                            "is larger than available symbols (index %d, total symbols %d).\n",
                            p.ident, idx, mOrderedConfigs.size());
                    hasError = true;
                } else if (mOrderedConfigs.itemAt(idx) == NULL) {
                    e->setPublic(true);
                    e->setPublicSourcePos(p.sourcePos);
                    mOrderedConfigs.replaceAt(e, idx);
                    origOrder.removeAt(i);
                    N--;
                    found = true;
                    break;
                } else {
                    sp<ConfigList> oe = mOrderedConfigs.itemAt(idx);

                    p.sourcePos.error("Multiple entry names declared for public entry"
                            " identifier 0x%x in type %s (%s vs %s).\n"
                            "%s:%d: Originally defined here.",
                            idx+1, String8(mName).string(),
                            String8(oe->getName()).string(),
                            String8(name).string(),
                            oe->getPublicSourcePos().file.string(),
                            oe->getPublicSourcePos().line);
                    hasError = true;
                }
            }
        }

        if (!found) {
            p.sourcePos.error("Public symbol %s/%s declared here is not defined.",
                    String8(mName).string(), String8(name).string());
            hasError = true;
        }
    }

    //printf("Copying back in %d non-public configs, have %d\n", N, origOrder.size());
    
    if (N != origOrder.size()) {
        printf("Internal error: remaining private symbol count mismatch\n");
        N = origOrder.size();
    }
    
    j = 0;
    for (i=0; i<N; i++) {
        sp<ConfigList> e = origOrder.itemAt(i);
        // There will always be enough room for the remaining entries.
        while (mOrderedConfigs.itemAt(j) != NULL) {
            j++;
        }
        mOrderedConfigs.replaceAt(e, j);
        j++;
    }

    return hasError ? UNKNOWN_ERROR : NO_ERROR;
}

ResourceTable::Package::Package(const String16& name, ssize_t includedId)
    : mName(name), mIncludedId(includedId),
      mTypeStringsMapping(0xffffffff),
      mKeyStringsMapping(0xffffffff)
{
}

sp<ResourceTable::Type> ResourceTable::Package::getType(const String16& type,
                                                        const SourcePos& sourcePos,
                                                        bool doSetIndex)
{
    sp<Type> t = mTypes.valueFor(type);
    if (t == NULL) {
        t = new Type(type, sourcePos);
        mTypes.add(type, t);
        mOrderedTypes.add(t);
        if (doSetIndex) {
            // For some reason the type's index is set to one plus the index
            // in the mOrderedTypes list, rather than just the index.
            t->setIndex(mOrderedTypes.size());
        }
    }
    return t;
}

status_t ResourceTable::Package::setTypeStrings(const sp<AaptFile>& data)
{
    mTypeStringsData = data;
    status_t err = setStrings(data, &mTypeStrings, &mTypeStringsMapping);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: Type string data is corrupt!\n");
    }
    return err;
}

status_t ResourceTable::Package::setKeyStrings(const sp<AaptFile>& data)
{
    mKeyStringsData = data;
    status_t err = setStrings(data, &mKeyStrings, &mKeyStringsMapping);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: Key string data is corrupt!\n");
    }
    return err;
}

status_t ResourceTable::Package::setStrings(const sp<AaptFile>& data,
                                            ResStringPool* strings,
                                            DefaultKeyedVector<String16, uint32_t>* mappings)
{
    if (data->getData() == NULL) {
        return UNKNOWN_ERROR;
    }

    NOISY(aout << "Setting restable string pool: "
          << HexDump(data->getData(), data->getSize()) << endl);

    status_t err = strings->setTo(data->getData(), data->getSize());
    if (err == NO_ERROR) {
        const size_t N = strings->size();
        for (size_t i=0; i<N; i++) {
            size_t len;
            mappings->add(String16(strings->stringAt(i, &len)), i);
        }
    }
    return err;
}

status_t ResourceTable::Package::applyPublicTypeOrder()
{
    size_t N = mOrderedTypes.size();
    Vector<sp<Type> > origOrder(mOrderedTypes);

    size_t i;
    for (i=0; i<N; i++) {
        mOrderedTypes.replaceAt(NULL, i);
    }

    for (i=0; i<N; i++) {
        sp<Type> t = origOrder.itemAt(i);
        int32_t idx = t->getPublicIndex();
        if (idx > 0) {
            idx--;
            while (idx >= (int32_t)mOrderedTypes.size()) {
                mOrderedTypes.add();
            }
            if (mOrderedTypes.itemAt(idx) != NULL) {
                sp<Type> ot = mOrderedTypes.itemAt(idx);
                t->getFirstPublicSourcePos().error("Multiple type names declared for public type"
                        " identifier 0x%x (%s vs %s).\n"
                        "%s:%d: Originally defined here.",
                        idx, String8(ot->getName()).string(),
                        String8(t->getName()).string(),
                        ot->getFirstPublicSourcePos().file.string(),
                        ot->getFirstPublicSourcePos().line);
                return UNKNOWN_ERROR;
            }
            mOrderedTypes.replaceAt(t, idx);
            origOrder.removeAt(i);
            i--;
            N--;
        }
    }

    size_t j=0;
    for (i=0; i<N; i++) {
        sp<Type> t = origOrder.itemAt(i);
        // There will always be enough room for the remaining types.
        while (mOrderedTypes.itemAt(j) != NULL) {
            j++;
        }
        mOrderedTypes.replaceAt(t, j);
    }

    return NO_ERROR;
}

sp<ResourceTable::Package> ResourceTable::getPackage(const String16& package)
{
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) {
        if (mIsAppPackage) {
            if (mHaveAppPackage) {
                fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
                                "Use -x to create extended resources.\n");
                return NULL;
            }
            mHaveAppPackage = true;
            p = new Package(package, 127);
        } else {
            p = new Package(package, mNextPackageId);
        }
        //printf("*** NEW PACKAGE: \"%s\" id=%d\n",
        //       String8(package).string(), p->getAssignedId());
        mPackages.add(package, p);
        mOrderedPackages.add(p);
        mNextPackageId++;
    }
    return p;
}

sp<ResourceTable::Type> ResourceTable::getType(const String16& package,
                                               const String16& type,
                                               const SourcePos& sourcePos,
                                               bool doSetIndex)
{
    sp<Package> p = getPackage(package);
    if (p == NULL) {
        return NULL;
    }
    return p->getType(type, sourcePos, doSetIndex);
}

sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
                                                 const String16& type,
                                                 const String16& name,
                                                 const SourcePos& sourcePos,
                                                 bool overlay,
                                                 const ResTable_config* config,
                                                 bool doSetIndex)
{
    sp<Type> t = getType(package, type, sourcePos, doSetIndex);
    if (t == NULL) {
        return NULL;
    }
    return t->getEntry(name, sourcePos, config, doSetIndex, overlay, mBundle->getAutoAddOverlay());
}

sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
                                                       const ResTable_config* config) const
{
    int pid = Res_GETPACKAGE(resID)+1;
    const size_t N = mOrderedPackages.size();
    size_t i;
    sp<Package> p;
    for (i=0; i<N; i++) {
        sp<Package> check = mOrderedPackages[i];
        if (check->getAssignedId() == pid) {
            p = check;
            break;
        }

    }
    if (p == NULL) {
        fprintf(stderr, "warning: Package not found for resource #%08x\n", resID);
        return NULL;
    }

    int tid = Res_GETTYPE(resID);
    if (tid < 0 || tid >= (int)p->getOrderedTypes().size()) {
        fprintf(stderr, "warning: Type not found for resource #%08x\n", resID);
        return NULL;
    }
    sp<Type> t = p->getOrderedTypes()[tid];

    int eid = Res_GETENTRY(resID);
    if (eid < 0 || eid >= (int)t->getOrderedConfigs().size()) {
        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
        return NULL;
    }

    sp<ConfigList> c = t->getOrderedConfigs()[eid];
    if (c == NULL) {
        fprintf(stderr, "warning: Entry not found for resource #%08x\n", resID);
        return NULL;
    }
    
    ConfigDescription cdesc;
    if (config) cdesc = *config;
    sp<Entry> e = c->getEntries().valueFor(cdesc);
    if (c == NULL) {
        fprintf(stderr, "warning: Entry configuration not found for resource #%08x\n", resID);
        return NULL;
    }
    
    return e;
}

const ResourceTable::Item* ResourceTable::getItem(uint32_t resID, uint32_t attrID) const
{
    sp<const Entry> e = getEntry(resID);
    if (e == NULL) {
        return NULL;
    }

    const size_t N = e->getBag().size();
    for (size_t i=0; i<N; i++) {
        const Item& it = e->getBag().valueAt(i);
        if (it.bagKeyId == 0) {
            fprintf(stderr, "warning: ID not yet assigned to '%s' in bag '%s'\n",
                    String8(e->getName()).string(),
                    String8(e->getBag().keyAt(i)).string());
        }
        if (it.bagKeyId == attrID) {
            return &it;
        }
    }

    return NULL;
}

bool ResourceTable::getItemValue(
    uint32_t resID, uint32_t attrID, Res_value* outValue)
{
    const Item* item = getItem(resID, attrID);

    bool res = false;
    if (item != NULL) {
        if (item->evaluating) {
            sp<const Entry> e = getEntry(resID);
            const size_t N = e->getBag().size();
            size_t i;
            for (i=0; i<N; i++) {
                if (&e->getBag().valueAt(i) == item) {
                    break;
                }
            }
            fprintf(stderr, "warning: Circular reference detected in key '%s' of bag '%s'\n",
                    String8(e->getName()).string(),
                    String8(e->getBag().keyAt(i)).string());
            return false;
        }
        item->evaluating = true;
        res = stringToValue(outValue, NULL, item->value, false, false, item->bagKeyId);
        NOISY(
            if (res) {
                printf("getItemValue of #%08x[#%08x] (%s): type=#%08x, data=#%08x\n",
                       resID, attrID, String8(getEntry(resID)->getName()).string(),
                       outValue->dataType, outValue->data);
            } else {
                printf("getItemValue of #%08x[#%08x]: failed\n",
                       resID, attrID);
            }
        );
        item->evaluating = false;
    }
    return res;
}
