diff --git a/include/androidfw/Asset.h b/include/androidfw/Asset.h
new file mode 100644
index 0000000..1fe0e06
--- /dev/null
+++ b/include/androidfw/Asset.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Class providing access to a read-only asset.  Asset objects are NOT
+// thread-safe, and should not be shared across threads.
+//
+#ifndef __LIBS_ASSET_H
+#define __LIBS_ASSET_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <utils/Compat.h>
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * Instances of this class provide read-only operations on a byte stream.
+ *
+ * Access may be optimized for streaming, random, or whole buffer modes.  All
+ * operations are supported regardless of how the file was opened, but some
+ * things will be less efficient.  [pass that in??]
+ *
+ * "Asset" is the base class for all types of assets.  The classes below
+ * provide most of the implementation.  The AssetManager uses one of the
+ * static "create" functions defined here to create a new instance.
+ */
+class Asset {
+public:
+    virtual ~Asset(void);
+
+    static int32_t getGlobalCount();
+    static String8 getAssetAllocations();
+    
+    /* used when opening an asset */
+    typedef enum AccessMode {
+        ACCESS_UNKNOWN = 0,
+
+        /* read chunks, and seek forward and backward */
+        ACCESS_RANDOM,
+
+        /* read sequentially, with an occasional forward seek */
+        ACCESS_STREAMING,
+
+        /* caller plans to ask for a read-only buffer with all data */
+        ACCESS_BUFFER,
+    } AccessMode;
+
+    /*
+     * Read data from the current offset.  Returns the actual number of
+     * bytes read, 0 on EOF, or -1 on error.
+     */
+    virtual ssize_t read(void* buf, size_t count) = 0;
+
+    /*
+     * Seek to the specified offset.  "whence" uses the same values as
+     * lseek/fseek.  Returns the new position on success, or (off64_t) -1
+     * on failure.
+     */
+    virtual off64_t seek(off64_t offset, int whence) = 0;
+
+    /*
+     * Close the asset, freeing all associated resources.
+     */
+    virtual void close(void) = 0;
+
+    /*
+     * Get a pointer to a buffer with the entire contents of the file.
+     */
+    virtual const void* getBuffer(bool wordAligned) = 0;
+
+    /*
+     * Get the total amount of data that can be read.
+     */
+    virtual off64_t getLength(void) const = 0;
+
+    /*
+     * Get the total amount of data that can be read from the current position.
+     */
+    virtual off64_t getRemainingLength(void) const = 0;
+
+    /*
+     * Open a new file descriptor that can be used to read this asset.
+     * Returns -1 if you can not use the file descriptor (for example if the
+     * asset is compressed).
+     */
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;
+
+    /*
+     * Return whether this asset's buffer is allocated in RAM (not mmapped).
+     * Note: not virtual so it is safe to call even when being destroyed.
+     */
+    virtual bool isAllocated(void) const { return false; }
+
+    /*
+     * Get a string identifying the asset's source.  This might be a full
+     * path, it might be a colon-separated list of identifiers.
+     *
+     * This is NOT intended to be used for anything except debug output.
+     * DO NOT try to parse this or use it to open a file.
+     */
+    const char* getAssetSource(void) const { return mAssetSource.string(); }
+
+protected:
+    Asset(void);        // constructor; only invoked indirectly
+
+    /* handle common seek() housekeeping */
+    off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);
+
+    /* set the asset source string */
+    void setAssetSource(const String8& path) { mAssetSource = path; }
+
+    AccessMode getAccessMode(void) const { return mAccessMode; }
+
+private:
+    /* these operations are not implemented */
+    Asset(const Asset& src);
+    Asset& operator=(const Asset& src);
+
+    /* AssetManager needs access to our "create" functions */
+    friend class AssetManager;
+
+    /*
+     * Create the asset from a named file on disk.
+     */
+    static Asset* createFromFile(const char* fileName, AccessMode mode);
+
+    /*
+     * Create the asset from a named, compressed file on disk (e.g. ".gz").
+     */
+    static Asset* createFromCompressedFile(const char* fileName,
+        AccessMode mode);
+
+#if 0
+    /*
+     * Create the asset from a segment of an open file.  This will fail
+     * if "offset" and "length" don't fit within the bounds of the file.
+     *
+     * The asset takes ownership of the file descriptor.
+     */
+    static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,
+        AccessMode mode);
+
+    /*
+     * Create from compressed data.  "fd" should be seeked to the start of
+     * the compressed data.  This could be inside a gzip file or part of a
+     * Zip archive.
+     *
+     * The asset takes ownership of the file descriptor.
+     *
+     * This may not verify the validity of the compressed data until first
+     * use.
+     */
+    static Asset* createFromCompressedData(int fd, off64_t offset,
+        int compressionMethod, size_t compressedLength,
+        size_t uncompressedLength, AccessMode mode);
+#endif
+
+    /*
+     * Create the asset from a memory-mapped file segment.
+     *
+     * The asset takes ownership of the FileMap.
+     */
+    static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);
+
+    /*
+     * Create the asset from a memory-mapped file segment with compressed
+     * data.  "method" is a Zip archive compression method constant.
+     *
+     * The asset takes ownership of the FileMap.
+     */
+    static Asset* createFromCompressedMap(FileMap* dataMap, int method,
+        size_t uncompressedLen, AccessMode mode);
+
+
+    /*
+     * Create from a reference-counted chunk of shared memory.
+     */
+    // TODO
+
+    AccessMode  mAccessMode;        // how the asset was opened
+    String8    mAssetSource;       // debug string
+    
+    Asset*		mNext;				// linked list.
+    Asset*		mPrev;
+};
+
+
+/*
+ * ===========================================================================
+ *
+ * Innards follow.  Do not use these classes directly.
+ */
+
+/*
+ * An asset based on an uncompressed file on disk.  It may encompass the
+ * entire file or just a piece of it.  Access is through fread/fseek.
+ */
+class _FileAsset : public Asset {
+public:
+    _FileAsset(void);
+    virtual ~_FileAsset(void);
+
+    /*
+     * Use a piece of an already-open file.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);
+
+    /*
+     * Use a memory-mapped region.
+     *
+     * On success, the object takes ownership of "dataMap".
+     */
+    status_t openChunk(FileMap* dataMap);
+
+    /*
+     * Standard Asset interfaces.
+     */
+    virtual ssize_t read(void* buf, size_t count);
+    virtual off64_t seek(off64_t offset, int whence);
+    virtual void close(void);
+    virtual const void* getBuffer(bool wordAligned);
+    virtual off64_t getLength(void) const { return mLength; }
+    virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;
+    virtual bool isAllocated(void) const { return mBuf != NULL; }
+
+private:
+    off64_t     mStart;         // absolute file offset of start of chunk
+    off64_t     mLength;        // length of the chunk
+    off64_t     mOffset;        // current local offset, 0 == mStart
+    FILE*       mFp;            // for read/seek
+    char*       mFileName;      // for opening
+
+    /*
+     * To support getBuffer() we either need to read the entire thing into
+     * a buffer or memory-map it.  For small files it's probably best to
+     * just read them in.
+     */
+    enum { kReadVsMapThreshold = 4096 };
+
+    FileMap*    mMap;           // for memory map
+    unsigned char* mBuf;        // for read
+    
+    const void* ensureAlignment(FileMap* map);
+};
+
+
+/*
+ * An asset based on compressed data in a file.
+ */
+class _CompressedAsset : public Asset {
+public:
+    _CompressedAsset(void);
+    virtual ~_CompressedAsset(void);
+
+    /*
+     * Use a piece of an already-open file.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(int fd, off64_t offset, int compressionMethod,
+        size_t uncompressedLen, size_t compressedLen);
+
+    /*
+     * Use a memory-mapped region.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(FileMap* dataMap, int compressionMethod,
+        size_t uncompressedLen);
+
+    /*
+     * Standard Asset interfaces.
+     */
+    virtual ssize_t read(void* buf, size_t count);
+    virtual off64_t seek(off64_t offset, int whence);
+    virtual void close(void);
+    virtual const void* getBuffer(bool wordAligned);
+    virtual off64_t getLength(void) const { return mUncompressedLen; }
+    virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }
+    virtual bool isAllocated(void) const { return mBuf != NULL; }
+
+private:
+    off64_t     mStart;         // offset to start of compressed data
+    off64_t     mCompressedLen; // length of the compressed data
+    off64_t     mUncompressedLen; // length of the uncompressed data
+    off64_t     mOffset;        // current offset, 0 == start of uncomp data
+
+    FileMap*    mMap;           // for memory-mapped input
+    int         mFd;            // for file input
+
+    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets
+
+    unsigned char*  mBuf;       // for getBuffer()
+};
+
+// need: shared mmap version?
+
+}; // namespace android
+
+#endif // __LIBS_ASSET_H
diff --git a/include/androidfw/AssetDir.h b/include/androidfw/AssetDir.h
new file mode 100644
index 0000000..bd89d7d
--- /dev/null
+++ b/include/androidfw/AssetDir.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Access a chunk of the asset hierarchy as if it were a single directory.
+//
+#ifndef __LIBS_ASSETDIR_H
+#define __LIBS_ASSETDIR_H
+
+#include <androidfw/misc.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/SortedVector.h>
+#include <sys/types.h>
+
+namespace android {
+
+/*
+ * This provides vector-style access to a directory.  We do this rather
+ * than modeling opendir/readdir access because it's simpler and the
+ * nature of the operation requires us to have all data on hand anyway.
+ *
+ * The list of files will be sorted in ascending order by ASCII value.
+ *
+ * The contents are populated by our friend, the AssetManager.
+ */
+class AssetDir {
+public:
+    AssetDir(void)
+        : mFileInfo(NULL)
+        {}
+    virtual ~AssetDir(void) {
+        delete mFileInfo;
+    }
+
+    /*
+     * Vector-style access.
+     */
+    size_t getFileCount(void) { return mFileInfo->size(); }
+    const String8& getFileName(int idx) {
+        return mFileInfo->itemAt(idx).getFileName();
+    }
+    const String8& getSourceName(int idx) {
+        return mFileInfo->itemAt(idx).getSourceName();
+    }
+
+    /*
+     * Get the type of a file (usually regular or directory).
+     */
+    FileType getFileType(int idx) {
+        return mFileInfo->itemAt(idx).getFileType();
+    }
+
+private:
+    /* these operations are not implemented */
+    AssetDir(const AssetDir& src);
+    const AssetDir& operator=(const AssetDir& src);
+
+    friend class AssetManager;
+
+    /*
+     * This holds information about files in the asset hierarchy.
+     */
+    class FileInfo {
+    public:
+        FileInfo(void) {}
+        FileInfo(const String8& path)      // useful for e.g. svect.indexOf
+            : mFileName(path), mFileType(kFileTypeUnknown)
+            {}
+        ~FileInfo(void) {}
+        FileInfo(const FileInfo& src) {
+            copyMembers(src);
+        }
+        const FileInfo& operator= (const FileInfo& src) {
+            if (this != &src)
+                copyMembers(src);
+            return *this;
+        }
+
+        void copyMembers(const FileInfo& src) {
+            mFileName = src.mFileName;
+            mFileType = src.mFileType;
+            mSourceName = src.mSourceName;
+        }
+
+        /* need this for SortedVector; must compare only on file name */
+        bool operator< (const FileInfo& rhs) const {
+            return mFileName < rhs.mFileName;
+        }
+
+        /* used by AssetManager */
+        bool operator== (const FileInfo& rhs) const {
+            return mFileName == rhs.mFileName;
+        }
+
+        void set(const String8& path, FileType type) {
+            mFileName = path;
+            mFileType = type;
+        }
+
+        const String8& getFileName(void) const { return mFileName; }
+        void setFileName(const String8& path) { mFileName = path; }
+
+        FileType getFileType(void) const { return mFileType; }
+        void setFileType(FileType type) { mFileType = type; }
+
+        const String8& getSourceName(void) const { return mSourceName; }
+        void setSourceName(const String8& path) { mSourceName = path; }
+
+        /*
+         * Handy utility for finding an entry in a sorted vector of FileInfo.
+         * Returns the index of the matching entry, or -1 if none found.
+         */
+        static int findEntry(const SortedVector<FileInfo>* pVector,
+            const String8& fileName);
+
+    private:
+        String8    mFileName;      // filename only
+        FileType    mFileType;      // regular, directory, etc
+
+        String8    mSourceName;    // currently debug-only
+    };
+
+    /* AssetManager uses this to initialize us */
+    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }
+
+    SortedVector<FileInfo>* mFileInfo;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETDIR_H
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
new file mode 100644
index 0000000..d95b45e
--- /dev/null
+++ b/include/androidfw/AssetManager.h
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Asset management class.  AssetManager objects are thread-safe.
+//
+#ifndef __LIBS_ASSETMANAGER_H
+#define __LIBS_ASSETMANAGER_H
+
+#include <androidfw/Asset.h>
+#include <androidfw/AssetDir.h>
+#include <androidfw/ZipFileRO.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+/*
+ * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAssetManager { };
+
+#ifdef __cplusplus
+};
+#endif
+
+
+/*
+ * Now the proper C++ android-namespace definitions
+ */
+
+namespace android {
+
+class Asset;        // fwd decl for things that include Asset.h first
+class ResTable;
+struct ResTable_config;
+
+/*
+ * Every application that uses assets needs one instance of this.  A
+ * single instance may be shared across multiple threads, and a single
+ * thread may have more than one instance (the latter is discouraged).
+ *
+ * The purpose of the AssetManager is to create Asset objects.  To do
+ * this efficiently it may cache information about the locations of
+ * files it has seen.  This can be controlled with the "cacheMode"
+ * argument.
+ *
+ * The asset hierarchy may be examined like a filesystem, using
+ * AssetDir objects to peruse a single directory.
+ */
+class AssetManager : public AAssetManager {
+public:
+    typedef enum CacheMode {
+        CACHE_UNKNOWN = 0,
+        CACHE_OFF,          // don't try to cache file locations
+        CACHE_DEFER,        // construct cache as pieces are needed
+        //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time
+    } CacheMode;
+
+    AssetManager(CacheMode cacheMode = CACHE_OFF);
+    virtual ~AssetManager(void);
+
+    static int32_t getGlobalCount();
+    
+    /*                                                                       
+     * Add a new source for assets.  This can be called multiple times to
+     * look in multiple places for assets.  It can be either a directory (for
+     * finding assets as raw files on the disk) or a ZIP file.  This newly
+     * added asset path will be examined first when searching for assets,
+     * before any that were previously added.
+     *
+     * Returns "true" on success, "false" on failure.  If 'cookie' is non-NULL,
+     * then on success, *cookie is set to the value corresponding to the
+     * newly-added asset source.
+     */
+    bool addAssetPath(const String8& path, void** cookie);
+
+    /*                                                                       
+     * Convenience for adding the standard system assets.  Uses the
+     * ANDROID_ROOT environment variable to find them.
+     */
+    bool addDefaultAssets();
+
+    /*                                                                       
+     * Iterate over the asset paths in this manager.  (Previously
+     * added via addAssetPath() and addDefaultAssets().)  On first call,
+     * 'cookie' must be NULL, resulting in the first cookie being returned.
+     * Each next cookie will be returned there-after, until NULL indicating
+     * the end has been reached.
+     */
+    void* nextAssetPath(void* cookie) const;
+
+    /*                                                                       
+     * Return an asset path in the manager.  'which' must be between 0 and
+     * countAssetPaths().
+     */
+    String8 getAssetPath(void* cookie) const;
+
+    /*
+     * Set the current locale and vendor.  The locale can change during
+     * the lifetime of an AssetManager if the user updates the device's
+     * language setting.  The vendor is less likely to change.
+     *
+     * Pass in NULL to indicate no preference.
+     */
+    void setLocale(const char* locale);
+    void setVendor(const char* vendor);
+
+    /*
+     * Choose screen orientation for resources values returned.
+     */
+    void setConfiguration(const ResTable_config& config, const char* locale = NULL);
+
+    void getConfiguration(ResTable_config* outConfig) const;
+
+    typedef Asset::AccessMode AccessMode;       // typing shortcut
+
+    /*
+     * Open an asset.
+     *
+     * This will search through locale-specific and vendor-specific
+     * directories and packages to find the file.
+     *
+     * The object returned does not depend on the AssetManager.  It should
+     * be freed by calling Asset::close().
+     */
+    Asset* open(const char* fileName, AccessMode mode);
+
+    /*
+     * Open a non-asset file as an asset.
+     *
+     * This is for opening files that are included in an asset package
+     * but aren't assets.  These sit outside the usual "locale/vendor"
+     * path hierarchy, and will not be seen by "AssetDir" or included
+     * in our filename cache.
+     */
+    Asset* openNonAsset(const char* fileName, AccessMode mode);
+
+    /*
+     * Explicit non-asset file.  The file explicitly named by the cookie (the
+     * resource set to look in) and fileName will be opened and returned.
+     */
+    Asset* openNonAsset(void* cookie, const char* fileName, AccessMode mode);
+
+    /*
+     * Open a directory within the asset hierarchy.
+     *
+     * The contents of the directory are an amalgam of vendor-specific,
+     * locale-specific, and generic assets stored loosely or in asset
+     * packages.  Depending on the cache setting and previous accesses,
+     * this call may incur significant disk overhead.
+     *
+     * To open the top-level directory, pass in "".
+     */
+    AssetDir* openDir(const char* dirName);
+
+    /*
+     * Open a directory within a particular path of the asset manager.
+     *
+     * The contents of the directory are an amalgam of vendor-specific,
+     * locale-specific, and generic assets stored loosely or in asset
+     * packages.  Depending on the cache setting and previous accesses,
+     * this call may incur significant disk overhead.
+     *
+     * To open the top-level directory, pass in "".
+     */
+    AssetDir* openNonAssetDir(void* cookie, const char* dirName);
+
+    /*
+     * Get the type of a file in the asset hierarchy.  They will either
+     * be "regular" or "directory".  [Currently only works for "regular".]
+     *
+     * Can also be used as a quick test for existence of a file.
+     */
+    FileType getFileType(const char* fileName);
+
+    /*                                                                       
+     * Return the complete resource table to find things in the package.
+     */
+    const ResTable& getResources(bool required = true) const;
+
+    /*
+     * Discard cached filename information.  This only needs to be called
+     * if somebody has updated the set of "loose" files, and we want to
+     * discard our cached notion of what's where.
+     */
+    void purge(void) { purgeFileNameCacheLocked(); }
+
+    /*
+     * Return true if the files this AssetManager references are all
+     * up-to-date (have not been changed since it was created).  If false
+     * is returned, you will need to create a new AssetManager to get
+     * the current data.
+     */
+    bool isUpToDate();
+    
+    /**
+     * Get the known locales for this asset manager object.
+     */
+    void getLocales(Vector<String8>* locales) const;
+
+private:
+    struct asset_path
+    {
+        String8 path;
+        FileType type;
+        String8 idmap;
+    };
+
+    Asset* openInPathLocked(const char* fileName, AccessMode mode,
+        const asset_path& path);
+    Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+        const asset_path& path);
+    Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+        const asset_path& path, const char* locale, const char* vendor);
+    String8 createPathNameLocked(const asset_path& path, const char* locale,
+        const char* vendor);
+    String8 createPathNameLocked(const asset_path& path, const char* rootDir);
+    String8 createZipSourceNameLocked(const String8& zipFileName,
+        const String8& dirName, const String8& fileName);
+
+    ZipFileRO* getZipFileLocked(const asset_path& path);
+    Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
+    Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
+        const ZipEntryRO entry, AccessMode mode, const String8& entryName);
+
+    bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* rootDir, const char* dirName);
+    SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
+    bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* rootDir, const char* dirName);
+    void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const SortedVector<AssetDir::FileInfo>* pContents);
+
+    void loadFileNameCacheLocked(void);
+    void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const char* dirName);
+    bool fncScanAndMergeDirLocked(
+        SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* locale, const char* vendor,
+        const char* dirName);
+    void purgeFileNameCacheLocked(void);
+
+    const ResTable* getResTable(bool required = true) const;
+    void setLocaleLocked(const char* locale);
+    void updateResourceParamsLocked() const;
+
+    bool createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
+                               const String8& idmapPath);
+
+    bool isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
+                            const String8& idmapPath);
+
+    Asset* openIdmapLocked(const struct asset_path& ap) const;
+
+    bool getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename, uint32_t* pCrc);
+
+    class SharedZip : public RefBase {
+    public:
+        static sp<SharedZip> get(const String8& path);
+
+        ZipFileRO* getZip();
+
+        Asset* getResourceTableAsset();
+        Asset* setResourceTableAsset(Asset* asset);
+
+        ResTable* getResourceTable();
+        ResTable* setResourceTable(ResTable* res);
+        
+        bool isUpToDate();
+        
+    protected:
+        ~SharedZip();
+
+    private:
+        SharedZip(const String8& path, time_t modWhen);
+        SharedZip(); // <-- not implemented
+
+        String8 mPath;
+        ZipFileRO* mZipFile;
+        time_t mModWhen;
+
+        Asset* mResourceTableAsset;
+        ResTable* mResourceTable;
+
+        static Mutex gLock;
+        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
+    };
+
+    /*
+     * Manage a set of Zip files.  For each file we need a pointer to the
+     * ZipFile and a time_t with the file's modification date.
+     *
+     * We currently only have two zip files (current app, "common" app).
+     * (This was originally written for 8, based on app/locale/vendor.)
+     */
+    class ZipSet {
+    public:
+        ZipSet(void);
+        ~ZipSet(void);
+
+        /*
+         * Return a ZipFileRO structure for a ZipFileRO with the specified
+         * parameters.
+         */
+        ZipFileRO* getZip(const String8& path);
+
+        Asset* getZipResourceTableAsset(const String8& path);
+        Asset* setZipResourceTableAsset(const String8& path, Asset* asset);
+
+        ResTable* getZipResourceTable(const String8& path);
+        ResTable* setZipResourceTable(const String8& path, ResTable* res);
+
+        // generate path, e.g. "common/en-US-noogle.zip"
+        static String8 getPathName(const char* path);
+
+        bool isUpToDate();
+        
+    private:
+        void closeZip(int idx);
+
+        int getIndex(const String8& zip) const;
+        mutable Vector<String8> mZipPath;
+        mutable Vector<sp<SharedZip> > mZipFile;
+    };
+
+    // Protect all internal state.
+    mutable Mutex   mLock;
+
+    ZipSet          mZipSet;
+
+    Vector<asset_path> mAssetPaths;
+    char*           mLocale;
+    char*           mVendor;
+
+    mutable ResTable* mResources;
+    ResTable_config* mConfig;
+
+    /*
+     * Cached data for "loose" files.  This lets us avoid poking at the
+     * filesystem when searching for loose assets.  Each entry is the
+     * "extended partial" path, e.g. "default/default/foo/bar.txt".  The
+     * full set of files is present, including ".EXCLUDE" entries.
+     *
+     * We do not cache directory names.  We don't retain the ".gz",
+     * because to our clients "foo" and "foo.gz" both look like "foo".
+     */
+    CacheMode       mCacheMode;         // is the cache enabled?
+    bool            mCacheValid;        // clear when locale or vendor changes
+    SortedVector<AssetDir::FileInfo> mCache;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETMANAGER_H
diff --git a/include/androidfw/BackupHelpers.h b/include/androidfw/BackupHelpers.h
new file mode 100644
index 0000000..1bb04a7
--- /dev/null
+++ b/include/androidfw/BackupHelpers.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UTILS_BACKUP_HELPERS_H
+#define _UTILS_BACKUP_HELPERS_H
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+enum {
+    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
+};
+
+typedef struct {
+    int type; // BACKUP_HEADER_ENTITY_V1
+    int keyLen; // length of the key name, not including the null terminator
+    int dataSize; // size of the data, not including the padding, -1 means delete
+} entity_header_v1;
+
+struct SnapshotHeader {
+    int magic0;
+    int fileCount;
+    int magic1;
+    int totalSize;
+};
+
+struct FileState {
+    int modTime_sec;
+    int modTime_nsec;
+    int mode;
+    int size;
+    int crc32;
+    int nameLen;
+};
+
+struct FileRec {
+    String8 file;
+    bool deleted;
+    FileState s;
+};
+
+
+/**
+ * Writes the data.
+ *
+ * If an error occurs, it poisons this object and all write calls will fail
+ * with the error that occurred.
+ */
+class BackupDataWriter
+{
+public:
+    BackupDataWriter(int fd);
+    // does not close fd
+    ~BackupDataWriter();
+
+    status_t WriteEntityHeader(const String8& key, size_t dataSize);
+
+    /* Note: WriteEntityData will write arbitrary data into the file without
+     * validation or a previously-supplied header.  The full backup implementation
+     * uses it this way to generate a controlled binary stream that is not
+     * entity-structured.  If the implementation here is changed, either this
+     * use case must remain valid, or the full backup implementation should be
+     * adjusted to use some other appropriate mechanism.
+     */
+    status_t WriteEntityData(const void* data, size_t size);
+
+    void SetKeyPrefix(const String8& keyPrefix);
+
+private:
+    explicit BackupDataWriter();
+    status_t write_padding_for(int n);
+    
+    int m_fd;
+    status_t m_status;
+    ssize_t m_pos;
+    int m_entityCount;
+    String8 m_keyPrefix;
+};
+
+/**
+ * Reads the data.
+ *
+ * If an error occurs, it poisons this object and all write calls will fail
+ * with the error that occurred.
+ */
+class BackupDataReader
+{
+public:
+    BackupDataReader(int fd);
+    // does not close fd
+    ~BackupDataReader();
+
+    status_t Status();
+    status_t ReadNextHeader(bool* done, int* type);
+
+    bool HasEntities();
+    status_t ReadEntityHeader(String8* key, size_t* dataSize);
+    status_t SkipEntityData(); // must be called with the pointer at the beginning of the data.
+    ssize_t ReadEntityData(void* data, size_t size);
+
+private:
+    explicit BackupDataReader();
+    status_t skip_padding();
+    
+    int m_fd;
+    bool m_done;
+    status_t m_status;
+    ssize_t m_pos;
+    ssize_t m_dataEndPos;
+    int m_entityCount;
+    union {
+        int type;
+        entity_header_v1 entity;
+    } m_header;
+    String8 m_key;
+};
+
+int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
+        char const* const* files, char const* const *keys, int fileCount);
+
+int write_tarfile(const String8& packageName, const String8& domain,
+        const String8& rootPath, const String8& filePath, BackupDataWriter* outputStream);
+
+class RestoreHelperBase
+{
+public:
+    RestoreHelperBase();
+    ~RestoreHelperBase();
+
+    status_t WriteFile(const String8& filename, BackupDataReader* in);
+    status_t WriteSnapshot(int fd);
+
+private:
+    void* m_buf;
+    bool m_loggedUnknownMetadata;
+    KeyedVector<String8,FileRec> m_files;
+};
+
+#define TEST_BACKUP_HELPERS 1
+
+#if TEST_BACKUP_HELPERS
+int backup_helper_test_empty();
+int backup_helper_test_four();
+int backup_helper_test_files();
+int backup_helper_test_null_base();
+int backup_helper_test_missing_file();
+int backup_helper_test_data_writer();
+int backup_helper_test_data_reader();
+#endif
+
+} // namespace android
+
+#endif // _UTILS_BACKUP_HELPERS_H
diff --git a/include/androidfw/CursorWindow.h b/include/androidfw/CursorWindow.h
new file mode 100644
index 0000000..8a2979a
--- /dev/null
+++ b/include/androidfw/CursorWindow.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID__DATABASE_WINDOW_H
+#define _ANDROID__DATABASE_WINDOW_H
+
+#include <cutils/log.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+#if LOG_NDEBUG
+
+#define IF_LOG_WINDOW() if (false)
+#define LOG_WINDOW(...)
+
+#else
+
+#define IF_LOG_WINDOW() IF_ALOG(LOG_DEBUG, "CursorWindow")
+#define LOG_WINDOW(...) ALOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
+
+#endif
+
+namespace android {
+
+/**
+ * This class stores a set of rows from a database in a buffer. The begining of the
+ * window has first chunk of RowSlots, which are offsets to the row directory, followed by
+ * an offset to the next chunk in a linked-list of additional chunk of RowSlots in case
+ * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
+ * FieldSlot per column, which has the size, offset, and type of the data for that field.
+ * Note that the data types come from sqlite3.h.
+ *
+ * Strings are stored in UTF-8.
+ */
+class CursorWindow {
+    CursorWindow(const String8& name, int ashmemFd,
+            void* data, size_t size, bool readOnly);
+
+public:
+    /* Field types. */
+    enum {
+        FIELD_TYPE_NULL = 0,
+        FIELD_TYPE_INTEGER = 1,
+        FIELD_TYPE_FLOAT = 2,
+        FIELD_TYPE_STRING = 3,
+        FIELD_TYPE_BLOB = 4,
+    };
+
+    /* Opaque type that describes a field slot. */
+    struct FieldSlot {
+    private:
+        int32_t type;
+        union {
+            double d;
+            int64_t l;
+            struct {
+                uint32_t offset;
+                uint32_t size;
+            } buffer;
+        } data;
+
+        friend class CursorWindow;
+    } __attribute((packed));
+
+    ~CursorWindow();
+
+    static status_t create(const String8& name, size_t size, CursorWindow** outCursorWindow);
+    static status_t createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow);
+
+    status_t writeToParcel(Parcel* parcel);
+
+    inline String8 name() { return mName; }
+    inline size_t size() { return mSize; }
+    inline size_t freeSpace() { return mSize - mHeader->freeOffset; }
+    inline uint32_t getNumRows() { return mHeader->numRows; }
+    inline uint32_t getNumColumns() { return mHeader->numColumns; }
+
+    status_t clear();
+    status_t setNumColumns(uint32_t numColumns);
+
+    /**
+     * Allocate a row slot and its directory.
+     * The row is initialized will null entries for each field.
+     */
+    status_t allocRow();
+    status_t freeLastRow();
+
+    status_t putBlob(uint32_t row, uint32_t column, const void* value, size_t size);
+    status_t putString(uint32_t row, uint32_t column, const char* value, size_t sizeIncludingNull);
+    status_t putLong(uint32_t row, uint32_t column, int64_t value);
+    status_t putDouble(uint32_t row, uint32_t column, double value);
+    status_t putNull(uint32_t row, uint32_t column);
+
+    /**
+     * Gets the field slot at the specified row and column.
+     * Returns null if the requested row or column is not in the window.
+     */
+    FieldSlot* getFieldSlot(uint32_t row, uint32_t column);
+
+    inline int32_t getFieldSlotType(FieldSlot* fieldSlot) {
+        return fieldSlot->type;
+    }
+
+    inline int64_t getFieldSlotValueLong(FieldSlot* fieldSlot) {
+        return fieldSlot->data.l;
+    }
+
+    inline double getFieldSlotValueDouble(FieldSlot* fieldSlot) {
+        return fieldSlot->data.d;
+    }
+
+    inline const char* getFieldSlotValueString(FieldSlot* fieldSlot,
+            size_t* outSizeIncludingNull) {
+        *outSizeIncludingNull = fieldSlot->data.buffer.size;
+        return static_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
+    }
+
+    inline const void* getFieldSlotValueBlob(FieldSlot* fieldSlot, size_t* outSize) {
+        *outSize = fieldSlot->data.buffer.size;
+        return offsetToPtr(fieldSlot->data.buffer.offset);
+    }
+
+private:
+    static const size_t ROW_SLOT_CHUNK_NUM_ROWS = 100;
+
+    struct Header {
+        // Offset of the lowest unused byte in the window.
+        uint32_t freeOffset;
+
+        // Offset of the first row slot chunk.
+        uint32_t firstChunkOffset;
+
+        uint32_t numRows;
+        uint32_t numColumns;
+    };
+
+    struct RowSlot {
+        uint32_t offset;
+    };
+
+    struct RowSlotChunk {
+        RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS];
+        uint32_t nextChunkOffset;
+    };
+
+    String8 mName;
+    int mAshmemFd;
+    void* mData;
+    size_t mSize;
+    bool mReadOnly;
+    Header* mHeader;
+
+    inline void* offsetToPtr(uint32_t offset) {
+        return static_cast<uint8_t*>(mData) + offset;
+    }
+
+    inline uint32_t offsetFromPtr(void* ptr) {
+        return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
+    }
+
+    /**
+     * Allocate a portion of the window. Returns the offset
+     * of the allocation, or 0 if there isn't enough space.
+     * If aligned is true, the allocation gets 4 byte alignment.
+     */
+    uint32_t alloc(size_t size, bool aligned = false);
+
+    RowSlot* getRowSlot(uint32_t row);
+    RowSlot* allocRowSlot();
+
+    status_t putBlobOrString(uint32_t row, uint32_t column,
+            const void* value, size_t size, int32_t type);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/androidfw/ObbFile.h b/include/androidfw/ObbFile.h
new file mode 100644
index 0000000..47559cd
--- /dev/null
+++ b/include/androidfw/ObbFile.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OBBFILE_H_
+#define OBBFILE_H_
+
+#include <stdint.h>
+#include <strings.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// OBB flags (bit 0)
+#define OBB_OVERLAY         (1 << 0)
+#define OBB_SALTED          (1 << 1)
+
+class ObbFile : public RefBase {
+protected:
+    virtual ~ObbFile();
+
+public:
+    ObbFile();
+
+    bool readFrom(const char* filename);
+    bool readFrom(int fd);
+    bool writeTo(const char* filename);
+    bool writeTo(int fd);
+    bool removeFrom(const char* filename);
+    bool removeFrom(int fd);
+
+    const char* getFileName() const {
+        return mFileName;
+    }
+
+    const String8 getPackageName() const {
+        return mPackageName;
+    }
+
+    void setPackageName(String8 packageName) {
+        mPackageName = packageName;
+    }
+
+    int32_t getVersion() const {
+        return mVersion;
+    }
+
+    void setVersion(int32_t version) {
+        mVersion = version;
+    }
+
+    int32_t getFlags() const {
+        return mFlags;
+    }
+
+    void setFlags(int32_t flags) {
+        mFlags = flags;
+    }
+
+    const unsigned char* getSalt(size_t* length) const {
+        if ((mFlags & OBB_SALTED) == 0) {
+            *length = 0;
+            return NULL;
+        }
+
+        *length = sizeof(mSalt);
+        return mSalt;
+    }
+
+    bool setSalt(const unsigned char* salt, size_t length) {
+        if (length != sizeof(mSalt)) {
+            return false;
+        }
+
+        memcpy(mSalt, salt, sizeof(mSalt));
+        mFlags |= OBB_SALTED;
+        return true;
+    }
+
+    bool isOverlay() {
+        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
+    }
+
+    void setOverlay(bool overlay) {
+        if (overlay) {
+            mFlags |= OBB_OVERLAY;
+        } else {
+            mFlags &= ~OBB_OVERLAY;
+        }
+    }
+
+    static inline uint32_t get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+    static inline void put4LE(unsigned char* buf, uint32_t val) {
+        buf[0] = val & 0xFF;
+        buf[1] = (val >> 8) & 0xFF;
+        buf[2] = (val >> 16) & 0xFF;
+        buf[3] = (val >> 24) & 0xFF;
+    }
+
+private:
+    /* Package name this ObbFile is associated with */
+    String8 mPackageName;
+
+    /* Package version this ObbFile is associated with */
+    int32_t mVersion;
+
+    /* Flags for this OBB type. */
+    int32_t mFlags;
+
+    /* Whether the file is salted. */
+    bool mSalted;
+
+    /* The encryption salt. */
+    unsigned char mSalt[8];
+
+    const char* mFileName;
+
+    size_t mFileSize;
+
+    size_t mFooterStart;
+
+    unsigned char* mReadBuf;
+
+    bool parseObbFile(int fd);
+};
+
+}
+#endif /* OBBFILE_H_ */
diff --git a/include/androidfw/PowerManager.h b/include/androidfw/PowerManager.h
new file mode 100644
index 0000000..ba98db0
--- /dev/null
+++ b/include/androidfw/PowerManager.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROIDFW_POWER_MANAGER_H
+#define _ANDROIDFW_POWER_MANAGER_H
+
+
+namespace android {
+
+enum {
+    USER_ACTIVITY_EVENT_OTHER = 0,
+    USER_ACTIVITY_EVENT_BUTTON = 1,
+    USER_ACTIVITY_EVENT_TOUCH = 2,
+
+    USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code.
+};
+
+} // namespace android
+
+#endif // _ANDROIDFW_POWER_MANAGER_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
new file mode 100644
index 0000000..97afa59
--- /dev/null
+++ b/include/androidfw/ResourceTypes.h
@@ -0,0 +1,1605 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Definitions of resource data structures.
+//
+#ifndef _LIBS_UTILS_RESOURCE_TYPES_H
+#define _LIBS_UTILS_RESOURCE_TYPES_H
+
+#include <androidfw/Asset.h>
+#include <utils/ByteOrder.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+#include <utils/threads.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <android/configuration.h>
+
+namespace android {
+
+/** ********************************************************************
+ *  PNG Extensions
+ *
+ *  New private chunks that may be placed in PNG images.
+ *
+ *********************************************************************** */
+
+/**
+ * This chunk specifies how to split an image into segments for
+ * scaling.
+ *
+ * There are J horizontal and K vertical segments.  These segments divide
+ * the image into J*K regions as follows (where J=4 and K=3):
+ *
+ *      F0   S0    F1     S1
+ *   +-----+----+------+-------+
+ * S2|  0  |  1 |  2   |   3   |
+ *   +-----+----+------+-------+
+ *   |     |    |      |       |
+ *   |     |    |      |       |
+ * F2|  4  |  5 |  6   |   7   |
+ *   |     |    |      |       |
+ *   |     |    |      |       |
+ *   +-----+----+------+-------+
+ * S3|  8  |  9 |  10  |   11  |
+ *   +-----+----+------+-------+
+ *
+ * Each horizontal and vertical segment is considered to by either
+ * stretchable (marked by the Sx labels) or fixed (marked by the Fy
+ * labels), in the horizontal or vertical axis, respectively. In the
+ * above example, the first is horizontal segment (F0) is fixed, the
+ * next is stretchable and then they continue to alternate. Note that
+ * the segment list for each axis can begin or end with a stretchable
+ * or fixed segment.
+ *
+ * The relative sizes of the stretchy segments indicates the relative
+ * amount of stretchiness of the regions bordered by the segments.  For
+ * example, regions 3, 7 and 11 above will take up more horizontal space
+ * than regions 1, 5 and 9 since the horizontal segment associated with
+ * the first set of regions is larger than the other set of regions.  The
+ * ratios of the amount of horizontal (or vertical) space taken by any
+ * two stretchable slices is exactly the ratio of their corresponding
+ * segment lengths.
+ *
+ * xDivs and yDivs point to arrays of horizontal and vertical pixel
+ * indices.  The first pair of Divs (in either array) indicate the
+ * starting and ending points of the first stretchable segment in that
+ * axis. The next pair specifies the next stretchable segment, etc. So
+ * in the above example xDiv[0] and xDiv[1] specify the horizontal
+ * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and
+ * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
+ * the leftmost slices always start at x=0 and the rightmost slices
+ * always end at the end of the image. So, for example, the regions 0,
+ * 4 and 8 (which are fixed along the X axis) start at x value 0 and
+ * go to xDiv[0] and slices 2, 6 and 10 start at xDiv[1] and end at
+ * xDiv[2].
+ *
+ * The array pointed to by the colors field lists contains hints for
+ * each of the regions.  They are ordered according left-to-right and
+ * top-to-bottom as indicated above. For each segment that is a solid
+ * color the array entry will contain that color value; otherwise it
+ * will contain NO_COLOR.  Segments that are completely transparent
+ * will always have the value TRANSPARENT_COLOR.
+ *
+ * The PNG chunk type is "npTc".
+ */
+struct Res_png_9patch
+{
+    Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
+                       yDivs(NULL), colors(NULL) { }
+
+    int8_t wasDeserialized;
+    int8_t numXDivs;
+    int8_t numYDivs;
+    int8_t numColors;
+
+    // These tell where the next section of a patch starts.
+    // For example, the first patch includes the pixels from
+    // 0 to xDivs[0]-1 and the second patch includes the pixels
+    // from xDivs[0] to xDivs[1]-1.
+    // Note: allocation/free of these pointers is left to the caller.
+    int32_t* xDivs;
+    int32_t* yDivs;
+
+    int32_t paddingLeft, paddingRight;
+    int32_t paddingTop, paddingBottom;
+
+    enum {
+        // The 9 patch segment is not a solid color.
+        NO_COLOR = 0x00000001,
+
+        // The 9 patch segment is completely transparent.
+        TRANSPARENT_COLOR = 0x00000000
+    };
+    // Note: allocation/free of this pointer is left to the caller.
+    uint32_t* colors;
+
+    // Convert data from device representation to PNG file representation.
+    void deviceToFile();
+    // Convert data from PNG file representation to device representation.
+    void fileToDevice();
+    // Serialize/Marshall the patch data into a newly malloc-ed block
+    void* serialize();
+    // Serialize/Marshall the patch data
+    void serialize(void* outData);
+    // Deserialize/Unmarshall the patch data
+    static Res_png_9patch* deserialize(const void* data);
+    // Compute the size of the serialized data structure
+    size_t serializedSize();
+};
+
+/** ********************************************************************
+ *  Base Types
+ *
+ *  These are standard types that are shared between multiple specific
+ *  resource types.
+ *
+ *********************************************************************** */
+
+/**
+ * Header that appears at the front of every data chunk in a resource.
+ */
+struct ResChunk_header
+{
+    // Type identifier for this chunk.  The meaning of this value depends
+    // on the containing chunk.
+    uint16_t type;
+
+    // Size of the chunk header (in bytes).  Adding this value to
+    // the address of the chunk allows you to find its associated data
+    // (if any).
+    uint16_t headerSize;
+
+    // Total size of this chunk (in bytes).  This is the chunkSize plus
+    // the size of any data associated with the chunk.  Adding this value
+    // to the chunk allows you to completely skip its contents (including
+    // any child chunks).  If this value is the same as chunkSize, there is
+    // no data associated with the chunk.
+    uint32_t size;
+};
+
+enum {
+    RES_NULL_TYPE               = 0x0000,
+    RES_STRING_POOL_TYPE        = 0x0001,
+    RES_TABLE_TYPE              = 0x0002,
+    RES_XML_TYPE                = 0x0003,
+
+    // Chunk types in RES_XML_TYPE
+    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
+    RES_XML_START_NAMESPACE_TYPE= 0x0100,
+    RES_XML_END_NAMESPACE_TYPE  = 0x0101,
+    RES_XML_START_ELEMENT_TYPE  = 0x0102,
+    RES_XML_END_ELEMENT_TYPE    = 0x0103,
+    RES_XML_CDATA_TYPE          = 0x0104,
+    RES_XML_LAST_CHUNK_TYPE     = 0x017f,
+    // This contains a uint32_t array mapping strings in the string
+    // pool back to resource identifiers.  It is optional.
+    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,
+
+    // Chunk types in RES_TABLE_TYPE
+    RES_TABLE_PACKAGE_TYPE      = 0x0200,
+    RES_TABLE_TYPE_TYPE         = 0x0201,
+    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202
+};
+
+/**
+ * Macros for building/splitting resource identifiers.
+ */
+#define Res_VALIDID(resid) (resid != 0)
+#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)
+#define Res_MAKEID(package, type, entry) \
+    (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))
+#define Res_GETPACKAGE(id) ((id>>24)-1)
+#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
+#define Res_GETENTRY(id) (id&0xFFFF)
+
+#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)
+#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
+#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
+
+#define Res_MAXPACKAGE 255
+
+/**
+ * Representation of a value in a resource, supplying type
+ * information.
+ */
+struct Res_value
+{
+    // Number of bytes in this structure.
+    uint16_t size;
+
+    // Always set to 0.
+    uint8_t res0;
+        
+    // Type of the data value.
+    enum {
+        // Contains no data.
+        TYPE_NULL = 0x00,
+        // The 'data' holds a ResTable_ref, a reference to another resource
+        // table entry.
+        TYPE_REFERENCE = 0x01,
+        // The 'data' holds an attribute resource identifier.
+        TYPE_ATTRIBUTE = 0x02,
+        // The 'data' holds an index into the containing resource table's
+        // global value string pool.
+        TYPE_STRING = 0x03,
+        // The 'data' holds a single-precision floating point number.
+        TYPE_FLOAT = 0x04,
+        // The 'data' holds a complex number encoding a dimension value,
+        // such as "100in".
+        TYPE_DIMENSION = 0x05,
+        // The 'data' holds a complex number encoding a fraction of a
+        // container.
+        TYPE_FRACTION = 0x06,
+
+        // Beginning of integer flavors...
+        TYPE_FIRST_INT = 0x10,
+
+        // The 'data' is a raw integer value of the form n..n.
+        TYPE_INT_DEC = 0x10,
+        // The 'data' is a raw integer value of the form 0xn..n.
+        TYPE_INT_HEX = 0x11,
+        // The 'data' is either 0 or 1, for input "false" or "true" respectively.
+        TYPE_INT_BOOLEAN = 0x12,
+
+        // Beginning of color integer flavors...
+        TYPE_FIRST_COLOR_INT = 0x1c,
+
+        // The 'data' is a raw integer value of the form #aarrggbb.
+        TYPE_INT_COLOR_ARGB8 = 0x1c,
+        // The 'data' is a raw integer value of the form #rrggbb.
+        TYPE_INT_COLOR_RGB8 = 0x1d,
+        // The 'data' is a raw integer value of the form #argb.
+        TYPE_INT_COLOR_ARGB4 = 0x1e,
+        // The 'data' is a raw integer value of the form #rgb.
+        TYPE_INT_COLOR_RGB4 = 0x1f,
+
+        // ...end of integer flavors.
+        TYPE_LAST_COLOR_INT = 0x1f,
+
+        // ...end of integer flavors.
+        TYPE_LAST_INT = 0x1f
+    };
+    uint8_t dataType;
+
+    // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
+    enum {
+        // Where the unit type information is.  This gives us 16 possible
+        // types, as defined below.
+        COMPLEX_UNIT_SHIFT = 0,
+        COMPLEX_UNIT_MASK = 0xf,
+
+        // TYPE_DIMENSION: Value is raw pixels.
+        COMPLEX_UNIT_PX = 0,
+        // TYPE_DIMENSION: Value is Device Independent Pixels.
+        COMPLEX_UNIT_DIP = 1,
+        // TYPE_DIMENSION: Value is a Scaled device independent Pixels.
+        COMPLEX_UNIT_SP = 2,
+        // TYPE_DIMENSION: Value is in points.
+        COMPLEX_UNIT_PT = 3,
+        // TYPE_DIMENSION: Value is in inches.
+        COMPLEX_UNIT_IN = 4,
+        // TYPE_DIMENSION: Value is in millimeters.
+        COMPLEX_UNIT_MM = 5,
+
+        // TYPE_FRACTION: A basic fraction of the overall size.
+        COMPLEX_UNIT_FRACTION = 0,
+        // TYPE_FRACTION: A fraction of the parent size.
+        COMPLEX_UNIT_FRACTION_PARENT = 1,
+
+        // Where the radix information is, telling where the decimal place
+        // appears in the mantissa.  This give us 4 possible fixed point
+        // representations as defined below.
+        COMPLEX_RADIX_SHIFT = 4,
+        COMPLEX_RADIX_MASK = 0x3,
+
+        // The mantissa is an integral number -- i.e., 0xnnnnnn.0
+        COMPLEX_RADIX_23p0 = 0,
+        // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
+        COMPLEX_RADIX_16p7 = 1,
+        // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
+        COMPLEX_RADIX_8p15 = 2,
+        // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
+        COMPLEX_RADIX_0p23 = 3,
+
+        // Where the actual value is.  This gives us 23 bits of
+        // precision.  The top bit is the sign.
+        COMPLEX_MANTISSA_SHIFT = 8,
+        COMPLEX_MANTISSA_MASK = 0xffffff
+    };
+
+    // The data for this item, as interpreted according to dataType.
+    uint32_t data;
+
+    void copyFrom_dtoh(const Res_value& src);
+};
+
+/**
+ *  This is a reference to a unique entry (a ResTable_entry structure)
+ *  in a resource table.  The value is structured as: 0xpptteeee,
+ *  where pp is the package index, tt is the type index in that
+ *  package, and eeee is the entry index in that type.  The package
+ *  and type values start at 1 for the first item, to help catch cases
+ *  where they have not been supplied.
+ */
+struct ResTable_ref
+{
+    uint32_t ident;
+};
+
+/**
+ * Reference to a string in a string pool.
+ */
+struct ResStringPool_ref
+{
+    // Index into the string pool table (uint32_t-offset from the indices
+    // immediately after ResStringPool_header) at which to find the location
+    // of the string data in the pool.
+    uint32_t index;
+};
+
+/** ********************************************************************
+ *  String Pool
+ *
+ *  A set of strings that can be references by others through a
+ *  ResStringPool_ref.
+ *
+ *********************************************************************** */
+
+/**
+ * Definition for a pool of strings.  The data of this chunk is an
+ * array of uint32_t providing indices into the pool, relative to
+ * stringsStart.  At stringsStart are all of the UTF-16 strings
+ * concatenated together; each starts with a uint16_t of the string's
+ * length and each ends with a 0x0000 terminator.  If a string is >
+ * 32767 characters, the high bit of the length is set meaning to take
+ * those 15 bits as a high word and it will be followed by another
+ * uint16_t containing the low word.
+ *
+ * If styleCount is not zero, then immediately following the array of
+ * uint32_t indices into the string table is another array of indices
+ * into a style table starting at stylesStart.  Each entry in the
+ * style table is an array of ResStringPool_span structures.
+ */
+struct ResStringPool_header
+{
+    struct ResChunk_header header;
+
+    // Number of strings in this pool (number of uint32_t indices that follow
+    // in the data).
+    uint32_t stringCount;
+
+    // Number of style span arrays in the pool (number of uint32_t indices
+    // follow the string indices).
+    uint32_t styleCount;
+
+    // Flags.
+    enum {
+        // If set, the string index is sorted by the string values (based
+        // on strcmp16()).
+        SORTED_FLAG = 1<<0,
+
+        // String pool is encoded in UTF-8
+        UTF8_FLAG = 1<<8
+    };
+    uint32_t flags;
+
+    // Index from header of the string data.
+    uint32_t stringsStart;
+
+    // Index from header of the style data.
+    uint32_t stylesStart;
+};
+
+/**
+ * This structure defines a span of style information associated with
+ * a string in the pool.
+ */
+struct ResStringPool_span
+{
+    enum {
+        END = 0xFFFFFFFF
+    };
+
+    // This is the name of the span -- that is, the name of the XML
+    // tag that defined it.  The special value END (0xFFFFFFFF) indicates
+    // the end of an array of spans.
+    ResStringPool_ref name;
+
+    // The range of characters in the string that this span applies to.
+    uint32_t firstChar, lastChar;
+};
+
+/**
+ * Convenience class for accessing data in a ResStringPool resource.
+ */
+class ResStringPool
+{
+public:
+    ResStringPool();
+    ResStringPool(const void* data, size_t size, bool copyData=false);
+    ~ResStringPool();
+
+    status_t setTo(const void* data, size_t size, bool copyData=false);
+
+    status_t getError() const;
+
+    void uninit();
+
+    // Return string entry as UTF16; if the pool is UTF8, the string will
+    // be converted before returning.
+    inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
+        return stringAt(ref.index, outLen);
+    }
+    const char16_t* stringAt(size_t idx, size_t* outLen) const;
+
+    // Note: returns null if the string pool is not UTF8.
+    const char* string8At(size_t idx, size_t* outLen) const;
+
+    // Return string whether the pool is UTF8 or UTF16.  Does not allow you
+    // to distinguish null.
+    const String8 string8ObjectAt(size_t idx) const;
+
+    const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
+    const ResStringPool_span* styleAt(size_t idx) const;
+
+    ssize_t indexOfString(const char16_t* str, size_t strLen) const;
+
+    size_t size() const;
+    size_t styleCount() const;
+    size_t bytes() const;
+
+    bool isSorted() const;
+    bool isUTF8() const;
+
+private:
+    status_t                    mError;
+    void*                       mOwnedData;
+    const ResStringPool_header* mHeader;
+    size_t                      mSize;
+    mutable Mutex               mDecodeLock;
+    const uint32_t*             mEntries;
+    const uint32_t*             mEntryStyles;
+    const void*                 mStrings;
+    char16_t mutable**          mCache;
+    uint32_t                    mStringPoolSize;    // number of uint16_t
+    const uint32_t*             mStyles;
+    uint32_t                    mStylePoolSize;    // number of uint32_t
+};
+
+/** ********************************************************************
+ *  XML Tree
+ *
+ *  Binary representation of an XML document.  This is designed to
+ *  express everything in an XML document, in a form that is much
+ *  easier to parse on the device.
+ *
+ *********************************************************************** */
+
+/**
+ * XML tree header.  This appears at the front of an XML tree,
+ * describing its content.  It is followed by a flat array of
+ * ResXMLTree_node structures; the hierarchy of the XML document
+ * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
+ * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
+ */
+struct ResXMLTree_header
+{
+    struct ResChunk_header header;
+};
+
+/**
+ * Basic XML tree node.  A single item in the XML document.  Extended info
+ * about the node can be found after header.headerSize.
+ */
+struct ResXMLTree_node
+{
+    struct ResChunk_header header;
+
+    // Line number in original source file at which this element appeared.
+    uint32_t lineNumber;
+
+    // Optional XML comment that was associated with this element; -1 if none.
+    struct ResStringPool_ref comment;
+};
+
+/**
+ * Extended XML tree node for CDATA tags -- includes the CDATA string.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_cdataExt
+{
+    // The raw CDATA character data.
+    struct ResStringPool_ref data;
+    
+    // The typed value of the character data if this is a CDATA node.
+    struct Res_value typedData;
+};
+
+/**
+ * Extended XML tree node for namespace start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_namespaceExt
+{
+    // The prefix of the namespace.
+    struct ResStringPool_ref prefix;
+    
+    // The URI of the namespace.
+    struct ResStringPool_ref uri;
+};
+
+/**
+ * Extended XML tree node for element start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_endElementExt
+{
+    // String of the full namespace of this element.
+    struct ResStringPool_ref ns;
+    
+    // String name of this node if it is an ELEMENT; the raw
+    // character data if this is a CDATA node.
+    struct ResStringPool_ref name;
+};
+
+/**
+ * Extended XML tree node for start tags -- includes attribute
+ * information.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_attrExt
+{
+    // String of the full namespace of this element.
+    struct ResStringPool_ref ns;
+    
+    // String name of this node if it is an ELEMENT; the raw
+    // character data if this is a CDATA node.
+    struct ResStringPool_ref name;
+    
+    // Byte offset from the start of this structure where the attributes start.
+    uint16_t attributeStart;
+    
+    // Size of the ResXMLTree_attribute structures that follow.
+    uint16_t attributeSize;
+    
+    // Number of attributes associated with an ELEMENT.  These are
+    // available as an array of ResXMLTree_attribute structures
+    // immediately following this node.
+    uint16_t attributeCount;
+    
+    // Index (1-based) of the "id" attribute. 0 if none.
+    uint16_t idIndex;
+    
+    // Index (1-based) of the "class" attribute. 0 if none.
+    uint16_t classIndex;
+    
+    // Index (1-based) of the "style" attribute. 0 if none.
+    uint16_t styleIndex;
+};
+
+struct ResXMLTree_attribute
+{
+    // Namespace of this attribute.
+    struct ResStringPool_ref ns;
+    
+    // Name of this attribute.
+    struct ResStringPool_ref name;
+
+    // The original raw string value of this attribute.
+    struct ResStringPool_ref rawValue;
+    
+    // Processesd typed value of this attribute.
+    struct Res_value typedValue;
+};
+
+class ResXMLTree;
+
+class ResXMLParser
+{
+public:
+    ResXMLParser(const ResXMLTree& tree);
+
+    enum event_code_t {
+        BAD_DOCUMENT = -1,
+        START_DOCUMENT = 0,
+        END_DOCUMENT = 1,
+        
+        FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, 
+        
+        START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
+        END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
+        START_TAG = RES_XML_START_ELEMENT_TYPE,
+        END_TAG = RES_XML_END_ELEMENT_TYPE,
+        TEXT = RES_XML_CDATA_TYPE
+    };
+
+    struct ResXMLPosition
+    {
+        event_code_t                eventCode;
+        const ResXMLTree_node*      curNode;
+        const void*                 curExt;
+    };
+
+    void restart();
+
+    const ResStringPool& getStrings() const;
+
+    event_code_t getEventType() const;
+    // Note, unlike XmlPullParser, the first call to next() will return
+    // START_TAG of the first element.
+    event_code_t next();
+
+    // These are available for all nodes:
+    int32_t getCommentID() const;
+    const uint16_t* getComment(size_t* outLen) const;
+    uint32_t getLineNumber() const;
+    
+    // This is available for TEXT:
+    int32_t getTextID() const;
+    const uint16_t* getText(size_t* outLen) const;
+    ssize_t getTextValue(Res_value* outValue) const;
+    
+    // These are available for START_NAMESPACE and END_NAMESPACE:
+    int32_t getNamespacePrefixID() const;
+    const uint16_t* getNamespacePrefix(size_t* outLen) const;
+    int32_t getNamespaceUriID() const;
+    const uint16_t* getNamespaceUri(size_t* outLen) const;
+    
+    // These are available for START_TAG and END_TAG:
+    int32_t getElementNamespaceID() const;
+    const uint16_t* getElementNamespace(size_t* outLen) const;
+    int32_t getElementNameID() const;
+    const uint16_t* getElementName(size_t* outLen) const;
+    
+    // Remaining methods are for retrieving information about attributes
+    // associated with a START_TAG:
+    
+    size_t getAttributeCount() const;
+    
+    // Returns -1 if no namespace, -2 if idx out of range.
+    int32_t getAttributeNamespaceID(size_t idx) const;
+    const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
+
+    int32_t getAttributeNameID(size_t idx) const;
+    const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
+    uint32_t getAttributeNameResID(size_t idx) const;
+
+    // These will work only if the underlying string pool is UTF-8.
+    const char* getAttributeNamespace8(size_t idx, size_t* outLen) const;
+    const char* getAttributeName8(size_t idx, size_t* outLen) const;
+
+    int32_t getAttributeValueStringID(size_t idx) const;
+    const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
+    
+    int32_t getAttributeDataType(size_t idx) const;
+    int32_t getAttributeData(size_t idx) const;
+    ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
+
+    ssize_t indexOfAttribute(const char* ns, const char* attr) const;
+    ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
+                             const char16_t* attr, size_t attrLen) const;
+
+    ssize_t indexOfID() const;
+    ssize_t indexOfClass() const;
+    ssize_t indexOfStyle() const;
+
+    void getPosition(ResXMLPosition* pos) const;
+    void setPosition(const ResXMLPosition& pos);
+
+private:
+    friend class ResXMLTree;
+    
+    event_code_t nextNode();
+
+    const ResXMLTree&           mTree;
+    event_code_t                mEventCode;
+    const ResXMLTree_node*      mCurNode;
+    const void*                 mCurExt;
+};
+
+/**
+ * Convenience class for accessing data in a ResXMLTree resource.
+ */
+class ResXMLTree : public ResXMLParser
+{
+public:
+    ResXMLTree();
+    ResXMLTree(const void* data, size_t size, bool copyData=false);
+    ~ResXMLTree();
+
+    status_t setTo(const void* data, size_t size, bool copyData=false);
+
+    status_t getError() const;
+
+    void uninit();
+
+private:
+    friend class ResXMLParser;
+
+    status_t validateNode(const ResXMLTree_node* node) const;
+
+    status_t                    mError;
+    void*                       mOwnedData;
+    const ResXMLTree_header*    mHeader;
+    size_t                      mSize;
+    const uint8_t*              mDataEnd;
+    ResStringPool               mStrings;
+    const uint32_t*             mResIds;
+    size_t                      mNumResIds;
+    const ResXMLTree_node*      mRootNode;
+    const void*                 mRootExt;
+    event_code_t                mRootCode;
+};
+
+/** ********************************************************************
+ *  RESOURCE TABLE
+ *
+ *********************************************************************** */
+
+/**
+ * Header for a resource table.  Its data contains a series of
+ * additional chunks:
+ *   * A ResStringPool_header containing all table values.  This string pool
+ *     contains all of the string values in the entire resource table (not
+ *     the names of entries or type identifiers however).
+ *   * One or more ResTable_package chunks.
+ *
+ * Specific entries within a resource table can be uniquely identified
+ * with a single integer as defined by the ResTable_ref structure.
+ */
+struct ResTable_header
+{
+    struct ResChunk_header header;
+
+    // The number of ResTable_package structures.
+    uint32_t packageCount;
+};
+
+/**
+ * A collection of resource data types within a package.  Followed by
+ * one or more ResTable_type and ResTable_typeSpec structures containing the
+ * entry values for each resource type.
+ */
+struct ResTable_package
+{
+    struct ResChunk_header header;
+
+    // If this is a base package, its ID.  Package IDs start
+    // at 1 (corresponding to the value of the package bits in a
+    // resource identifier).  0 means this is not a base package.
+    uint32_t id;
+
+    // Actual name of this package, \0-terminated.
+    char16_t name[128];
+
+    // Offset to a ResStringPool_header defining the resource
+    // type symbol table.  If zero, this package is inheriting from
+    // another base package (overriding specific values in it).
+    uint32_t typeStrings;
+
+    // Last index into typeStrings that is for public use by others.
+    uint32_t lastPublicType;
+
+    // Offset to a ResStringPool_header defining the resource
+    // key symbol table.  If zero, this package is inheriting from
+    // another base package (overriding specific values in it).
+    uint32_t keyStrings;
+
+    // Last index into keyStrings that is for public use by others.
+    uint32_t lastPublicKey;
+};
+
+/**
+ * Describes a particular resource configuration.
+ */
+struct ResTable_config
+{
+    // Number of bytes in this structure.
+    uint32_t size;
+    
+    union {
+        struct {
+            // Mobile country code (from SIM).  0 means "any".
+            uint16_t mcc;
+            // Mobile network code (from SIM).  0 means "any".
+            uint16_t mnc;
+        };
+        uint32_t imsi;
+    };
+    
+    union {
+        struct {
+            // \0\0 means "any".  Otherwise, en, fr, etc.
+            char language[2];
+            
+            // \0\0 means "any".  Otherwise, US, CA, etc.
+            char country[2];
+        };
+        uint32_t locale;
+    };
+    
+    enum {
+        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,
+        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
+        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
+        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
+    };
+    
+    enum {
+        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,
+        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
+        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,
+        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,
+    };
+    
+    enum {
+        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
+        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
+        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
+        DENSITY_TV = ACONFIGURATION_DENSITY_TV,
+        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+        DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,
+        DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,
+        DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH,
+        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
+    };
+    
+    union {
+        struct {
+            uint8_t orientation;
+            uint8_t touchscreen;
+            uint16_t density;
+        };
+        uint32_t screenType;
+    };
+    
+    enum {
+        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,
+        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,
+        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,
+        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,
+    };
+    
+    enum {
+        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,
+        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,
+        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,
+        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,
+        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,
+    };
+    
+    enum {
+        MASK_KEYSHIDDEN = 0x0003,
+        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
+        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
+        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
+        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
+    };
+    
+    enum {
+        MASK_NAVHIDDEN = 0x000c,
+        SHIFT_NAVHIDDEN = 2,
+        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
+    };
+    
+    union {
+        struct {
+            uint8_t keyboard;
+            uint8_t navigation;
+            uint8_t inputFlags;
+            uint8_t inputPad0;
+        };
+        uint32_t input;
+    };
+    
+    enum {
+        SCREENWIDTH_ANY = 0
+    };
+    
+    enum {
+        SCREENHEIGHT_ANY = 0
+    };
+    
+    union {
+        struct {
+            uint16_t screenWidth;
+            uint16_t screenHeight;
+        };
+        uint32_t screenSize;
+    };
+    
+    enum {
+        SDKVERSION_ANY = 0
+    };
+    
+    enum {
+        MINORVERSION_ANY = 0
+    };
+    
+    union {
+        struct {
+            uint16_t sdkVersion;
+            // For now minorVersion must always be 0!!!  Its meaning
+            // is currently undefined.
+            uint16_t minorVersion;
+        };
+        uint32_t version;
+    };
+    
+    enum {
+        // screenLayout bits for screen size class.
+        MASK_SCREENSIZE = 0x0f,
+        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
+        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
+        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
+        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
+        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
+        
+        // screenLayout bits for wide/long screen variation.
+        MASK_SCREENLONG = 0x30,
+        SHIFT_SCREENLONG = 4,
+        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
+        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
+        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
+
+        // screenLayout bits for layout direction.
+        MASK_LAYOUTDIR = 0xC0,
+        SHIFT_LAYOUTDIR = 6,
+        LAYOUTDIR_ANY = ACONFIGURATION_LAYOUTDIR_ANY << SHIFT_LAYOUTDIR,
+        LAYOUTDIR_LTR = ACONFIGURATION_LAYOUTDIR_LTR << SHIFT_LAYOUTDIR,
+        LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR,
+    };
+    
+    enum {
+        // uiMode bits for the mode type.
+        MASK_UI_MODE_TYPE = 0x0f,
+        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
+        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
+        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
+        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
+        UI_MODE_TYPE_TELEVISION = ACONFIGURATION_UI_MODE_TYPE_TELEVISION,
+        UI_MODE_TYPE_APPLIANCE = ACONFIGURATION_UI_MODE_TYPE_APPLIANCE,
+
+        // uiMode bits for the night switch.
+        MASK_UI_MODE_NIGHT = 0x30,
+        SHIFT_UI_MODE_NIGHT = 4,
+        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
+    };
+
+    union {
+        struct {
+            uint8_t screenLayout;
+            uint8_t uiMode;
+            uint16_t smallestScreenWidthDp;
+        };
+        uint32_t screenConfig;
+    };
+    
+    union {
+        struct {
+            uint16_t screenWidthDp;
+            uint16_t screenHeightDp;
+        };
+        uint32_t screenSizeDp;
+    };
+
+    void copyFromDeviceNoSwap(const ResTable_config& o);
+    
+    void copyFromDtoH(const ResTable_config& o);
+    
+    void swapHtoD();
+
+    int compare(const ResTable_config& o) const;
+    int compareLogical(const ResTable_config& o) const;
+
+    // Flags indicating a set of config values.  These flag constants must
+    // match the corresponding ones in android.content.pm.ActivityInfo and
+    // attrs_manifest.xml.
+    enum {
+        CONFIG_MCC = ACONFIGURATION_MCC,
+        CONFIG_MNC = ACONFIGURATION_MCC,
+        CONFIG_LOCALE = ACONFIGURATION_LOCALE,
+        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
+        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
+        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
+        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
+        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
+        CONFIG_DENSITY = ACONFIGURATION_DENSITY,
+        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+        CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,
+        CONFIG_VERSION = ACONFIGURATION_VERSION,
+        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
+        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE,
+        CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR,
+    };
+    
+    // Compare two configuration, returning CONFIG_* flags set for each value
+    // that is different.
+    int diff(const ResTable_config& o) const;
+    
+    // Return true if 'this' is more specific than 'o'.
+    bool isMoreSpecificThan(const ResTable_config& o) const;
+
+    // Return true if 'this' is a better match than 'o' for the 'requested'
+    // configuration.  This assumes that match() has already been used to
+    // remove any configurations that don't match the requested configuration
+    // at all; if they are not first filtered, non-matching results can be
+    // considered better than matching ones.
+    // The general rule per attribute: if the request cares about an attribute
+    // (it normally does), if the two (this and o) are equal it's a tie.  If
+    // they are not equal then one must be generic because only generic and
+    // '==requested' will pass the match() call.  So if this is not generic,
+    // it wins.  If this IS generic, o wins (return false).
+    bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;
+
+    // Return true if 'this' can be considered a match for the parameters in 
+    // 'settings'.
+    // Note this is asymetric.  A default piece of data will match every request
+    // but a request for the default should not match odd specifics
+    // (ie, request with no mcc should not match a particular mcc's data)
+    // settings is the requested settings
+    bool match(const ResTable_config& settings) const;
+
+    void getLocale(char str[6]) const;
+
+    String8 toString() const;
+};
+
+/**
+ * A specification of the resources defined by a particular type.
+ *
+ * There should be one of these chunks for each resource type.
+ *
+ * This structure is followed by an array of integers providing the set of
+ * configuration change flags (ResTable_config::CONFIG_*) that have multiple
+ * resources for that configuration.  In addition, the high bit is set if that
+ * resource has been made public.
+ */
+struct ResTable_typeSpec
+{
+    struct ResChunk_header header;
+
+    // The type identifier this chunk is holding.  Type IDs start
+    // at 1 (corresponding to the value of the type bits in a
+    // resource identifier).  0 is invalid.
+    uint8_t id;
+    
+    // Must be 0.
+    uint8_t res0;
+    // Must be 0.
+    uint16_t res1;
+    
+    // Number of uint32_t entry configuration masks that follow.
+    uint32_t entryCount;
+
+    enum {
+        // Additional flag indicating an entry is public.
+        SPEC_PUBLIC = 0x40000000
+    };
+};
+
+/**
+ * A collection of resource entries for a particular resource data
+ * type. Followed by an array of uint32_t defining the resource
+ * values, corresponding to the array of type strings in the
+ * ResTable_package::typeStrings string block. Each of these hold an
+ * index from entriesStart; a value of NO_ENTRY means that entry is
+ * not defined.
+ *
+ * There may be multiple of these chunks for a particular resource type,
+ * supply different configuration variations for the resource values of
+ * that type.
+ *
+ * It would be nice to have an additional ordered index of entries, so
+ * we can do a binary search if trying to find a resource by string name.
+ */
+struct ResTable_type
+{
+    struct ResChunk_header header;
+
+    enum {
+        NO_ENTRY = 0xFFFFFFFF
+    };
+    
+    // The type identifier this chunk is holding.  Type IDs start
+    // at 1 (corresponding to the value of the type bits in a
+    // resource identifier).  0 is invalid.
+    uint8_t id;
+    
+    // Must be 0.
+    uint8_t res0;
+    // Must be 0.
+    uint16_t res1;
+    
+    // Number of uint32_t entry indices that follow.
+    uint32_t entryCount;
+
+    // Offset from header where ResTable_entry data starts.
+    uint32_t entriesStart;
+    
+    // Configuration this collection of entries is designed for.
+    ResTable_config config;
+};
+
+/**
+ * This is the beginning of information about an entry in the resource
+ * table.  It holds the reference to the name of this entry, and is
+ * immediately followed by one of:
+ *   * A Res_value structure, if FLAG_COMPLEX is -not- set.
+ *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.
+ *     These supply a set of name/value mappings of data.
+ */
+struct ResTable_entry
+{
+    // Number of bytes in this structure.
+    uint16_t size;
+
+    enum {
+        // If set, this is a complex entry, holding a set of name/value
+        // mappings.  It is followed by an array of ResTable_map structures.
+        FLAG_COMPLEX = 0x0001,
+        // If set, this resource has been declared public, so libraries
+        // are allowed to reference it.
+        FLAG_PUBLIC = 0x0002
+    };
+    uint16_t flags;
+    
+    // Reference into ResTable_package::keyStrings identifying this entry.
+    struct ResStringPool_ref key;
+};
+
+/**
+ * Extended form of a ResTable_entry for map entries, defining a parent map
+ * resource from which to inherit values.
+ */
+struct ResTable_map_entry : public ResTable_entry
+{
+    // Resource identifier of the parent mapping, or 0 if there is none.
+    ResTable_ref parent;
+    // Number of name/value pairs that follow for FLAG_COMPLEX.
+    uint32_t count;
+};
+
+/**
+ * A single name/value mapping that is part of a complex resource
+ * entry.
+ */
+struct ResTable_map
+{
+    // The resource identifier defining this mapping's name.  For attribute
+    // resources, 'name' can be one of the following special resource types
+    // to supply meta-data about the attribute; for all other resource types
+    // it must be an attribute resource.
+    ResTable_ref name;
+
+    // Special values for 'name' when defining attribute resources.
+    enum {
+        // This entry holds the attribute's type code.
+        ATTR_TYPE = Res_MAKEINTERNAL(0),
+
+        // For integral attributes, this is the minimum value it can hold.
+        ATTR_MIN = Res_MAKEINTERNAL(1),
+
+        // For integral attributes, this is the maximum value it can hold.
+        ATTR_MAX = Res_MAKEINTERNAL(2),
+
+        // Localization of this resource is can be encouraged or required with
+        // an aapt flag if this is set
+        ATTR_L10N = Res_MAKEINTERNAL(3),
+
+        // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
+        ATTR_OTHER = Res_MAKEINTERNAL(4),
+        ATTR_ZERO = Res_MAKEINTERNAL(5),
+        ATTR_ONE = Res_MAKEINTERNAL(6),
+        ATTR_TWO = Res_MAKEINTERNAL(7),
+        ATTR_FEW = Res_MAKEINTERNAL(8),
+        ATTR_MANY = Res_MAKEINTERNAL(9)
+        
+    };
+
+    // Bit mask of allowed types, for use with ATTR_TYPE.
+    enum {
+        // No type has been defined for this attribute, use generic
+        // type handling.  The low 16 bits are for types that can be
+        // handled generically; the upper 16 require additional information
+        // in the bag so can not be handled generically for TYPE_ANY.
+        TYPE_ANY = 0x0000FFFF,
+
+        // Attribute holds a references to another resource.
+        TYPE_REFERENCE = 1<<0,
+
+        // Attribute holds a generic string.
+        TYPE_STRING = 1<<1,
+
+        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
+        // optionally specify a constrained range of possible integer values.
+        TYPE_INTEGER = 1<<2,
+
+        // Attribute holds a boolean integer.
+        TYPE_BOOLEAN = 1<<3,
+
+        // Attribute holds a color value.
+        TYPE_COLOR = 1<<4,
+
+        // Attribute holds a floating point value.
+        TYPE_FLOAT = 1<<5,
+
+        // Attribute holds a dimension value, such as "20px".
+        TYPE_DIMENSION = 1<<6,
+
+        // Attribute holds a fraction value, such as "20%".
+        TYPE_FRACTION = 1<<7,
+
+        // Attribute holds an enumeration.  The enumeration values are
+        // supplied as additional entries in the map.
+        TYPE_ENUM = 1<<16,
+
+        // Attribute holds a bitmaks of flags.  The flag bit values are
+        // supplied as additional entries in the map.
+        TYPE_FLAGS = 1<<17
+    };
+
+    // Enum of localization modes, for use with ATTR_L10N.
+    enum {
+        L10N_NOT_REQUIRED = 0,
+        L10N_SUGGESTED    = 1
+    };
+    
+    // This mapping's value.
+    Res_value value;
+};
+
+/**
+ * Convenience class for accessing data in a ResTable resource.
+ */
+class ResTable
+{
+public:
+    ResTable();
+    ResTable(const void* data, size_t size, void* cookie,
+             bool copyData=false);
+    ~ResTable();
+
+    status_t add(const void* data, size_t size, void* cookie,
+                 bool copyData=false, const void* idmap = NULL);
+    status_t add(Asset* asset, void* cookie,
+                 bool copyData=false, const void* idmap = NULL);
+    status_t add(ResTable* src);
+
+    status_t getError() const;
+
+    void uninit();
+
+    struct resource_name
+    {
+        const char16_t* package;
+        size_t packageLen;
+        const char16_t* type;
+        const char* type8;
+        size_t typeLen;
+        const char16_t* name;
+        const char* name8;
+        size_t nameLen;
+    };
+
+    bool getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const;
+
+    /**
+     * Retrieve the value of a resource.  If the resource is found, returns a
+     * value >= 0 indicating the table it is in (for use with
+     * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
+     * not found, returns a negative error code.
+     *
+     * Note that this function does not do reference traversal.  If you want
+     * to follow references to other resources to get the "real" value to
+     * use, you need to call resolveReference() after this function.
+     *
+     * @param resID The desired resoruce identifier.
+     * @param outValue Filled in with the resource data that was found.
+     *
+     * @return ssize_t Either a >= 0 table index or a negative error code.
+     */
+    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false,
+                    uint16_t density = 0,
+                    uint32_t* outSpecFlags = NULL,
+                    ResTable_config* outConfig = NULL) const;
+
+    inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
+            uint32_t* outSpecFlags=NULL) const {
+        return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL);
+    }
+
+    ssize_t resolveReference(Res_value* inOutValue,
+                             ssize_t blockIndex,
+                             uint32_t* outLastRef = NULL,
+                             uint32_t* inoutTypeSpecFlags = NULL,
+                             ResTable_config* outConfig = NULL) const;
+
+    enum {
+        TMP_BUFFER_SIZE = 16
+    };
+    const char16_t* valueToString(const Res_value* value, size_t stringBlock,
+                                  char16_t tmpBuffer[TMP_BUFFER_SIZE],
+                                  size_t* outLen);
+
+    struct bag_entry {
+        ssize_t stringBlock;
+        ResTable_map map;
+    };
+
+    /**
+     * Retrieve the bag of a resource.  If the resoruce is found, returns the
+     * number of bags it contains and 'outBag' points to an array of their
+     * values.  If not found, a negative error code is returned.
+     *
+     * Note that this function -does- do reference traversal of the bag data.
+     *
+     * @param resID The desired resource identifier.
+     * @param outBag Filled inm with a pointer to the bag mappings.
+     *
+     * @return ssize_t Either a >= 0 bag count of negative error code.
+     */
+    ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
+
+    void unlockBag(const bag_entry* bag) const;
+
+    void lock() const;
+
+    ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
+            uint32_t* outTypeSpecFlags=NULL) const;
+
+    void unlock() const;
+
+    class Theme {
+    public:
+        Theme(const ResTable& table);
+        ~Theme();
+
+        inline const ResTable& getResTable() const { return mTable; }
+
+        status_t applyStyle(uint32_t resID, bool force=false);
+        status_t setTo(const Theme& other);
+
+        /**
+         * Retrieve a value in the theme.  If the theme defines this
+         * value, returns a value >= 0 indicating the table it is in
+         * (for use with getTableStringBlock() and getTableCookie) and
+         * fills in 'outValue'.  If not found, returns a negative error
+         * code.
+         *
+         * Note that this function does not do reference traversal.  If you want
+         * to follow references to other resources to get the "real" value to
+         * use, you need to call resolveReference() after this function.
+         *
+         * @param resID A resource identifier naming the desired theme
+         *              attribute.
+         * @param outValue Filled in with the theme value that was
+         *                 found.
+         *
+         * @return ssize_t Either a >= 0 table index or a negative error code.
+         */
+        ssize_t getAttribute(uint32_t resID, Res_value* outValue,
+                uint32_t* outTypeSpecFlags = NULL) const;
+
+        /**
+         * This is like ResTable::resolveReference(), but also takes
+         * care of resolving attribute references to the theme.
+         */
+        ssize_t resolveAttributeReference(Res_value* inOutValue,
+                ssize_t blockIndex, uint32_t* outLastRef = NULL,
+                uint32_t* inoutTypeSpecFlags = NULL,
+                ResTable_config* inoutConfig = NULL) const;
+
+        void dumpToLog() const;
+        
+    private:
+        Theme(const Theme&);
+        Theme& operator=(const Theme&);
+
+        struct theme_entry {
+            ssize_t stringBlock;
+            uint32_t typeSpecFlags;
+            Res_value value;
+        };
+        struct type_info {
+            size_t numEntries;
+            theme_entry* entries;
+        };
+        struct package_info {
+            size_t numTypes;
+            type_info types[];
+        };
+
+        void free_package(package_info* pi);
+        package_info* copy_package(package_info* pi);
+
+        const ResTable& mTable;
+        package_info*   mPackages[Res_MAXPACKAGE];
+    };
+
+    void setParameters(const ResTable_config* params);
+    void getParameters(ResTable_config* params) const;
+
+    // Retrieve an identifier (which can be passed to getResource)
+    // for a given resource name.  The 'name' can be fully qualified
+    // (<package>:<type>.<basename>) or the package or type components
+    // can be dropped if default values are supplied here.
+    //
+    // Returns 0 if no such resource was found, else a valid resource ID.
+    uint32_t identifierForName(const char16_t* name, size_t nameLen,
+                               const char16_t* type = 0, size_t typeLen = 0,
+                               const char16_t* defPackage = 0,
+                               size_t defPackageLen = 0,
+                               uint32_t* outTypeSpecFlags = NULL) const;
+
+    static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
+                                  String16* outPackage,
+                                  String16* outType,
+                                  String16* outName,
+                                  const String16* defType = NULL,
+                                  const String16* defPackage = NULL,
+                                  const char** outErrorMsg = NULL,
+                                  bool* outPublicOnly = NULL);
+
+    static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
+    static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
+
+    // Used with stringToValue.
+    class Accessor
+    {
+    public:
+        inline virtual ~Accessor() { }
+
+        virtual uint32_t getCustomResource(const String16& package,
+                                           const String16& type,
+                                           const String16& name) const = 0;
+        virtual uint32_t getCustomResourceWithCreation(const String16& package,
+                                                       const String16& type,
+                                                       const String16& name,
+                                                       const bool createIfNeeded = false) = 0;
+        virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
+        virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
+        virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
+        virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
+        virtual bool getAttributeEnum(uint32_t attrID,
+                                      const char16_t* name, size_t nameLen,
+                                      Res_value* outValue) = 0;
+        virtual bool getAttributeFlags(uint32_t attrID,
+                                       const char16_t* name, size_t nameLen,
+                                       Res_value* outValue) = 0;
+        virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
+        virtual bool getLocalizationSetting() = 0;
+        virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
+    };
+
+    // Convert a string to a resource value.  Handles standard "@res",
+    // "#color", "123", and "0x1bd" types; performs escaping of strings.
+    // The resulting value is placed in 'outValue'; if it is a string type,
+    // 'outString' receives the string.  If 'attrID' is supplied, the value is
+    // type checked against this attribute and it is used to perform enum
+    // evaluation.  If 'acccessor' is supplied, it will be used to attempt to
+    // resolve resources that do not exist in this ResTable.  If 'attrType' is
+    // supplied, the value will be type checked for this format if 'attrID'
+    // is not supplied or found.
+    bool stringToValue(Res_value* outValue, String16* outString,
+                       const char16_t* s, size_t len,
+                       bool preserveSpaces, bool coerceType,
+                       uint32_t attrID = 0,
+                       const String16* defType = NULL,
+                       const String16* defPackage = NULL,
+                       Accessor* accessor = NULL,
+                       void* accessorCookie = NULL,
+                       uint32_t attrType = ResTable_map::TYPE_ANY,
+                       bool enforcePrivate = true) const;
+
+    // Perform processing of escapes and quotes in a string.
+    static bool collectString(String16* outString,
+                              const char16_t* s, size_t len,
+                              bool preserveSpaces,
+                              const char** outErrorMsg = NULL,
+                              bool append = false);
+
+    size_t getBasePackageCount() const;
+    const char16_t* getBasePackageName(size_t idx) const;
+    uint32_t getBasePackageId(size_t idx) const;
+
+    // Return the number of resource tables that the object contains.
+    size_t getTableCount() const;
+    // Return the values string pool for the resource table at the given
+    // index.  This string pool contains all of the strings for values
+    // contained in the resource table -- that is the item values themselves,
+    // but not the names their entries or types.
+    const ResStringPool* getTableStringBlock(size_t index) const;
+    // Return unique cookie identifier for the given resource table.
+    void* getTableCookie(size_t index) const;
+
+    // Return the configurations (ResTable_config) that we know about
+    void getConfigurations(Vector<ResTable_config>* configs) const;
+
+    void getLocales(Vector<String8>* locales) const;
+
+    // Generate an idmap.
+    //
+    // Return value: on success: NO_ERROR; caller is responsible for free-ing
+    // outData (using free(3)). On failure, any status_t value other than
+    // NO_ERROR; the caller should not free outData.
+    status_t createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
+                         void** outData, size_t* outSize) const;
+
+    enum {
+        IDMAP_HEADER_SIZE_BYTES = 3 * sizeof(uint32_t),
+    };
+    // Retrieve idmap meta-data.
+    //
+    // This function only requires the idmap header (the first
+    // IDMAP_HEADER_SIZE_BYTES) bytes of an idmap file.
+    static bool getIdmapInfo(const void* idmap, size_t size,
+                             uint32_t* pOriginalCrc, uint32_t* pOverlayCrc);
+
+    void print(bool inclValues) const;
+    static String8 normalizeForOutput(const char* input);
+
+private:
+    struct Header;
+    struct Type;
+    struct Package;
+    struct PackageGroup;
+    struct bag_set;
+
+    status_t add(const void* data, size_t size, void* cookie,
+                 Asset* asset, bool copyData, const Asset* idmap);
+
+    ssize_t getResourcePackageIndex(uint32_t resID) const;
+    ssize_t getEntry(
+        const Package* package, int typeIndex, int entryIndex,
+        const ResTable_config* config,
+        const ResTable_type** outType, const ResTable_entry** outEntry,
+        const Type** outTypeClass) const;
+    status_t parsePackage(
+        const ResTable_package* const pkg, const Header* const header, uint32_t idmap_id);
+
+    void print_value(const Package* pkg, const Res_value& value) const;
+    
+    mutable Mutex               mLock;
+
+    status_t                    mError;
+
+    ResTable_config             mParams;
+
+    // Array of all resource tables.
+    Vector<Header*>             mHeaders;
+
+    // Array of packages in all resource tables.
+    Vector<PackageGroup*>       mPackageGroups;
+
+    // Mapping from resource package IDs to indices into the internal
+    // package array.
+    uint8_t                     mPackageMap[256];
+};
+
+}   // namespace android
+
+#endif // _LIBS_UTILS_RESOURCE_TYPES_H
diff --git a/include/androidfw/StreamingZipInflater.h b/include/androidfw/StreamingZipInflater.h
new file mode 100644
index 0000000..3ace5d5
--- /dev/null
+++ b/include/androidfw/StreamingZipInflater.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIBS_STREAMINGZIPINFLATER_H
+#define __LIBS_STREAMINGZIPINFLATER_H
+
+#include <unistd.h>
+#include <inttypes.h>
+#include <zlib.h>
+
+#include <utils/Compat.h>
+
+namespace android {
+
+class StreamingZipInflater {
+public:
+    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
+    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
+
+    // Flavor that pages in the compressed data from a fd
+    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);
+
+    // Flavor that gets the compressed data from an in-memory buffer
+    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
+
+    ~StreamingZipInflater();
+
+    // read 'count' bytes of uncompressed data from the current position.  outBuf may
+    // be NULL, in which case the data is consumed and discarded.
+    ssize_t read(void* outBuf, size_t count);
+
+    // seeking backwards requires uncompressing fom the beginning, so is very
+    // expensive.  seeking forwards only requires uncompressing from the current
+    // position to the destination.
+    off64_t seekAbsolute(off64_t absoluteInputPosition);
+
+private:
+    void initInflateState();
+    int readNextChunk();
+
+    // where to find the uncompressed data
+    int mFd;
+    off64_t mInFileStart;         // where the compressed data lives in the file
+    class FileMap* mDataMap;
+
+    z_stream mInflateState;
+    bool mStreamNeedsInit;
+
+    // output invariants for this asset
+    uint8_t* mOutBuf;           // output buf for decompressed bytes
+    size_t mOutBufSize;         // allocated size of mOutBuf
+    size_t mOutTotalSize;       // total uncompressed size of the blob
+
+    // current output state bookkeeping
+    off64_t mOutCurPosition;      // current position in total offset
+    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
+    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
+
+    // input invariants
+    uint8_t* mInBuf;
+    size_t mInBufSize;          // allocated size of mInBuf;
+    size_t mInTotalSize;        // total size of compressed data for this blob
+
+    // input state bookkeeping
+    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies
+    // the z_stream contains state about input block consumption
+};
+
+}
+
+#endif
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
new file mode 100644
index 0000000..547e36a
--- /dev/null
+++ b/include/androidfw/ZipFileRO.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Read-only access to Zip archives, with minimal heap allocation.
+ *
+ * This is similar to the more-complete ZipFile class, but no attempt
+ * has been made to make them interchangeable.  This class operates under
+ * a very different set of assumptions and constraints.
+ *
+ * One such assumption is that if you're getting file descriptors for
+ * use with this class as a child of a fork() operation, you must be on
+ * a pread() to guarantee correct operation. This is because pread() can
+ * atomically read at a file offset without worrying about a lock around an
+ * lseek() + read() pair.
+ */
+#ifndef __LIBS_ZIPFILERO_H
+#define __LIBS_ZIPFILERO_H
+
+#include <utils/Compat.h>
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/threads.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+namespace android {
+
+/*
+ * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
+ * integer.  We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryRO;
+
+/*
+ * Open a Zip archive for reading.
+ *
+ * We want "open" and "find entry by name" to be fast operations, and we
+ * want to use as little memory as possible.  We memory-map the file,
+ * and load a hash table with pointers to the filenames (which aren't
+ * null-terminated).  The other fields are at a fixed offset from the
+ * filename, so we don't need to extract those (but we do need to byte-read
+ * and endian-swap them every time we want them).
+ *
+ * To speed comparisons when doing a lookup by name, we could make the mapping
+ * "private" (copy-on-write) and null-terminate the filenames after verifying
+ * the record structure.  However, this requires a private mapping of
+ * every page that the Central Directory touches.  Easier to tuck a copy
+ * of the string length into the hash table entry.
+ *
+ * NOTE: If this is used on file descriptors inherited from a fork() operation,
+ * you must be on a platform that implements pread() to guarantee correctness
+ * on the shared file descriptors.
+ */
+class ZipFileRO {
+public:
+    ZipFileRO()
+        : mFd(-1), mFileName(NULL), mFileLength(-1),
+          mDirectoryMap(NULL),
+          mNumEntries(-1), mDirectoryOffset(-1),
+          mHashTableSize(-1), mHashTable(NULL)
+        {}
+
+    ~ZipFileRO();
+
+    /*
+     * Open an archive.
+     */
+    status_t open(const char* zipFileName);
+
+    /*
+     * Find an entry, by name.  Returns the entry identifier, or NULL if
+     * not found.
+     *
+     * If two entries have the same name, one will be chosen at semi-random.
+     */
+    ZipEntryRO findEntryByName(const char* fileName) const;
+
+    /*
+     * Return the #of entries in the Zip archive.
+     */
+    int getNumEntries(void) const {
+        return mNumEntries;
+    }
+
+    /*
+     * Return the Nth entry.  Zip file entries are not stored in sorted
+     * order, and updated entries may appear at the end, so anyone walking
+     * the archive needs to avoid making ordering assumptions.  We take
+     * that further by returning the Nth non-empty entry in the hash table
+     * rather than the Nth entry in the archive.
+     *
+     * Valid values are [0..numEntries).
+     *
+     * [This is currently O(n).  If it needs to be fast we can allocate an
+     * additional data structure or provide an iterator interface.]
+     */
+    ZipEntryRO findEntryByIndex(int idx) const;
+
+    /*
+     * Copy the filename into the supplied buffer.  Returns 0 on success,
+     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
+     * length, and the returned string, include the null-termination.
+     */
+    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
+
+    /*
+     * Get the vital stats for an entry.  Pass in NULL pointers for anything
+     * you don't need.
+     *
+     * "*pOffset" holds the Zip file offset of the entry's data.
+     *
+     * Returns "false" if "entry" is bogus or if the data in the Zip file
+     * appears to be bad.
+     */
+    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
+
+    /*
+     * Create a new FileMap object that maps a subset of the archive.  For
+     * an uncompressed entry this effectively provides a pointer to the
+     * actual data, for a compressed entry this provides the input buffer
+     * for inflate().
+     */
+    FileMap* createEntryFileMap(ZipEntryRO entry) const;
+
+    /*
+     * Uncompress the data into a buffer.  Depending on the compression
+     * format, this is either an "inflate" operation or a memcpy.
+     *
+     * Use "uncompLen" from getEntryInfo() to determine the required
+     * buffer size.
+     *
+     * Returns "true" on success.
+     */
+    bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
+
+    /*
+     * Uncompress the data to an open file descriptor.
+     */
+    bool uncompressEntry(ZipEntryRO entry, int fd) const;
+
+    /* Zip compression methods we support */
+    enum {
+        kCompressStored     = 0,        // no compression
+        kCompressDeflated   = 8,        // standard deflate
+    };
+
+    /*
+     * Utility function: uncompress deflated data, buffer to buffer.
+     */
+    static bool inflateBuffer(void* outBuf, const void* inBuf,
+        size_t uncompLen, size_t compLen);
+
+    /*
+     * Utility function: uncompress deflated data, buffer to fd.
+     */
+    static bool inflateBuffer(int fd, const void* inBuf,
+        size_t uncompLen, size_t compLen);
+
+    /*
+     * Utility function to convert ZIP's time format to a timespec struct.
+     */
+    static inline void zipTimeToTimespec(long when, struct tm* timespec) {
+        const long date = when >> 16;
+        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980
+        timespec->tm_mon = (date >> 5) & 0x0F;
+        timespec->tm_mday = date & 0x1F;
+
+        timespec->tm_hour = (when >> 11) & 0x1F;
+        timespec->tm_min = (when >> 5) & 0x3F;
+        timespec->tm_sec = (when & 0x1F) << 1;
+    }
+
+    /*
+     * Some basic functions for raw data manipulation.  "LE" means
+     * Little Endian.
+     */
+    static inline unsigned short get2LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8);
+    }
+    static inline unsigned long get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+private:
+    /* these are private and not defined */ 
+    ZipFileRO(const ZipFileRO& src);
+    ZipFileRO& operator=(const ZipFileRO& src);
+
+    /* locate and parse the central directory */
+    bool mapCentralDirectory(void);
+
+    /* parse the archive, prepping internal structures */
+    bool parseZipArchive(void);
+
+    /* add a new entry to the hash table */
+    void addToHash(const char* str, int strLen, unsigned int hash);
+
+    /* compute string hash code */
+    static unsigned int computeHash(const char* str, int len);
+
+    /* convert a ZipEntryRO back to a hash table index */
+    int entryToIndex(const ZipEntryRO entry) const;
+
+    /*
+     * One entry in the hash table.
+     */
+    typedef struct HashEntry {
+        const char*     name;
+        unsigned short  nameLen;
+        //unsigned int    hash;
+    } HashEntry;
+
+    /* open Zip archive */
+    int         mFd;
+
+    /* Lock for handling the file descriptor (seeks, etc) */
+    mutable Mutex mFdLock;
+
+    /* zip file name */
+    char*       mFileName;
+
+    /* length of file */
+    size_t      mFileLength;
+
+    /* mapped file */
+    FileMap*    mDirectoryMap;
+
+    /* number of entries in the Zip archive */
+    int         mNumEntries;
+
+    /* CD directory offset in the Zip archive */
+    off64_t     mDirectoryOffset;
+
+    /*
+     * We know how many entries are in the Zip archive, so we have a
+     * fixed-size hash table.  We probe for an empty slot.
+     */
+    int         mHashTableSize;
+    HashEntry*  mHashTable;
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h
new file mode 100644
index 0000000..42c42b6
--- /dev/null
+++ b/include/androidfw/ZipUtils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Miscellaneous zip/gzip utility functions.
+//
+#ifndef __LIBS_ZIPUTILS_H
+#define __LIBS_ZIPUTILS_H
+
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Container class for utility functions, primarily for namespace reasons.
+ */
+class ZipUtils {
+public:
+    /*
+     * General utility function for uncompressing "deflate" data from a file
+     * to a buffer.
+     */
+    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
+        long compressedLen);
+    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
+        long compressedLen);
+
+    /*
+     * Someday we might want to make this generic and handle bzip2 ".bz2"
+     * files too.
+     *
+     * We could declare gzip to be a sub-class of zip that has exactly
+     * one always-compressed entry, but we currently want to treat Zip
+     * and gzip as distinct, so there's no value.
+     *
+     * The zlib library has some gzip utilities, but it has no interface
+     * for extracting the uncompressed length of the file (you do *not*
+     * want to gzseek to the end).
+     *
+     * Pass in a seeked file pointer for the gzip file.  If this is a gzip
+     * file, we set our return values appropriately and return "true" with
+     * the file seeked to the start of the compressed data.
+     */
+    static bool examineGzip(FILE* fp, int* pCompressionMethod,
+        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
+
+private:
+    ZipUtils() {}
+    ~ZipUtils() {}
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/include/androidfw/misc.h b/include/androidfw/misc.h
new file mode 100644
index 0000000..5a5a0e2
--- /dev/null
+++ b/include/androidfw/misc.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+
+//
+// Handy utility functions and portability code.
+//
+#ifndef _LIBS_ANDROID_FW_MISC_H
+#define _LIBS_ANDROID_FW_MISC_H
+
+namespace android {
+
+/*
+ * Some utility functions for working with files.  These could be made
+ * part of a "File" class.
+ */
+typedef enum FileType {
+    kFileTypeUnknown = 0,
+    kFileTypeNonexistent,       // i.e. ENOENT
+    kFileTypeRegular,
+    kFileTypeDirectory,
+    kFileTypeCharDev,
+    kFileTypeBlockDev,
+    kFileTypeFifo,
+    kFileTypeSymlink,
+    kFileTypeSocket,
+} FileType;
+/* get the file's type; follows symlinks */
+FileType getFileType(const char* fileName);
+/* get the file's modification date; returns -1 w/errno set on failure */
+time_t getFileModDate(const char* fileName);
+
+}; // namespace android
+
+#endif // _LIBS_ANDROID_FW_MISC_H
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
new file mode 100644
index 0000000..d80612b
--- /dev/null
+++ b/libs/androidfw/Android.mk
@@ -0,0 +1,93 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+# libandroidfw is partially built for the host (used by obbtool and others)
+# These files are common to host and target builds.
+
+commonSources := \
+    Asset.cpp \
+    AssetDir.cpp \
+    AssetManager.cpp \
+    misc.cpp \
+    ObbFile.cpp \
+    ResourceTypes.cpp \
+    StreamingZipInflater.cpp \
+    ZipFileRO.cpp \
+    ZipUtils.cpp
+
+deviceSources := \
+    $(commonSources) \
+    BackupData.cpp \
+    BackupHelpers.cpp \
+    CursorWindow.cpp
+
+hostSources := \
+    $(commonSources)
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(hostSources)
+
+LOCAL_MODULE:= libandroidfw
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
+
+LOCAL_C_INCLUDES := \
+	external/zlib
+
+LOCAL_STATIC_LIBRARIES := liblog
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# For the device
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(deviceSources)
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	liblog \
+	libcutils \
+	libutils \
+	libz
+
+LOCAL_C_INCLUDES := \
+    external/icu4c/common \
+	external/zlib
+
+LOCAL_MODULE:= libandroidfw
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
new file mode 100644
index 0000000..cb7628d
--- /dev/null
+++ b/libs/androidfw/Asset.cpp
@@ -0,0 +1,897 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to a read-only asset.
+//
+
+#define LOG_TAG "asset"
+//#define NDEBUG 0
+
+#include <androidfw/Asset.h>
+#include <androidfw/StreamingZipInflater.h>
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
+#include <utils/Atomic.h>
+#include <utils/FileMap.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+using namespace android;
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static Mutex gAssetLock;
+static int32_t gCount = 0;
+static Asset* gHead = NULL;
+static Asset* gTail = NULL;
+
+int32_t Asset::getGlobalCount()
+{
+    AutoMutex _l(gAssetLock);
+    return gCount;
+}
+
+String8 Asset::getAssetAllocations()
+{
+    AutoMutex _l(gAssetLock);
+    String8 res;
+    Asset* cur = gHead;
+    while (cur != NULL) {
+        if (cur->isAllocated()) {
+            res.append("    ");
+            res.append(cur->getAssetSource());
+            off64_t size = (cur->getLength()+512)/1024;
+            char buf[64];
+            sprintf(buf, ": %dK\n", (int)size);
+            res.append(buf);
+        }
+        cur = cur->mNext;
+    }
+    
+    return res;
+}
+
+Asset::Asset(void)
+    : mAccessMode(ACCESS_UNKNOWN)
+{
+    AutoMutex _l(gAssetLock);
+    gCount++;
+    mNext = mPrev = NULL;
+    if (gTail == NULL) {
+        gHead = gTail = this;
+  	} else {
+  	    mPrev = gTail;
+  	    gTail->mNext = this;
+  	    gTail = this;
+  	}
+    //ALOGI("Creating Asset %p #%d\n", this, gCount);
+}
+
+Asset::~Asset(void)
+{
+    AutoMutex _l(gAssetLock);
+	gCount--;
+    if (gHead == this) {
+        gHead = mNext;
+    }
+    if (gTail == this) {
+        gTail = mPrev;
+    }
+    if (mNext != NULL) {
+        mNext->mPrev = mPrev;
+    }
+    if (mPrev != NULL) {
+        mPrev->mNext = mNext;
+    }
+    mNext = mPrev = NULL;
+    //ALOGI("Destroying Asset in %p #%d\n", this, gCount);
+}
+
+/*
+ * Create a new Asset from a file on disk.  There is a fair chance that
+ * the file doesn't actually exist.
+ *
+ * We can use "mode" to decide how we want to go about it.
+ */
+/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+    off64_t length;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    /*
+     * Under Linux, the lseek fails if we actually opened a directory.  To
+     * be correct we should test the file type explicitly, but since we
+     * always open things read-only it doesn't really matter, so there's
+     * no value in incurring the extra overhead of an fstat() call.
+     */
+    // TODO(kroot): replace this with fstat despite the plea above.
+#if 1
+    length = lseek64(fd, 0, SEEK_END);
+    if (length < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek64(fd, 0, SEEK_SET);
+#else
+    struct stat st;
+    if (fstat(fd, &st) < 0) {
+        ::close(fd);
+        return NULL;
+    }
+
+    if (!S_ISREG(st.st_mode)) {
+        ::close(fd);
+        return NULL;
+    }
+#endif
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(fileName, fd, 0, length);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Create a new Asset from a compressed file on disk.  There is a fair chance
+ * that the file doesn't actually exist.
+ *
+ * We currently support gzip files.  We might want to handle .bz2 someday.
+ */
+/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+    off64_t fileLen;
+    bool scanResult;
+    long offset;
+    int method;
+    long uncompressedLen, compressedLen;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    fileLen = lseek(fd, 0, SEEK_END);
+    if (fileLen < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    /* want buffered I/O for the file scan; must dup so fclose() is safe */
+    FILE* fp = fdopen(dup(fd), "rb");
+    if (fp == NULL) {
+        ::close(fd);
+        return NULL;
+    }
+
+    unsigned long crc32;
+    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
+                    &compressedLen, &crc32);
+    offset = ftell(fp);
+    fclose(fp);
+    if (!scanResult) {
+        ALOGD("File '%s' is not in gzip format\n", fileName);
+        ::close(fd);
+        return NULL;
+    }
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, method, uncompressedLen,
+                compressedLen);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+#if 0
+/*
+ * Create a new Asset from part of an open file.
+ */
+/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,
+    size_t length, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(NULL, fd, offset, length);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in an open file.
+ */
+/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, compressionMethod,
+                uncompressedLen, compressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+#endif
+
+/*
+ * Create a new Asset from a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
+    AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(dataMap);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
+    int method, size_t uncompressedLen, AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(dataMap, method, uncompressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Do generic seek() housekeeping.  Pass in the offset/whence values from
+ * the seek request, along with the current chunk offset and the chunk
+ * length.
+ *
+ * Returns the new chunk offset, or -1 if the seek is illegal.
+ */
+off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)
+{
+    off64_t newOffset;
+
+    switch (whence) {
+    case SEEK_SET:
+        newOffset = offset;
+        break;
+    case SEEK_CUR:
+        newOffset = curPosn + offset;
+        break;
+    case SEEK_END:
+        newOffset = maxPosn + offset;
+        break;
+    default:
+        ALOGW("unexpected whence %d\n", whence);
+        // this was happening due to an off64_t size mismatch
+        assert(false);
+        return (off64_t) -1;
+    }
+
+    if (newOffset < 0 || newOffset > maxPosn) {
+        ALOGW("seek out of range: want %ld, end=%ld\n",
+            (long) newOffset, (long) maxPosn);
+        return (off64_t) -1;
+    }
+
+    return newOffset;
+}
+
+
+/*
+ * ===========================================================================
+ *      _FileAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_FileAsset::_FileAsset(void)
+    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_FileAsset::~_FileAsset(void)
+{
+    close();
+}
+
+/*
+ * Operate on a chunk of an uncompressed file.
+ *
+ * Zero-length chunks are allowed.
+ */
+status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+
+    /*
+     * Seek to end to get file length.
+     */
+    off64_t fileLength;
+    fileLength = lseek64(fd, 0, SEEK_END);
+    if (fileLength == (off64_t) -1) {
+        // probably a bad file descriptor
+        ALOGD("failed lseek (errno=%d)\n", errno);
+        return UNKNOWN_ERROR;
+    }
+
+    if ((off64_t) (offset + length) > fileLength) {
+        ALOGD("start (%ld) + len (%ld) > end (%ld)\n",
+            (long) offset, (long) length, (long) fileLength);
+        return BAD_INDEX;
+    }
+
+    /* after fdopen, the fd will be closed on fclose() */
+    mFp = fdopen(fd, "rb");
+    if (mFp == NULL)
+        return UNKNOWN_ERROR;
+
+    mStart = offset;
+    mLength = length;
+    assert(mOffset == 0);
+
+    /* seek the FILE* to the start of chunk */
+    if (fseek(mFp, mStart, SEEK_SET) != 0) {
+        assert(false);
+    }
+
+    mFileName = fileName != NULL ? strdup(fileName) : NULL;
+    
+    return NO_ERROR;
+}
+
+/*
+ * Create the chunk from the map.
+ */
+status_t _FileAsset::openChunk(FileMap* dataMap)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    mMap = dataMap;
+    mStart = -1;            // not used
+    mLength = dataMap->getDataLength();
+    assert(mOffset == 0);
+
+    return NO_ERROR;
+}
+
+/*
+ * Read a chunk of data.
+ */
+ssize_t _FileAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mLength);
+
+    if (getAccessMode() == ACCESS_BUFFER) {
+        /*
+         * On first access, read or map the entire file.  The caller has
+         * requested buffer access, either because they're going to be
+         * using the buffer or because what they're doing has appropriate
+         * performance needs and access patterns.
+         */
+        if (mBuf == NULL)
+            getBuffer(false);
+    }
+
+    /* adjust count if we're near EOF */
+    maxLen = mLength - mOffset;
+    if (count > maxLen)
+        count = maxLen;
+
+    if (!count)
+        return 0;
+
+    if (mMap != NULL) {
+        /* copy from mapped area */
+        //printf("map read\n");
+        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
+        actual = count;
+    } else if (mBuf != NULL) {
+        /* copy from buffer */
+        //printf("buf read\n");
+        memcpy(buf, (char*)mBuf + mOffset, count);
+        actual = count;
+    } else {
+        /* read from the file */
+        //printf("file read\n");
+        if (ftell(mFp) != mStart + mOffset) {
+            ALOGE("Hosed: %ld != %ld+%ld\n",
+                ftell(mFp), (long) mStart, (long) mOffset);
+            assert(false);
+        }
+
+        /*
+         * This returns 0 on error or eof.  We need to use ferror() or feof()
+         * to tell the difference, but we don't currently have those on the
+         * device.  However, we know how much data is *supposed* to be in the
+         * file, so if we don't read the full amount we know something is
+         * hosed.
+         */
+        actual = fread(buf, 1, count, mFp);
+        if (actual == 0)        // something failed -- I/O error?
+            return -1;
+
+        assert(actual == count);
+    }
+
+    mOffset += actual;
+    return actual;
+}
+
+/*
+ * Seek to a new position.
+ */
+off64_t _FileAsset::seek(off64_t offset, int whence)
+{
+    off64_t newPosn;
+    off64_t actualOffset;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mLength);
+    if (newPosn == (off64_t) -1)
+        return newPosn;
+
+    actualOffset = mStart + newPosn;
+
+    if (mFp != NULL) {
+        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
+            return (off64_t) -1;
+    }
+
+    mOffset = actualOffset - mStart;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _FileAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = NULL;
+    }
+
+    if (mFileName != NULL) {
+        free(mFileName);
+        mFileName = NULL;
+    }
+    
+    if (mFp != NULL) {
+        // can only be NULL when called from destructor
+        // (otherwise we would never return this object)
+        fclose(mFp);
+        mFp = NULL;
+    }
+}
+
+/*
+ * Return a read-only pointer to a buffer.
+ *
+ * We can either read the whole thing in or map the relevant piece of
+ * the source file.  Ideally a map would be established at a higher
+ * level and we'd be using a different object, but we didn't, so we
+ * deal with it here.
+ */
+const void* _FileAsset::getBuffer(bool wordAligned)
+{
+    /* subsequent requests just use what we did previously */
+    if (mBuf != NULL)
+        return mBuf;
+    if (mMap != NULL) {
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+
+    assert(mFp != NULL);
+
+    if (mLength < kReadVsMapThreshold) {
+        unsigned char* buf;
+        long allocLen;
+
+        /* zero-length files are allowed; not sure about zero-len allocs */
+        /* (works fine with gcc + x86linux) */
+        allocLen = mLength;
+        if (mLength == 0)
+            allocLen = 1;
+
+        buf = new unsigned char[allocLen];
+        if (buf == NULL) {
+            ALOGE("alloc of %ld bytes failed\n", (long) allocLen);
+            return NULL;
+        }
+
+        ALOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
+        if (mLength > 0) {
+            long oldPosn = ftell(mFp);
+            fseek(mFp, mStart, SEEK_SET);
+            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
+                ALOGE("failed reading %ld bytes\n", (long) mLength);
+                delete[] buf;
+                return NULL;
+            }
+            fseek(mFp, oldPosn, SEEK_SET);
+        }
+
+        ALOGV(" getBuffer: loaded into buffer\n");
+
+        mBuf = buf;
+        return mBuf;
+    } else {
+        FileMap* map;
+
+        map = new FileMap;
+        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
+            map->release();
+            return NULL;
+        }
+
+        ALOGV(" getBuffer: mapped\n");
+
+        mMap = map;
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+}
+
+int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const
+{
+    if (mMap != NULL) {
+        const char* fname = mMap->getFileName();
+        if (fname == NULL) {
+            fname = mFileName;
+        }
+        if (fname == NULL) {
+            return -1;
+        }
+        *outStart = mMap->getDataOffset();
+        *outLength = mMap->getDataLength();
+        return open(fname, O_RDONLY | O_BINARY);
+    }
+    if (mFileName == NULL) {
+        return -1;
+    }
+    *outStart = mStart;
+    *outLength = mLength;
+    return open(mFileName, O_RDONLY | O_BINARY);
+}
+
+const void* _FileAsset::ensureAlignment(FileMap* map)
+{
+    void* data = map->getDataPtr();
+    if ((((size_t)data)&0x3) == 0) {
+        // We can return this directly if it is aligned on a word
+        // boundary.
+        ALOGV("Returning aligned FileAsset %p (%s).", this,
+                getAssetSource());
+        return data;
+    }
+    // If not aligned on a word boundary, then we need to copy it into
+    // our own buffer.
+    ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
+            getAssetSource(), (int)mLength);
+    unsigned char* buf = new unsigned char[mLength];
+    if (buf == NULL) {
+        ALOGE("alloc of %ld bytes failed\n", (long) mLength);
+        return NULL;
+    }
+    memcpy(buf, data, mLength);
+    mBuf = buf;
+    return buf;
+}
+
+/*
+ * ===========================================================================
+ *      _CompressedAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_CompressedAsset::_CompressedAsset(void)
+    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
+      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_CompressedAsset::~_CompressedAsset(void)
+{
+    close();
+}
+
+/*
+ * Open a chunk of compressed data inside a file.
+ *
+ * This currently just sets up some values and returns.  On the first
+ * read, we expand the entire file into a buffer and return data from it.
+ */
+status_t _CompressedAsset::openChunk(int fd, off64_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(compressedLen > 0);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mStart = offset;
+    mCompressedLen = compressedLen;
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+    mFd = fd;
+    assert(mBuf == NULL);
+
+    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
+        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Open a chunk of compressed data in a mapped region.
+ *
+ * Nothing is expanded until the first read call.
+ */
+status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
+    size_t uncompressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mMap = dataMap;
+    mStart = -1;        // not used
+    mCompressedLen = dataMap->getDataLength();
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+
+    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
+        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);
+    }
+    return NO_ERROR;
+}
+
+/*
+ * Read data from a chunk of compressed data.
+ *
+ * [For now, that's just copying data out of a buffer.]
+ */
+ssize_t _CompressedAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mUncompressedLen);
+
+    /* If we're relying on a streaming inflater, go through that */
+    if (mZipInflater) {
+        actual = mZipInflater->read(buf, count);
+    } else {
+        if (mBuf == NULL) {
+            if (getBuffer(false) == NULL)
+                return -1;
+        }
+        assert(mBuf != NULL);
+
+        /* adjust count if we're near EOF */
+        maxLen = mUncompressedLen - mOffset;
+        if (count > maxLen)
+            count = maxLen;
+
+        if (!count)
+            return 0;
+
+        /* copy from buffer */
+        //printf("comp buf read\n");
+        memcpy(buf, (char*)mBuf + mOffset, count);
+        actual = count;
+    }
+
+    mOffset += actual;
+    return actual;
+}
+
+/*
+ * Handle a seek request.
+ *
+ * If we're working in a streaming mode, this is going to be fairly
+ * expensive, because it requires plowing through a bunch of compressed
+ * data.
+ */
+off64_t _CompressedAsset::seek(off64_t offset, int whence)
+{
+    off64_t newPosn;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
+    if (newPosn == (off64_t) -1)
+        return newPosn;
+
+    if (mZipInflater) {
+        mZipInflater->seekAbsolute(newPosn);
+    }
+    mOffset = newPosn;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _CompressedAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+
+    delete[] mBuf;
+    mBuf = NULL;
+
+    delete mZipInflater;
+    mZipInflater = NULL;
+
+    if (mFd > 0) {
+        ::close(mFd);
+        mFd = -1;
+    }
+}
+
+/*
+ * Get a pointer to a read-only buffer of data.
+ *
+ * The first time this is called, we expand the compressed data into a
+ * buffer.
+ */
+const void* _CompressedAsset::getBuffer(bool wordAligned)
+{
+    unsigned char* buf = NULL;
+
+    if (mBuf != NULL)
+        return mBuf;
+
+    /*
+     * Allocate a buffer and read the file into it.
+     */
+    buf = new unsigned char[mUncompressedLen];
+    if (buf == NULL) {
+        ALOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
+        goto bail;
+    }
+
+    if (mMap != NULL) {
+        if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
+                mUncompressedLen, mCompressedLen))
+            goto bail;
+    } else {
+        assert(mFd >= 0);
+
+        /*
+         * Seek to the start of the compressed data.
+         */
+        if (lseek(mFd, mStart, SEEK_SET) != mStart)
+            goto bail;
+
+        /*
+         * Expand the data into it.
+         */
+        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
+                mCompressedLen))
+            goto bail;
+    }
+
+    /*
+     * Success - now that we have the full asset in RAM we
+     * no longer need the streaming inflater
+     */
+    delete mZipInflater;
+    mZipInflater = NULL;
+
+    mBuf = buf;
+    buf = NULL;
+
+bail:
+    delete[] buf;
+    return mBuf;
+}
+
diff --git a/libs/androidfw/AssetDir.cpp b/libs/androidfw/AssetDir.cpp
new file mode 100644
index 0000000..475f521
--- /dev/null
+++ b/libs/androidfw/AssetDir.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to a virtual directory in "asset space".  Most of the
+// implementation is in the header file or in friend functions in
+// AssetManager.
+//
+#include <androidfw/AssetDir.h>
+
+using namespace android;
+
+
+/*
+ * Find a matching entry in a vector of FileInfo.  Because it's sorted, we
+ * can use a binary search.
+ *
+ * Assumes the vector is sorted in ascending order.
+ */
+/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
+    const String8& fileName)
+{
+    FileInfo tmpInfo;
+
+    tmpInfo.setFileName(fileName);
+    return pVector->indexOf(tmpInfo);
+
+#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)
+    int lo, hi, cur;
+
+    lo = 0;
+    hi = pVector->size() -1;
+    while (lo <= hi) {
+        int cmp;
+
+        cur = (hi + lo) / 2;
+        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
+        if (cmp == 0) {
+            /* match, bail */
+            return cur;
+        } else if (cmp < 0) {
+            /* too low */
+            lo = cur + 1;
+        } else {
+            /* too high */
+            hi = cur -1;
+        }
+    }
+
+    return -1;
+#endif
+}
+
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
new file mode 100644
index 0000000..6667daf
--- /dev/null
+++ b/libs/androidfw/AssetManager.cpp
@@ -0,0 +1,2034 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to read-only assets.
+//
+
+#define LOG_TAG "asset"
+#define ATRACE_TAG ATRACE_TAG_RESOURCES
+//#define LOG_NDEBUG 0
+
+#include <androidfw/Asset.h>
+#include <androidfw/AssetDir.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/misc.h>
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/ZipFileRO.h>
+#include <utils/Atomic.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#ifdef HAVE_ANDROID_OS
+#include <cutils/trace.h>
+#endif
+
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+#ifdef HAVE_ANDROID_OS
+#define MY_TRACE_BEGIN(x) ATRACE_BEGIN(x)
+#define MY_TRACE_END() ATRACE_END()
+#else
+#define MY_TRACE_BEGIN(x)
+#define MY_TRACE_END()
+#endif
+
+using namespace android;
+
+/*
+ * Names for default app, locale, and vendor.  We might want to change
+ * these to be an actual locale, e.g. always use en-US as the default.
+ */
+static const char* kDefaultLocale = "default";
+static const char* kDefaultVendor = "default";
+static const char* kAssetsRoot = "assets";
+static const char* kAppZipName = NULL; //"classes.jar";
+static const char* kSystemAssets = "framework/framework-res.apk";
+static const char* kIdmapCacheDir = "resource-cache";
+
+static const char* kExcludeExtension = ".EXCLUDE";
+
+static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
+
+static volatile int32_t gCount = 0;
+
+namespace {
+    // Transform string /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
+    String8 idmapPathForPackagePath(const String8& pkgPath)
+    {
+        const char* root = getenv("ANDROID_DATA");
+        LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_DATA not set");
+        String8 path(root);
+        path.appendPath(kIdmapCacheDir);
+
+        char buf[256]; // 256 chars should be enough for anyone...
+        strncpy(buf, pkgPath.string(), 255);
+        buf[255] = '\0';
+        char* filename = buf;
+        while (*filename && *filename == '/') {
+            ++filename;
+        }
+        char* p = filename;
+        while (*p) {
+            if (*p == '/') {
+                *p = '@';
+            }
+            ++p;
+        }
+        path.appendPath(filename);
+        path.append("@idmap");
+
+        return path;
+    }
+
+    /*
+     * Like strdup(), but uses C++ "new" operator instead of malloc.
+     */
+    static char* strdupNew(const char* str)
+    {
+        char* newStr;
+        int len;
+
+        if (str == NULL)
+            return NULL;
+
+        len = strlen(str);
+        newStr = new char[len+1];
+        memcpy(newStr, str, len+1);
+
+        return newStr;
+    }
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager
+ * ===========================================================================
+ */
+
+int32_t AssetManager::getGlobalCount()
+{
+    return gCount;
+}
+
+AssetManager::AssetManager(CacheMode cacheMode)
+    : mLocale(NULL), mVendor(NULL),
+      mResources(NULL), mConfig(new ResTable_config),
+      mCacheMode(cacheMode), mCacheValid(false)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //ALOGI("Creating AssetManager %p #%d\n", this, count);
+    memset(mConfig, 0, sizeof(ResTable_config));
+}
+
+AssetManager::~AssetManager(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //ALOGI("Destroying AssetManager in %p #%d\n", this, count);
+
+    delete mConfig;
+    delete mResources;
+
+    // don't have a String class yet, so make sure we clean up
+    delete[] mLocale;
+    delete[] mVendor;
+}
+
+bool AssetManager::addAssetPath(const String8& path, void** cookie)
+{
+    AutoMutex _l(mLock);
+
+    asset_path ap;
+
+    String8 realPath(path);
+    if (kAppZipName) {
+        realPath.appendPath(kAppZipName);
+    }
+    ap.type = ::getFileType(realPath.string());
+    if (ap.type == kFileTypeRegular) {
+        ap.path = realPath;
+    } else {
+        ap.path = path;
+        ap.type = ::getFileType(path.string());
+        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
+            ALOGW("Asset path %s is neither a directory nor file (type=%d).",
+                 path.string(), (int)ap.type);
+            return false;
+        }
+    }
+
+    // Skip if we have it already.
+    for (size_t i=0; i<mAssetPaths.size(); i++) {
+        if (mAssetPaths[i].path == ap.path) {
+            if (cookie) {
+                *cookie = (void*)(i+1);
+            }
+            return true;
+        }
+    }
+
+    ALOGV("In %p Asset %s path: %s", this,
+         ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
+
+    mAssetPaths.add(ap);
+
+    // new paths are always added at the end
+    if (cookie) {
+        *cookie = (void*)mAssetPaths.size();
+    }
+
+    // add overlay packages for /system/framework; apps are handled by the
+    // (Java) package manager
+    if (strncmp(path.string(), "/system/framework/", 18) == 0) {
+        // When there is an environment variable for /vendor, this
+        // should be changed to something similar to how ANDROID_ROOT
+        // and ANDROID_DATA are used in this file.
+        String8 overlayPath("/vendor/overlay/framework/");
+        overlayPath.append(path.getPathLeaf());
+        if (TEMP_FAILURE_RETRY(access(overlayPath.string(), R_OK)) == 0) {
+            asset_path oap;
+            oap.path = overlayPath;
+            oap.type = ::getFileType(overlayPath.string());
+            bool addOverlay = (oap.type == kFileTypeRegular); // only .apks supported as overlay
+            if (addOverlay) {
+                oap.idmap = idmapPathForPackagePath(overlayPath);
+
+                if (isIdmapStaleLocked(ap.path, oap.path, oap.idmap)) {
+                    addOverlay = createIdmapFileLocked(ap.path, oap.path, oap.idmap);
+                }
+            }
+            if (addOverlay) {
+                mAssetPaths.add(oap);
+            } else {
+                ALOGW("failed to add overlay package %s\n", overlayPath.string());
+            }
+        }
+    }
+
+    return true;
+}
+
+bool AssetManager::isIdmapStaleLocked(const String8& originalPath, const String8& overlayPath,
+                                      const String8& idmapPath)
+{
+    struct stat st;
+    if (TEMP_FAILURE_RETRY(stat(idmapPath.string(), &st)) == -1) {
+        if (errno == ENOENT) {
+            return true; // non-existing idmap is always stale
+        } else {
+            ALOGW("failed to stat file %s: %s\n", idmapPath.string(), strerror(errno));
+            return false;
+        }
+    }
+    if (st.st_size < ResTable::IDMAP_HEADER_SIZE_BYTES) {
+        ALOGW("file %s has unexpectedly small size=%zd\n", idmapPath.string(), (size_t)st.st_size);
+        return false;
+    }
+    int fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_RDONLY));
+    if (fd == -1) {
+        ALOGW("failed to open file %s: %s\n", idmapPath.string(), strerror(errno));
+        return false;
+    }
+    char buf[ResTable::IDMAP_HEADER_SIZE_BYTES];
+    ssize_t bytesLeft = ResTable::IDMAP_HEADER_SIZE_BYTES;
+    for (;;) {
+        ssize_t r = TEMP_FAILURE_RETRY(read(fd, buf + ResTable::IDMAP_HEADER_SIZE_BYTES - bytesLeft,
+                                            bytesLeft));
+        if (r < 0) {
+            TEMP_FAILURE_RETRY(close(fd));
+            return false;
+        }
+        bytesLeft -= r;
+        if (bytesLeft == 0) {
+            break;
+        }
+    }
+    TEMP_FAILURE_RETRY(close(fd));
+
+    uint32_t cachedOriginalCrc, cachedOverlayCrc;
+    if (!ResTable::getIdmapInfo(buf, ResTable::IDMAP_HEADER_SIZE_BYTES,
+                                &cachedOriginalCrc, &cachedOverlayCrc)) {
+        return false;
+    }
+
+    uint32_t actualOriginalCrc, actualOverlayCrc;
+    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &actualOriginalCrc)) {
+        return false;
+    }
+    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &actualOverlayCrc)) {
+        return false;
+    }
+    return cachedOriginalCrc != actualOriginalCrc || cachedOverlayCrc != actualOverlayCrc;
+}
+
+bool AssetManager::getZipEntryCrcLocked(const String8& zipPath, const char* entryFilename,
+                                        uint32_t* pCrc)
+{
+    asset_path ap;
+    ap.path = zipPath;
+    const ZipFileRO* zip = getZipFileLocked(ap);
+    if (zip == NULL) {
+        return false;
+    }
+    const ZipEntryRO entry = zip->findEntryByName(entryFilename);
+    if (entry == NULL) {
+        return false;
+    }
+    if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)pCrc)) {
+        return false;
+    }
+    return true;
+}
+
+bool AssetManager::createIdmapFileLocked(const String8& originalPath, const String8& overlayPath,
+                                         const String8& idmapPath)
+{
+    ALOGD("%s: originalPath=%s overlayPath=%s idmapPath=%s\n",
+         __FUNCTION__, originalPath.string(), overlayPath.string(), idmapPath.string());
+    ResTable tables[2];
+    const String8* paths[2] = { &originalPath, &overlayPath };
+    uint32_t originalCrc, overlayCrc;
+    bool retval = false;
+    ssize_t offset = 0;
+    int fd = 0;
+    uint32_t* data = NULL;
+    size_t size;
+
+    for (int i = 0; i < 2; ++i) {
+        asset_path ap;
+        ap.type = kFileTypeRegular;
+        ap.path = *paths[i];
+        Asset* ass = openNonAssetInPathLocked("resources.arsc", Asset::ACCESS_BUFFER, ap);
+        if (ass == NULL) {
+            ALOGW("failed to find resources.arsc in %s\n", ap.path.string());
+            goto error;
+        }
+        tables[i].add(ass, (void*)1, false);
+    }
+
+    if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) {
+        ALOGW("failed to retrieve crc for resources.arsc in %s\n", originalPath.string());
+        goto error;
+    }
+    if (!getZipEntryCrcLocked(overlayPath, "resources.arsc", &overlayCrc)) {
+        ALOGW("failed to retrieve crc for resources.arsc in %s\n", overlayPath.string());
+        goto error;
+    }
+
+    if (tables[0].createIdmap(tables[1], originalCrc, overlayCrc,
+                              (void**)&data, &size) != NO_ERROR) {
+        ALOGW("failed to generate idmap data for file %s\n", idmapPath.string());
+        goto error;
+    }
+
+    // This should be abstracted (eg replaced by a stand-alone
+    // application like dexopt, triggered by something equivalent to
+    // installd).
+    fd = TEMP_FAILURE_RETRY(::open(idmapPath.string(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
+    if (fd == -1) {
+        ALOGW("failed to write idmap file %s (open: %s)\n", idmapPath.string(), strerror(errno));
+        goto error_free;
+    }
+    for (;;) {
+        ssize_t written = TEMP_FAILURE_RETRY(write(fd, data + offset, size));
+        if (written < 0) {
+            ALOGW("failed to write idmap file %s (write: %s)\n", idmapPath.string(),
+                 strerror(errno));
+            goto error_close;
+        }
+        size -= (size_t)written;
+        offset += written;
+        if (size == 0) {
+            break;
+        }
+    }
+
+    retval = true;
+error_close:
+    TEMP_FAILURE_RETRY(close(fd));
+error_free:
+    free(data);
+error:
+    return retval;
+}
+
+bool AssetManager::addDefaultAssets()
+{
+    const char* root = getenv("ANDROID_ROOT");
+    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
+
+    String8 path(root);
+    path.appendPath(kSystemAssets);
+
+    return addAssetPath(path, NULL);
+}
+
+void* AssetManager::nextAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    size_t next = ((size_t)cookie)+1;
+    return next > mAssetPaths.size() ? NULL : (void*)next;
+}
+
+String8 AssetManager::getAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    const size_t which = ((size_t)cookie)-1;
+    if (which < mAssetPaths.size()) {
+        return mAssetPaths[which].path;
+    }
+    return String8();
+}
+
+/*
+ * Set the current locale.  Use NULL to indicate no locale.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the locale-specific sections of the tree.
+ */
+void AssetManager::setLocale(const char* locale)
+{
+    AutoMutex _l(mLock);
+    setLocaleLocked(locale);
+}
+
+void AssetManager::setLocaleLocked(const char* locale)
+{
+    if (mLocale != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeLocale();
+        delete[] mLocale;
+    }
+    mLocale = strdupNew(locale);
+    
+    updateResourceParamsLocked();
+}
+
+/*
+ * Set the current vendor.  Use NULL to indicate no vendor.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the vendor-specific sections of the tree.
+ */
+void AssetManager::setVendor(const char* vendor)
+{
+    AutoMutex _l(mLock);
+
+    if (mVendor != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeVendor();
+        delete[] mVendor;
+    }
+    mVendor = strdupNew(vendor);
+}
+
+void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
+{
+    AutoMutex _l(mLock);
+    *mConfig = config;
+    if (locale) {
+        setLocaleLocked(locale);
+    } else if (config.language[0] != 0) {
+        char spec[9];
+        spec[0] = config.language[0];
+        spec[1] = config.language[1];
+        if (config.country[0] != 0) {
+            spec[2] = '_';
+            spec[3] = config.country[0];
+            spec[4] = config.country[1];
+            spec[5] = 0;
+        } else {
+            spec[3] = 0;
+        }
+        setLocaleLocked(spec);
+    } else {
+        updateResourceParamsLocked();
+    }
+}
+
+void AssetManager::getConfiguration(ResTable_config* outConfig) const
+{
+    AutoMutex _l(mLock);
+    *outConfig = *mConfig;
+}
+
+/*
+ * Open an asset.
+ *
+ * The data could be;
+ *  - In a file on disk (assetBase + fileName).
+ *  - In a compressed file on disk (assetBase + fileName.gz).
+ *  - In a Zip archive, uncompressed or compressed.
+ *
+ * It can be in a number of different directories and Zip archives.
+ * The search order is:
+ *  - [appname]
+ *    - locale + vendor
+ *    - "default" + vendor
+ *    - locale + "default"
+ *    - "default + "default"
+ *  - "common"
+ *    - (same as above)
+ *
+ * To find a particular file, we have to try up to eight paths with
+ * all three forms of data.
+ *
+ * We should probably reject requests for "illegal" filenames, e.g. those
+ * with illegal characters or "../" backward relative paths.
+ */
+Asset* AssetManager::open(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    String8 assetName(kAssetsRoot);
+    assetName.appendPath(fileName);
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        ALOGV("Looking for asset '%s' in '%s'\n",
+                assetName.string(), mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Open a non-asset file as if it were an asset.
+ *
+ * The "fileName" is the partial path starting from the application
+ * name.
+ */
+Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
+{
+    const size_t which = ((size_t)cookie)-1;
+
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    if (which < mAssetPaths.size()) {
+        ALOGV("Looking for non-asset '%s' in '%s'\n", fileName,
+                mAssetPaths.itemAt(which).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(which));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the type of a file in the asset namespace.
+ *
+ * This currently only works for regular files.  All others (including
+ * directories) will return kFileTypeNonexistent.
+ */
+FileType AssetManager::getFileType(const char* fileName)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Open the asset.  This is less efficient than simply finding the
+     * file, but it's not too bad (we don't uncompress or mmap data until
+     * the first read() call).
+     */
+    pAsset = open(fileName, Asset::ACCESS_STREAMING);
+    delete pAsset;
+
+    if (pAsset == NULL)
+        return kFileTypeNonexistent;
+    else
+        return kFileTypeRegular;
+}
+
+const ResTable* AssetManager::getResTable(bool required) const
+{
+    ResTable* rt = mResources;
+    if (rt) {
+        return rt;
+    }
+
+    // Iterate through all asset packages, collecting resources from each.
+
+    AutoMutex _l(mLock);
+
+    if (mResources != NULL) {
+        return mResources;
+    }
+
+    if (required) {
+        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    }
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
+
+    const size_t N = mAssetPaths.size();
+    for (size_t i=0; i<N; i++) {
+        Asset* ass = NULL;
+        ResTable* sharedRes = NULL;
+        bool shared = true;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        MY_TRACE_BEGIN(ap.path.string());
+        Asset* idmap = openIdmapLocked(ap);
+        ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
+        if (ap.type != kFileTypeDirectory) {
+            if (i == 0) {
+                // The first item is typically the framework resources,
+                // which we want to avoid parsing every time.
+                sharedRes = const_cast<AssetManager*>(this)->
+                    mZipSet.getZipResourceTable(ap.path);
+            }
+            if (sharedRes == NULL) {
+                ass = const_cast<AssetManager*>(this)->
+                    mZipSet.getZipResourceTableAsset(ap.path);
+                if (ass == NULL) {
+                    ALOGV("loading resource table %s\n", ap.path.string());
+                    ass = const_cast<AssetManager*>(this)->
+                        openNonAssetInPathLocked("resources.arsc",
+                                                 Asset::ACCESS_BUFFER,
+                                                 ap);
+                    if (ass != NULL && ass != kExcludedAsset) {
+                        ass = const_cast<AssetManager*>(this)->
+                            mZipSet.setZipResourceTableAsset(ap.path, ass);
+                    }
+                }
+                
+                if (i == 0 && ass != NULL) {
+                    // If this is the first resource table in the asset
+                    // manager, then we are going to cache it so that we
+                    // can quickly copy it out for others.
+                    ALOGV("Creating shared resources for %s", ap.path.string());
+                    sharedRes = new ResTable();
+                    sharedRes->add(ass, (void*)(i+1), false, idmap);
+                    sharedRes = const_cast<AssetManager*>(this)->
+                        mZipSet.setZipResourceTable(ap.path, sharedRes);
+                }
+            }
+        } else {
+            ALOGV("loading resource table %s\n", ap.path.string());
+            Asset* ass = const_cast<AssetManager*>(this)->
+                openNonAssetInPathLocked("resources.arsc",
+                                         Asset::ACCESS_BUFFER,
+                                         ap);
+            shared = false;
+        }
+        if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) {
+            if (rt == NULL) {
+                mResources = rt = new ResTable();
+                updateResourceParamsLocked();
+            }
+            ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+            if (sharedRes != NULL) {
+                ALOGV("Copying existing resources for %s", ap.path.string());
+                rt->add(sharedRes);
+            } else {
+                ALOGV("Parsing resources for %s", ap.path.string());
+                rt->add(ass, (void*)(i+1), !shared, idmap);
+            }
+
+            if (!shared) {
+                delete ass;
+            }
+        }
+        if (idmap != NULL) {
+            delete idmap;
+        }
+        MY_TRACE_END();
+    }
+
+    if (required && !rt) ALOGW("Unable to find resources file resources.arsc");
+    if (!rt) {
+        mResources = rt = new ResTable();
+    }
+    return rt;
+}
+
+void AssetManager::updateResourceParamsLocked() const
+{
+    ResTable* res = mResources;
+    if (!res) {
+        return;
+    }
+
+    size_t llen = mLocale ? strlen(mLocale) : 0;
+    mConfig->language[0] = 0;
+    mConfig->language[1] = 0;
+    mConfig->country[0] = 0;
+    mConfig->country[1] = 0;
+    if (llen >= 2) {
+        mConfig->language[0] = mLocale[0];
+        mConfig->language[1] = mLocale[1];
+    }
+    if (llen >= 5) {
+        mConfig->country[0] = mLocale[3];
+        mConfig->country[1] = mLocale[4];
+    }
+    mConfig->size = sizeof(*mConfig);
+
+    res->setParameters(mConfig);
+}
+
+Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const
+{
+    Asset* ass = NULL;
+    if (ap.idmap.size() != 0) {
+        ass = const_cast<AssetManager*>(this)->
+            openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);
+        if (ass) {
+            ALOGV("loading idmap %s\n", ap.idmap.string());
+        } else {
+            ALOGW("failed to load idmap %s\n", ap.idmap.string());
+        }
+    }
+    return ass;
+}
+
+const ResTable& AssetManager::getResources(bool required) const
+{
+    const ResTable* rt = getResTable(required);
+    return *rt;
+}
+
+bool AssetManager::isUpToDate()
+{
+    AutoMutex _l(mLock);
+    return mZipSet.isUpToDate();
+}
+
+void AssetManager::getLocales(Vector<String8>* locales) const
+{
+    ResTable* res = mResources;
+    if (res != NULL) {
+        res->getLocales(locales);
+    }
+}
+
+/*
+ * Open a non-asset file as if it were an asset, searching for it in the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /* look at the filesystem on disk */
+    if (ap.type == kFileTypeDirectory) {
+        String8 path(ap.path);
+        path.appendPath(fileName);
+
+        pAsset = openAssetFromFileLocked(path, mode);
+
+        if (pAsset == NULL) {
+            /* try again, this time with ".gz" */
+            path.append(".gz");
+            pAsset = openAssetFromFileLocked(path, mode);
+        }
+
+        if (pAsset != NULL) {
+            //printf("FOUND NA '%s' on disk\n", fileName);
+            pAsset->setAssetSource(path);
+        }
+
+    /* look inside the zip file */
+    } else {
+        String8 path(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking NA '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(
+                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
+                                                String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Try various combinations of locale and vendor.
+     */
+    if (mLocale != NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
+    if (pAsset == NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
+    if (pAsset == NULL && mLocale != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
+    if (pAsset == NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified locale and vendor.
+ *
+ * We also search in "app.jar".
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * defaults should be used.
+ */
+Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap, const char* locale, const char* vendor)
+{
+    Asset* pAsset = NULL;
+
+    if (ap.type == kFileTypeDirectory) {
+        if (mCacheMode == CACHE_OFF) {
+            /* look at the filesystem on disk */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
+                /* say no more */
+                //printf("+++ excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+    
+            pAsset = openAssetFromFileLocked(path, mode);
+    
+            if (pAsset == NULL) {
+                /* try again, this time with ".gz" */
+                path.append(".gz");
+                pAsset = openAssetFromFileLocked(path, mode);
+            }
+    
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+        } else {
+            /* find in cache */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            AssetDir::FileInfo tmpInfo;
+            bool found = false;
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+    
+            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
+                /* go no farther */
+                //printf("+++ Excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+
+            /*
+             * File compression extensions (".gz") don't get stored in the
+             * name cache, so we have to try both here.
+             */
+            if (mCache.indexOf(path) != NAME_NOT_FOUND) {
+                found = true;
+                pAsset = openAssetFromFileLocked(path, mode);
+                if (pAsset == NULL) {
+                    /* try again, this time with ".gz" */
+                    path.append(".gz");
+                    pAsset = openAssetFromFileLocked(path, mode);
+                }
+            }
+
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+
+            /*
+             * Don't continue the search into the Zip files.  Our cached info
+             * said it was a file on disk; to be consistent with openDir()
+             * we want to return the loose asset.  If the cached file gets
+             * removed, we fail.
+             *
+             * The alternative is to update our cache when files get deleted,
+             * or make some sort of "best effort" promise, but for now I'm
+             * taking the hard line.
+             */
+            if (found) {
+                if (pAsset == NULL)
+                    ALOGD("Expected file not found: '%s'\n", path.string());
+                return pAsset;
+            }
+        }
+    }
+
+    /*
+     * Either it wasn't found on disk or on the cached view of the disk.
+     * Dig through the currently-opened set of Zip files.  If caching
+     * is disabled, the Zip file may get reopened.
+     */
+    if (pAsset == NULL && ap.type == kFileTypeRegular) {
+        String8 path;
+
+        path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+        path.appendPath(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND in Zip file for %s/%s-%s\n",
+                //    appName, locale, vendor);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
+                                                             String8(""), String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Create a "source name" for a file from a Zip archive.
+ */
+String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
+    const String8& dirName, const String8& fileName)
+{
+    String8 sourceName("zip:");
+    sourceName.append(zipFileName);
+    sourceName.append(":");
+    if (dirName.length() > 0) {
+        sourceName.appendPath(dirName);
+    }
+    sourceName.appendPath(fileName);
+    return sourceName;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/locale/vendor).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
+    const char* vendor)
+{
+    String8 path(ap.path);
+    path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+    return path;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/rootDir).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
+{
+    String8 path(ap.path);
+    if (rootDir != NULL) path.appendPath(rootDir);
+    return path;
+}
+
+/*
+ * Return a pointer to one of our open Zip archives.  Returns NULL if no
+ * matching Zip file exists.
+ *
+ * Right now we have 2 possible Zip files (1 each in app/"common").
+ *
+ * If caching is set to CACHE_OFF, to get the expected behavior we
+ * need to reopen the Zip file on every request.  That would be silly
+ * and expensive, so instead we just check the file modification date.
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * generics should be used.
+ */
+ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
+{
+    ALOGV("getZipFileLocked() in %p\n", this);
+
+    return mZipSet.getZip(ap.path);
+}
+
+/*
+ * Try to open an asset from a file on disk.
+ *
+ * If the file is compressed with gzip, we seek to the start of the
+ * deflated data and pass that in (just like we would for a Zip archive).
+ *
+ * For uncompressed data, we may already have an mmap()ed version sitting
+ * around.  If so, we want to hand that to the Asset instead.
+ *
+ * This returns NULL if the file doesn't exist, couldn't be opened, or
+ * claims to be a ".gz" but isn't.
+ */
+Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
+    AccessMode mode)
+{
+    Asset* pAsset = NULL;
+
+    if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
+    } else {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromFile(pathName.string(), mode);
+    }
+
+    return pAsset;
+}
+
+/*
+ * Given an entry in a Zip archive, create a new Asset object.
+ *
+ * If the entry is uncompressed, we may want to create or share a
+ * slice of shared memory.
+ */
+Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
+    const ZipEntryRO entry, AccessMode mode, const String8& entryName)
+{
+    Asset* pAsset = NULL;
+
+    // TODO: look for previously-created shared memory slice?
+    int method;
+    size_t uncompressedLen;
+
+    //printf("USING Zip '%s'\n", pEntry->getFileName());
+
+    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
+    //    &offset);
+    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
+            NULL, NULL))
+    {
+        ALOGW("getEntryInfo failed\n");
+        return NULL;
+    }
+
+    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
+    if (dataMap == NULL) {
+        ALOGW("create map from entry failed\n");
+        return NULL;
+    }
+
+    if (method == ZipFileRO::kCompressStored) {
+        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
+        ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    } else {
+        pAsset = Asset::createFromCompressedMap(dataMap, method,
+            uncompressedLen, mode);
+        ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    }
+    if (pAsset == NULL) {
+        /* unexpected */
+        ALOGW("create from segment failed\n");
+    }
+
+    return pAsset;
+}
+
+
+
+/*
+ * Open a directory in the asset namespace.
+ *
+ * An "asset directory" is simply the combination of all files in all
+ * locations, with ".gz" stripped for loose files.  With app, locale, and
+ * vendor defined, we have 8 directories and 2 Zip archives to scan.
+ *
+ * Pass in "" for the root dir.
+ */
+AssetDir* AssetManager::openDir(const char* dirName)
+{
+    AutoMutex _l(mLock);
+
+    AssetDir* pDir = NULL;
+    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    assert(dirName != NULL);
+
+    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    pDir = new AssetDir;
+
+    /*
+     * Scan the various directories, merging what we find into a single
+     * vector.  We want to scan them in reverse priority order so that
+     * the ".EXCLUDE" processing works correctly.  Also, if we decide we
+     * want to remember where the file is coming from, we'll get the right
+     * version.
+     *
+     * We start with Zip archives, then do loose files.
+     */
+    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        if (ap.type == kFileTypeRegular) {
+            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        } else {
+            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        }
+    }
+
+#if 0
+    printf("FILE LIST:\n");
+    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            pMergedInfo->itemAt(i).getFileType(),
+            (const char*) pMergedInfo->itemAt(i).getFileName());
+    }
+#endif
+
+    pDir->setFileList(pMergedInfo);
+    return pDir;
+}
+
+/*
+ * Open a directory in the non-asset namespace.
+ *
+ * An "asset directory" is simply the combination of all files in all
+ * locations, with ".gz" stripped for loose files.  With app, locale, and
+ * vendor defined, we have 8 directories and 2 Zip archives to scan.
+ *
+ * Pass in "" for the root dir.
+ */
+AssetDir* AssetManager::openNonAssetDir(void* cookie, const char* dirName)
+{
+    AutoMutex _l(mLock);
+
+    AssetDir* pDir = NULL;
+    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    assert(dirName != NULL);
+
+    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    pDir = new AssetDir;
+
+    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
+
+    const size_t which = ((size_t)cookie)-1;
+
+    if (which < mAssetPaths.size()) {
+        const asset_path& ap = mAssetPaths.itemAt(which);
+        if (ap.type == kFileTypeRegular) {
+            ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+            scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
+        } else {
+            ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+            scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
+        }
+    }
+
+#if 0
+    printf("FILE LIST:\n");
+    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            pMergedInfo->itemAt(i).getFileType(),
+            (const char*) pMergedInfo->itemAt(i).getFileName());
+    }
+#endif
+
+    pDir->setFileList(pMergedInfo);
+    return pDir;
+}
+
+/*
+ * Scan the contents of the specified directory and merge them into the
+ * "pMergedInfo" vector, removing previous entries if we find "exclude"
+ * directives.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 path;
+
+    assert(pMergedInfo != NULL);
+
+    //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
+
+    if (mCacheValid) {
+        int i, start, count;
+
+        pContents = new SortedVector<AssetDir::FileInfo>;
+
+        /*
+         * Get the basic partial path and find it in the cache.  That's
+         * the start point for the search.
+         */
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+
+        start = mCache.indexOf(path);
+        if (start == NAME_NOT_FOUND) {
+            //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
+            delete pContents;
+            return false;
+        }
+
+        /*
+         * The match string looks like "common/default/default/foo/bar/".
+         * The '/' on the end ensures that we don't match on the directory
+         * itself or on ".../foo/barfy/".
+         */
+        path.append("/");
+
+        count = mCache.size();
+
+        /*
+         * Pick out the stuff in the current dir by examining the pathname.
+         * It needs to match the partial pathname prefix, and not have a '/'
+         * (fssep) anywhere after the prefix.
+         */
+        for (i = start+1; i < count; i++) {
+            if (mCache[i].getFileName().length() > path.length() &&
+                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
+            {
+                const char* name = mCache[i].getFileName().string();
+                // XXX THIS IS BROKEN!  Looks like we need to store the full
+                // path prefix separately from the file path.
+                if (strchr(name + path.length(), '/') == NULL) {
+                    /* grab it, reducing path to just the filename component */
+                    AssetDir::FileInfo tmp = mCache[i];
+                    tmp.setFileName(tmp.getFileName().getPathLeaf());
+                    pContents->add(tmp);
+                }
+            } else {
+                /* no longer in the dir or its subdirs */
+                break;
+            }
+
+        }
+    } else {
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+        pContents = scanDirLocked(path);
+        if (pContents == NULL)
+            return false;
+    }
+
+    // if we wanted to do an incremental cache fill, we would do it here
+
+    /*
+     * Process "exclude" directives.  If we find a filename that ends with
+     * ".EXCLUDE", we look for a matching entry in the "merged" set, and
+     * remove it if we find it.  We also delete the "exclude" entry.
+     */
+    int i, count, exclExtLen;
+
+    count = pContents->size();
+    exclExtLen = strlen(kExcludeExtension);
+    for (i = 0; i < count; i++) {
+        const char* name;
+        int nameLen;
+
+        name = pContents->itemAt(i).getFileName().string();
+        nameLen = strlen(name);
+        if (nameLen > exclExtLen &&
+            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
+        {
+            String8 match(name, nameLen - exclExtLen);
+            int matchIdx;
+
+            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
+            if (matchIdx > 0) {
+                ALOGV("Excluding '%s' [%s]\n",
+                    pMergedInfo->itemAt(matchIdx).getFileName().string(),
+                    pMergedInfo->itemAt(matchIdx).getSourceName().string());
+                pMergedInfo->removeAt(matchIdx);
+            } else {
+                //printf("+++ no match on '%s'\n", (const char*) match);
+            }
+
+            ALOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
+            pContents->removeAt(i);
+            i--;        // adjust "for" loop
+            count--;    //  and loop limit
+        }
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+
+    delete pContents;
+
+    return true;
+}
+
+/*
+ * Scan the contents of the specified directory, and stuff what we find
+ * into a newly-allocated vector.
+ *
+ * Files ending in ".gz" will have their extensions removed.
+ *
+ * We should probably think about skipping files with "illegal" names,
+ * e.g. illegal characters (/\:) or excessive length.
+ *
+ * Returns NULL if the specified directory doesn't exist.
+ */
+SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
+{
+    SortedVector<AssetDir::FileInfo>* pContents = NULL;
+    DIR* dir;
+    struct dirent* entry;
+    FileType fileType;
+
+    ALOGV("Scanning dir '%s'\n", path.string());
+
+    dir = opendir(path.string());
+    if (dir == NULL)
+        return NULL;
+
+    pContents = new SortedVector<AssetDir::FileInfo>;
+
+    while (1) {
+        entry = readdir(dir);
+        if (entry == NULL)
+            break;
+
+        if (strcmp(entry->d_name, ".") == 0 ||
+            strcmp(entry->d_name, "..") == 0)
+            continue;
+
+#ifdef _DIRENT_HAVE_D_TYPE
+        if (entry->d_type == DT_REG)
+            fileType = kFileTypeRegular;
+        else if (entry->d_type == DT_DIR)
+            fileType = kFileTypeDirectory;
+        else
+            fileType = kFileTypeUnknown;
+#else
+        // stat the file
+        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
+#endif
+
+        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
+            continue;
+
+        AssetDir::FileInfo info;
+        info.set(String8(entry->d_name), fileType);
+        if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
+            info.setFileName(info.getFileName().getBasePath());
+        info.setSourceName(path.appendPathCopy(info.getFileName()));
+        pContents->add(info);
+    }
+
+    closedir(dir);
+    return pContents;
+}
+
+/*
+ * Scan the contents out of the specified Zip archive, and merge what we
+ * find into "pMergedInfo".  If the Zip archive in question doesn't exist,
+ * we return immediately.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* baseDirName)
+{
+    ZipFileRO* pZip;
+    Vector<String8> dirs;
+    AssetDir::FileInfo info;
+    SortedVector<AssetDir::FileInfo> contents;
+    String8 sourceName, zipName, dirName;
+
+    pZip = mZipSet.getZip(ap.path);
+    if (pZip == NULL) {
+        ALOGW("Failure opening zip %s\n", ap.path.string());
+        return false;
+    }
+
+    zipName = ZipSet::getPathName(ap.path.string());
+
+    /* convert "sounds" to "rootDir/sounds" */
+    if (rootDir != NULL) dirName = rootDir;
+    dirName.appendPath(baseDirName);
+
+    /*
+     * Scan through the list of files, looking for a match.  The files in
+     * the Zip table of contents are not in sorted order, so we have to
+     * process the entire list.  We're looking for a string that begins
+     * with the characters in "dirName", is followed by a '/', and has no
+     * subsequent '/' in the stuff that follows.
+     *
+     * What makes this especially fun is that directories are not stored
+     * explicitly in Zip archives, so we have to infer them from context.
+     * When we see "sounds/foo.wav" we have to leave a note to ourselves
+     * to insert a directory called "sounds" into the list.  We store
+     * these in temporary vector so that we only return each one once.
+     *
+     * Name comparisons are case-sensitive to match UNIX filesystem
+     * semantics.
+     */
+    int dirNameLen = dirName.length();
+    for (int i = 0; i < pZip->getNumEntries(); i++) {
+        ZipEntryRO entry;
+        char nameBuf[256];
+
+        entry = pZip->findEntryByIndex(i);
+        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
+            // TODO: fix this if we expect to have long names
+            ALOGE("ARGH: name too long?\n");
+            continue;
+        }
+        //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
+        if (dirNameLen == 0 ||
+            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
+             nameBuf[dirNameLen] == '/'))
+        {
+            const char* cp;
+            const char* nextSlash;
+
+            cp = nameBuf + dirNameLen;
+            if (dirNameLen != 0)
+                cp++;       // advance past the '/'
+
+            nextSlash = strchr(cp, '/');
+//xxx this may break if there are bare directory entries
+            if (nextSlash == NULL) {
+                /* this is a file in the requested directory */
+
+                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
+
+                info.setSourceName(
+                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+
+                contents.add(info);
+                //printf("FOUND: file '%s'\n", info.getFileName().string());
+            } else {
+                /* this is a subdir; add it if we don't already have it*/
+                String8 subdirName(cp, nextSlash - cp);
+                size_t j;
+                size_t N = dirs.size();
+
+                for (j = 0; j < N; j++) {
+                    if (subdirName == dirs[j]) {
+                        break;
+                    }
+                }
+                if (j == N) {
+                    dirs.add(subdirName);
+                }
+
+                //printf("FOUND: dir '%s'\n", subdirName.string());
+            }
+        }
+    }
+
+    /*
+     * Add the set of unique directories.
+     */
+    for (int i = 0; i < (int) dirs.size(); i++) {
+        info.set(dirs[i], kFileTypeDirectory);
+        info.setSourceName(
+            createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+        contents.add(info);
+    }
+
+    mergeInfoLocked(pMergedInfo, &contents);
+
+    return true;
+}
+
+
+/*
+ * Merge two vectors of FileInfo.
+ *
+ * The merged contents will be stuffed into *pMergedInfo.
+ *
+ * If an entry for a file exists in both "pMergedInfo" and "pContents",
+ * we use the newer "pContents" entry.
+ */
+void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const SortedVector<AssetDir::FileInfo>* pContents)
+{
+    /*
+     * Merge what we found in this directory with what we found in
+     * other places.
+     *
+     * Two basic approaches:
+     * (1) Create a new array that holds the unique values of the two
+     *     arrays.
+     * (2) Take the elements from pContents and shove them into pMergedInfo.
+     *
+     * Because these are vectors of complex objects, moving elements around
+     * inside the vector requires constructing new objects and allocating
+     * storage for members.  With approach #1, we're always adding to the
+     * end, whereas with #2 we could be inserting multiple elements at the
+     * front of the vector.  Approach #1 requires a full copy of the
+     * contents of pMergedInfo, but approach #2 requires the same copy for
+     * every insertion at the front of pMergedInfo.
+     *
+     * (We should probably use a SortedVector interface that allows us to
+     * just stuff items in, trusting us to maintain the sort order.)
+     */
+    SortedVector<AssetDir::FileInfo>* pNewSorted;
+    int mergeMax, contMax;
+    int mergeIdx, contIdx;
+
+    pNewSorted = new SortedVector<AssetDir::FileInfo>;
+    mergeMax = pMergedInfo->size();
+    contMax = pContents->size();
+    mergeIdx = contIdx = 0;
+
+    while (mergeIdx < mergeMax || contIdx < contMax) {
+        if (mergeIdx == mergeMax) {
+            /* hit end of "merge" list, copy rest of "contents" */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        } else if (contIdx == contMax) {
+            /* hit end of "cont" list, copy rest of "merge" */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
+        {
+            /* items are identical, add newer and advance both indices */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            mergeIdx++;
+            contIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
+        {
+            /* "merge" is lower, add that one */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else {
+            /* "cont" is lower, add that one */
+            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        }
+    }
+
+    /*
+     * Overwrite the "merged" list with the new stuff.
+     */
+    *pMergedInfo = *pNewSorted;
+    delete pNewSorted;
+
+#if 0       // for Vector, rather than SortedVector
+    int i, j;
+    for (i = pContents->size() -1; i >= 0; i--) {
+        bool add = true;
+
+        for (j = pMergedInfo->size() -1; j >= 0; j--) {
+            /* case-sensitive comparisons, to behave like UNIX fs */
+            if (strcmp(pContents->itemAt(i).mFileName,
+                       pMergedInfo->itemAt(j).mFileName) == 0)
+            {
+                /* match, don't add this entry */
+                add = false;
+                break;
+            }
+        }
+
+        if (add)
+            pMergedInfo->add(pContents->itemAt(i));
+    }
+#endif
+}
+
+
+/*
+ * Load all files into the file name cache.  We want to do this across
+ * all combinations of { appname, locale, vendor }, performing a recursive
+ * directory traversal.
+ *
+ * This is not the most efficient data structure.  Also, gathering the
+ * information as we needed it (file-by-file or directory-by-directory)
+ * would be faster.  However, on the actual device, 99% of the files will
+ * live in Zip archives, so this list will be very small.  The trouble
+ * is that we have to check the "loose" files first, so it's important
+ * that we don't beat the filesystem silly looking for files that aren't
+ * there.
+ *
+ * Note on thread safety: this is the only function that causes updates
+ * to mCache, and anybody who tries to use it will call here if !mCacheValid,
+ * so we need to employ a mutex here.
+ */
+void AssetManager::loadFileNameCacheLocked(void)
+{
+    assert(!mCacheValid);
+    assert(mCache.size() == 0);
+
+#ifdef DO_TIMINGS   // need to link against -lrt for this now
+    DurationTimer timer;
+    timer.start();
+#endif
+
+    fncScanLocked(&mCache, "");
+
+#ifdef DO_TIMINGS
+    timer.stop();
+    ALOGD("Cache scan took %.3fms\n",
+        timer.durationUsecs() / 1000.0);
+#endif
+
+#if 0
+    int i;
+    printf("CACHED FILE LIST (%d entries):\n", mCache.size());
+    for (i = 0; i < (int) mCache.size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            mCache.itemAt(i).getFileType(),
+            (const char*) mCache.itemAt(i).getFileName());
+    }
+#endif
+
+    mCacheValid = true;
+}
+
+/*
+ * Scan up to 8 versions of the specified directory.
+ */
+void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const char* dirName)
+{
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
+        if (mLocale != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
+        if (mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
+        if (mLocale != NULL && mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
+    }
+}
+
+/*
+ * Recursively scan this directory and all subdirs.
+ *
+ * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
+ * files, and we prepend the extended partial path to the filenames.
+ */
+bool AssetManager::fncScanAndMergeDirLocked(
+    SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* locale, const char* vendor,
+    const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 partialPath;
+    String8 fullPath;
+
+    // XXX This is broken -- the filename cache needs to hold the base
+    // asset path separately from its filename.
+    
+    partialPath = createPathNameLocked(ap, locale, vendor);
+    if (dirName[0] != '\0') {
+        partialPath.appendPath(dirName);
+    }
+
+    fullPath = partialPath;
+    pContents = scanDirLocked(fullPath);
+    if (pContents == NULL) {
+        return false;       // directory did not exist
+    }
+
+    /*
+     * Scan all subdirectories of the current dir, merging what we find
+     * into "pMergedInfo".
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
+            String8 subdir(dirName);
+            subdir.appendPath(pContents->itemAt(i).getFileName());
+
+            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
+        }
+    }
+
+    /*
+     * To be consistent, we want entries for the root directory.  If
+     * we're the root, add one now.
+     */
+    if (dirName[0] == '\0') {
+        AssetDir::FileInfo tmpInfo;
+
+        tmpInfo.set(String8(""), kFileTypeDirectory);
+        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
+        pContents->add(tmpInfo);
+    }
+
+    /*
+     * We want to prepend the extended partial path to every entry in
+     * "pContents".  It's the same value for each entry, so this will
+     * not change the sorting order of the vector contents.
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        const AssetDir::FileInfo& info = pContents->itemAt(i);
+        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+    return true;
+}
+
+/*
+ * Trash the cache.
+ */
+void AssetManager::purgeFileNameCacheLocked(void)
+{
+    mCacheValid = false;
+    mCache.clear();
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::SharedZip
+ * ===========================================================================
+ */
+
+
+Mutex AssetManager::SharedZip::gLock;
+DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
+
+AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
+    : mPath(path), mZipFile(NULL), mModWhen(modWhen),
+      mResourceTableAsset(NULL), mResourceTable(NULL)
+{
+    //ALOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+    mZipFile = new ZipFileRO;
+    ALOGV("+++ opening zip '%s'\n", mPath.string());
+    if (mZipFile->open(mPath.string()) != NO_ERROR) {
+        ALOGD("failed to open Zip archive '%s'\n", mPath.string());
+        delete mZipFile;
+        mZipFile = NULL;
+    }
+}
+
+sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
+{
+    AutoMutex _l(gLock);
+    time_t modWhen = getFileModDate(path);
+    sp<SharedZip> zip = gOpen.valueFor(path).promote();
+    if (zip != NULL && zip->mModWhen == modWhen) {
+        return zip;
+    }
+    zip = new SharedZip(path, modWhen);
+    gOpen.add(path, zip);
+    return zip;
+
+}
+
+ZipFileRO* AssetManager::SharedZip::getZip()
+{
+    return mZipFile;
+}
+
+Asset* AssetManager::SharedZip::getResourceTableAsset()
+{
+    ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
+    return mResourceTableAsset;
+}
+
+Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
+{
+    {
+        AutoMutex _l(gLock);
+        if (mResourceTableAsset == NULL) {
+            mResourceTableAsset = asset;
+            // This is not thread safe the first time it is called, so
+            // do it here with the global lock held.
+            asset->getBuffer(true);
+            return asset;
+        }
+    }
+    delete asset;
+    return mResourceTableAsset;
+}
+
+ResTable* AssetManager::SharedZip::getResourceTable()
+{
+    ALOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
+    return mResourceTable;
+}
+
+ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res)
+{
+    {
+        AutoMutex _l(gLock);
+        if (mResourceTable == NULL) {
+            mResourceTable = res;
+            return res;
+        }
+    }
+    delete res;
+    return mResourceTable;
+}
+
+bool AssetManager::SharedZip::isUpToDate()
+{
+    time_t modWhen = getFileModDate(mPath.string());
+    return mModWhen == modWhen;
+}
+
+AssetManager::SharedZip::~SharedZip()
+{
+    //ALOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+    if (mResourceTable != NULL) {
+        delete mResourceTable;
+    }
+    if (mResourceTableAsset != NULL) {
+        delete mResourceTableAsset;
+    }
+    if (mZipFile != NULL) {
+        delete mZipFile;
+        ALOGV("Closed '%s'\n", mPath.string());
+    }
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::ZipSet
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+AssetManager::ZipSet::ZipSet(void)
+{
+}
+
+/*
+ * Destructor.  Close any open archives.
+ */
+AssetManager::ZipSet::~ZipSet(void)
+{
+    size_t N = mZipFile.size();
+    for (size_t i = 0; i < N; i++)
+        closeZip(i);
+}
+
+/*
+ * Close a Zip file and reset the entry.
+ */
+void AssetManager::ZipSet::closeZip(int idx)
+{
+    mZipFile.editItemAt(idx) = NULL;
+}
+
+
+/*
+ * Retrieve the appropriate Zip file from the set.
+ */
+ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getZip();
+}
+
+Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getResourceTableAsset();
+}
+
+Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path,
+                                                 Asset* asset)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    // doesn't make sense to call before previously accessing.
+    return zip->setResourceTableAsset(asset);
+}
+
+ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getResourceTable();
+}
+
+ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path,
+                                                    ResTable* res)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    // doesn't make sense to call before previously accessing.
+    return zip->setResourceTable(res);
+}
+
+/*
+ * Generate the partial pathname for the specified archive.  The caller
+ * gets to prepend the asset root directory.
+ *
+ * Returns something like "common/en-US-noogle.jar".
+ */
+/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
+{
+    return String8(zipPath);
+}
+
+bool AssetManager::ZipSet::isUpToDate()
+{
+    const size_t N = mZipFile.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * Compute the zip file's index.
+ *
+ * "appName", "locale", and "vendor" should be set to NULL to indicate the
+ * default directory.
+ */
+int AssetManager::ZipSet::getIndex(const String8& zip) const
+{
+    const size_t N = mZipPath.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipPath[i] == zip) {
+            return i;
+        }
+    }
+
+    mZipPath.add(zip);
+    mZipFile.add(NULL);
+
+    return mZipPath.size()-1;
+}
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
new file mode 100644
index 0000000..4e3b522
--- /dev/null
+++ b/libs/androidfw/BackupData.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "backup_data"
+
+#include <androidfw/BackupHelpers.h>
+#include <utils/ByteOrder.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+
+namespace android {
+
+static const bool DEBUG = false;
+
+/*
+ * File Format (v1):
+ *
+ * All ints are stored little-endian.
+ *
+ *  - An app_header_v1 struct.
+ *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
+ *  - A sequence of zero or more key/value paires (entities), each with
+ *      - A entity_header_v1 struct
+ *      - The key, utf-8, null terminated, padded to 4-byte boundary.
+ *      - The value, padded to 4 byte boundary
+ */
+
+const static int ROUND_UP[4] = { 0, 3, 2, 1 };
+
+static inline size_t
+round_up(size_t n)
+{
+    return n + ROUND_UP[n % 4];
+}
+
+static inline size_t
+padding_extra(size_t n)
+{
+    return ROUND_UP[n % 4];
+}
+
+BackupDataWriter::BackupDataWriter(int fd)
+    :m_fd(fd),
+     m_status(NO_ERROR),
+     m_pos(0),
+     m_entityCount(0)
+{
+}
+
+BackupDataWriter::~BackupDataWriter()
+{
+}
+
+// Pad out anything they've previously written to the next 4 byte boundary.
+status_t
+BackupDataWriter::write_padding_for(int n)
+{
+    ssize_t amt;
+    ssize_t paddingSize;
+
+    paddingSize = padding_extra(n);
+    if (paddingSize > 0) {
+        uint32_t padding = 0xbcbcbcbc;
+        if (DEBUG) ALOGI("writing %d padding bytes for %d", paddingSize, n);
+        amt = write(m_fd, &padding, paddingSize);
+        if (amt != paddingSize) {
+            m_status = errno;
+            return m_status;
+        }
+        m_pos += amt;
+    }
+    return NO_ERROR;
+}
+
+status_t
+BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+
+    ssize_t amt;
+
+    amt = write_padding_for(m_pos);
+    if (amt != 0) {
+        return amt;
+    }
+
+    String8 k;
+    if (m_keyPrefix.length() > 0) {
+        k = m_keyPrefix;
+        k += ":";
+        k += key;
+    } else {
+        k = key;
+    }
+    if (DEBUG) {
+        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(),
+                key.string(), dataSize);
+    }
+
+    entity_header_v1 header;
+    ssize_t keyLen;
+
+    keyLen = k.length();
+
+    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
+    header.keyLen = tolel(keyLen);
+    header.dataSize = tolel(dataSize);
+
+    if (DEBUG) ALOGI("writing entity header, %d bytes", sizeof(entity_header_v1));
+    amt = write(m_fd, &header, sizeof(entity_header_v1));
+    if (amt != sizeof(entity_header_v1)) {
+        m_status = errno;
+        return m_status;
+    }
+    m_pos += amt;
+
+    if (DEBUG) ALOGI("writing entity header key, %d bytes", keyLen+1);
+    amt = write(m_fd, k.string(), keyLen+1);
+    if (amt != keyLen+1) {
+        m_status = errno;
+        return m_status;
+    }
+    m_pos += amt;
+
+    amt = write_padding_for(keyLen+1);
+
+    m_entityCount++;
+
+    return amt;
+}
+
+status_t
+BackupDataWriter::WriteEntityData(const void* data, size_t size)
+{
+    if (DEBUG) ALOGD("Writing data: size=%lu", (unsigned long) size);
+
+    if (m_status != NO_ERROR) {
+        if (DEBUG) {
+            ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
+        }
+        return m_status;
+    }
+
+    // We don't write padding here, because they're allowed to call this several
+    // times with smaller buffers.  We write it at the end of WriteEntityHeader
+    // instead.
+    ssize_t amt = write(m_fd, data, size);
+    if (amt != (ssize_t)size) {
+        m_status = errno;
+        if (DEBUG) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
+        return m_status;
+    }
+    m_pos += amt;
+    return NO_ERROR;
+}
+
+void
+BackupDataWriter::SetKeyPrefix(const String8& keyPrefix)
+{
+    m_keyPrefix = keyPrefix;
+}
+
+
+BackupDataReader::BackupDataReader(int fd)
+    :m_fd(fd),
+     m_done(false),
+     m_status(NO_ERROR),
+     m_pos(0),
+     m_entityCount(0)
+{
+    memset(&m_header, 0, sizeof(m_header));
+}
+
+BackupDataReader::~BackupDataReader()
+{
+}
+
+status_t
+BackupDataReader::Status()
+{
+    return m_status;
+}
+
+#define CHECK_SIZE(actual, expected) \
+    do { \
+        if ((actual) != (expected)) { \
+            if ((actual) == 0) { \
+                m_status = EIO; \
+                m_done = true; \
+            } else { \
+                m_status = errno; \
+                ALOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
+                    long(actual), long(expected), __LINE__, strerror(m_status)); \
+            } \
+            return m_status; \
+        } \
+    } while(0)
+#define SKIP_PADDING() \
+    do { \
+        status_t err = skip_padding(); \
+        if (err != NO_ERROR) { \
+            ALOGD("SKIP_PADDING FAILED at line %d", __LINE__); \
+            m_status = err; \
+            return err; \
+        } \
+    } while(0)
+
+status_t
+BackupDataReader::ReadNextHeader(bool* done, int* type)
+{
+    *done = m_done;
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+
+    int amt;
+
+    amt = skip_padding();
+    if (amt == EIO) {
+        *done = m_done = true;
+        return NO_ERROR;
+    }
+    else if (amt != NO_ERROR) {
+        return amt;
+    }
+    amt = read(m_fd, &m_header, sizeof(m_header));
+    *done = m_done = (amt == 0);
+    if (*done) {
+        return NO_ERROR;
+    }
+    CHECK_SIZE(amt, sizeof(m_header));
+    m_pos += sizeof(m_header);
+    if (type) {
+        *type = m_header.type;
+    }
+
+    // validate and fix up the fields.
+    m_header.type = fromlel(m_header.type);
+    switch (m_header.type)
+    {
+        case BACKUP_HEADER_ENTITY_V1:
+        {
+            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
+            if (m_header.entity.keyLen <= 0) {
+                ALOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
+                        (int)m_header.entity.keyLen);
+                m_status = EINVAL;
+            }
+            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
+            m_entityCount++;
+
+            // read the rest of the header (filename)
+            size_t size = m_header.entity.keyLen;
+            char* buf = m_key.lockBuffer(size);
+            if (buf == NULL) {
+                m_status = ENOMEM;
+                return m_status;
+            }
+            int amt = read(m_fd, buf, size+1);
+            CHECK_SIZE(amt, (int)size+1);
+            m_key.unlockBuffer(size);
+            m_pos += size+1;
+            SKIP_PADDING();
+            m_dataEndPos = m_pos + m_header.entity.dataSize;
+
+            break;
+        }
+        default:
+            ALOGD("Chunk header at %d has invalid type: 0x%08x",
+                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);
+            m_status = EINVAL;
+    }
+    
+    return m_status;
+}
+
+bool
+BackupDataReader::HasEntities()
+{
+    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
+}
+
+status_t
+BackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
+        return EINVAL;
+    }
+    *key = m_key;
+    *dataSize = m_header.entity.dataSize;
+    return NO_ERROR;
+}
+
+status_t
+BackupDataReader::SkipEntityData()
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
+        return EINVAL;
+    }
+    if (m_header.entity.dataSize > 0) {
+        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
+        if (pos == -1) {
+            return errno;
+        }
+        m_pos = pos;
+    }
+    SKIP_PADDING();
+    return NO_ERROR;
+}
+
+ssize_t
+BackupDataReader::ReadEntityData(void* data, size_t size)
+{
+    if (m_status != NO_ERROR) {
+        return -1;
+    }
+    int remaining = m_dataEndPos - m_pos;
+    //ALOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
+    //        size, m_pos, m_dataEndPos, remaining);
+    if (remaining <= 0) {
+        return 0;
+    }
+    if (((int)size) > remaining) {
+        size = remaining;
+    }
+    //ALOGD("   reading %d bytes", size);
+    int amt = read(m_fd, data, size);
+    if (amt < 0) {
+        m_status = errno;
+        return -1;
+    }
+    if (amt == 0) {
+        m_status = EIO;
+        m_done = true;
+    }
+    m_pos += amt;
+    return amt;
+}
+
+status_t
+BackupDataReader::skip_padding()
+{
+    ssize_t amt;
+    ssize_t paddingSize;
+
+    paddingSize = padding_extra(m_pos);
+    if (paddingSize > 0) {
+        uint32_t padding;
+        amt = read(m_fd, &padding, paddingSize);
+        CHECK_SIZE(amt, paddingSize);
+        m_pos += amt;
+    }
+    return NO_ERROR;
+}
+
+
+} // namespace android
diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
new file mode 100644
index 0000000..b8d3f48
--- /dev/null
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -0,0 +1,1591 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "file_backup_helper"
+
+#include <androidfw/BackupHelpers.h>
+
+#include <utils/KeyedVector.h>
+#include <utils/ByteOrder.h>
+#include <utils/String8.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/time.h>  // for utimes
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <zlib.h>
+
+#include <cutils/log.h>
+
+namespace android {
+
+#define MAGIC0 0x70616e53 // Snap
+#define MAGIC1 0x656c6946 // File
+
+/*
+ * File entity data format (v1):
+ *
+ *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
+ *   - 12 bytes of metadata
+ *   - the file data itself
+ *
+ * i.e. a 16-byte metadata header followed by the raw file data.  If the
+ * restore code does not recognize the metadata version, it can still
+ * interpret the file data itself correctly.
+ *
+ * file_metadata_v1:
+ *
+ *   - 4 byte version number === 0x00000001 (little endian)
+ *   - 4-byte access mode (little-endian)
+ *   - undefined (8 bytes)
+ */
+
+struct file_metadata_v1 {
+    int version;
+    int mode;
+    int undefined_1;
+    int undefined_2;
+};
+
+const static int CURRENT_METADATA_VERSION = 1;
+
+#if 1
+#define LOGP(f, x...)
+#else
+#if TEST_BACKUP_HELPERS
+#define LOGP(f, x...) printf(f "\n", x)
+#else
+#define LOGP(x...) ALOGD(x)
+#endif
+#endif
+
+const static int ROUND_UP[4] = { 0, 3, 2, 1 };
+
+static inline int
+round_up(int n)
+{
+    return n + ROUND_UP[n % 4];
+}
+
+static int
+read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
+{
+    int bytesRead = 0;
+    int amt;
+    SnapshotHeader header;
+
+    amt = read(fd, &header, sizeof(header));
+    if (amt != sizeof(header)) {
+        return errno;
+    }
+    bytesRead += amt;
+
+    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
+        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
+        return 1;
+    }
+
+    for (int i=0; i<header.fileCount; i++) {
+        FileState file;
+        char filenameBuf[128];
+
+        amt = read(fd, &file, sizeof(FileState));
+        if (amt != sizeof(FileState)) {
+            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
+            return 1;
+        }
+        bytesRead += amt;
+
+        // filename is not NULL terminated, but it is padded
+        int nameBufSize = round_up(file.nameLen);
+        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
+                ? filenameBuf
+                : (char*)malloc(nameBufSize);
+        amt = read(fd, filename, nameBufSize);
+        if (amt == nameBufSize) {
+            snapshot->add(String8(filename, file.nameLen), file);
+        }
+        bytesRead += amt;
+        if (filename != filenameBuf) {
+            free(filename);
+        }
+        if (amt != nameBufSize) {
+            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
+            return 1;
+        }
+    }
+
+    if (header.totalSize != bytesRead) {
+        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
+                header.totalSize, bytesRead);
+        return 1;
+    }
+
+    return 0;
+}
+
+static int
+write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
+{
+    int fileCount = 0;
+    int bytesWritten = sizeof(SnapshotHeader);
+    // preflight size
+    const int N = snapshot.size();
+    for (int i=0; i<N; i++) {
+        const FileRec& g = snapshot.valueAt(i);
+        if (!g.deleted) {
+            const String8& name = snapshot.keyAt(i);
+            bytesWritten += sizeof(FileState) + round_up(name.length());
+            fileCount++;
+        }
+    }
+
+    LOGP("write_snapshot_file fd=%d\n", fd);
+
+    int amt;
+    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
+
+    amt = write(fd, &header, sizeof(header));
+    if (amt != sizeof(header)) {
+        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
+        return errno;
+    }
+
+    for (int i=0; i<N; i++) {
+        FileRec r = snapshot.valueAt(i);
+        if (!r.deleted) {
+            const String8& name = snapshot.keyAt(i);
+            int nameLen = r.s.nameLen = name.length();
+
+            amt = write(fd, &r.s, sizeof(FileState));
+            if (amt != sizeof(FileState)) {
+                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
+                return 1;
+            }
+
+            // filename is not NULL terminated, but it is padded
+            amt = write(fd, name.string(), nameLen);
+            if (amt != nameLen) {
+                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
+                return 1;
+            }
+            int paddingLen = ROUND_UP[nameLen % 4];
+            if (paddingLen != 0) {
+                int padding = 0xabababab;
+                amt = write(fd, &padding, paddingLen);
+                if (amt != paddingLen) {
+                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
+                            paddingLen, strerror(errno));
+                    return 1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int
+write_delete_file(BackupDataWriter* dataStream, const String8& key)
+{
+    LOGP("write_delete_file %s\n", key.string());
+    return dataStream->WriteEntityHeader(key, -1);
+}
+
+static int
+write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
+        char const* realFilename)
+{
+    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
+
+    const int bufsize = 4*1024;
+    int err;
+    int amt;
+    int fileSize;
+    int bytesLeft;
+    file_metadata_v1 metadata;
+
+    char* buf = (char*)malloc(bufsize);
+    int crc = crc32(0L, Z_NULL, 0);
+
+
+    fileSize = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+
+    if (sizeof(metadata) != 16) {
+        ALOGE("ERROR: metadata block is the wrong size!");
+    }
+
+    bytesLeft = fileSize + sizeof(metadata);
+    err = dataStream->WriteEntityHeader(key, bytesLeft);
+    if (err != 0) {
+        free(buf);
+        return err;
+    }
+
+    // store the file metadata first
+    metadata.version = tolel(CURRENT_METADATA_VERSION);
+    metadata.mode = tolel(mode);
+    metadata.undefined_1 = metadata.undefined_2 = 0;
+    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
+    if (err != 0) {
+        free(buf);
+        return err;
+    }
+    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
+
+    // now store the file content
+    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
+        bytesLeft -= amt;
+        if (bytesLeft < 0) {
+            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
+        }
+        err = dataStream->WriteEntityData(buf, amt);
+        if (err != 0) {
+            free(buf);
+            return err;
+        }
+    }
+    if (bytesLeft != 0) {
+        if (bytesLeft > 0) {
+            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
+            // even though the data we're sending is probably bad.
+            memset(buf, 0, bufsize);
+            while (bytesLeft > 0) {
+                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
+                bytesLeft -= amt;
+                err = dataStream->WriteEntityData(buf, amt);
+                if (err != 0) {
+                    free(buf);
+                    return err;
+                }
+            }
+        }
+        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
+                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
+    }
+
+    free(buf);
+    return NO_ERROR;
+}
+
+static int
+write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
+{
+    int err;
+    struct stat st;
+
+    err = stat(realFilename, &st);
+    if (err < 0) {
+        return errno;
+    }
+
+    int fd = open(realFilename, O_RDONLY);
+    if (fd == -1) {
+        return errno;
+    }
+
+    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
+    close(fd);
+    return err;
+}
+
+static int
+compute_crc32(int fd)
+{
+    const int bufsize = 4*1024;
+    int amt;
+
+    char* buf = (char*)malloc(bufsize);
+    int crc = crc32(0L, Z_NULL, 0);
+
+    lseek(fd, 0, SEEK_SET);
+
+    while ((amt = read(fd, buf, bufsize)) != 0) {
+        crc = crc32(crc, (Bytef*)buf, amt);
+    }
+
+    free(buf);
+    return crc;
+}
+
+int
+back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
+        char const* const* files, char const* const* keys, int fileCount)
+{
+    int err;
+    KeyedVector<String8,FileState> oldSnapshot;
+    KeyedVector<String8,FileRec> newSnapshot;
+
+    if (oldSnapshotFD != -1) {
+        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
+        if (err != 0) {
+            // On an error, treat this as a full backup.
+            oldSnapshot.clear();
+        }
+    }
+
+    for (int i=0; i<fileCount; i++) {
+        String8 key(keys[i]);
+        FileRec r;
+        char const* file = files[i];
+        r.file = file;
+        struct stat st;
+
+        err = stat(file, &st);
+        if (err != 0) {
+            r.deleted = true;
+        } else {
+            r.deleted = false;
+            r.s.modTime_sec = st.st_mtime;
+            r.s.modTime_nsec = 0; // workaround sim breakage
+            //r.s.modTime_nsec = st.st_mtime_nsec;
+            r.s.mode = st.st_mode;
+            r.s.size = st.st_size;
+            // we compute the crc32 later down below, when we already have the file open.
+
+            if (newSnapshot.indexOfKey(key) >= 0) {
+                LOGP("back_up_files key already in use '%s'", key.string());
+                return -1;
+            }
+        }
+        newSnapshot.add(key, r);
+    }
+
+    int n = 0;
+    int N = oldSnapshot.size();
+    int m = 0;
+
+    while (n<N && m<fileCount) {
+        const String8& p = oldSnapshot.keyAt(n);
+        const String8& q = newSnapshot.keyAt(m);
+        FileRec& g = newSnapshot.editValueAt(m);
+        int cmp = p.compare(q);
+        if (g.deleted || cmp < 0) {
+            // file removed
+            LOGP("file removed: %s", p.string());
+            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
+            dataStream->WriteEntityHeader(p, -1);
+            n++;
+        }
+        else if (cmp > 0) {
+            // file added
+            LOGP("file added: %s", g.file.string());
+            write_update_file(dataStream, q, g.file.string());
+            m++;
+        }
+        else {
+            // both files exist, check them
+            const FileState& f = oldSnapshot.valueAt(n);
+
+            int fd = open(g.file.string(), O_RDONLY);
+            if (fd < 0) {
+                // We can't open the file.  Don't report it as a delete either.  Let the
+                // server keep the old version.  Maybe they'll be able to deal with it
+                // on restore.
+                LOGP("Unable to open file %s - skipping", g.file.string());
+            } else {
+                g.s.crc32 = compute_crc32(fd);
+
+                LOGP("%s", q.string());
+                LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
+                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
+                LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
+                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
+                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
+                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
+                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
+                }
+
+                close(fd);
+            }
+            n++;
+            m++;
+        }
+    }
+
+    // these were deleted
+    while (n<N) {
+        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
+        n++;
+    }
+
+    // these were added
+    while (m<fileCount) {
+        const String8& q = newSnapshot.keyAt(m);
+        FileRec& g = newSnapshot.editValueAt(m);
+        write_update_file(dataStream, q, g.file.string());
+        m++;
+    }
+
+    err = write_snapshot_file(newSnapshotFD, newSnapshot);
+
+    return 0;
+}
+
+// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of
+// returning the initial dest, return a pointer to the trailing NUL.
+static char* strcpy_ptr(char* dest, const char* str) {
+    if (dest && str) {
+        while ((*dest = *str) != 0) {
+            dest++;
+            str++;
+        }
+    }
+    return dest;
+}
+
+static void calc_tar_checksum(char* buf) {
+    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
+    memset(buf + 148, ' ', 8);
+
+    uint16_t sum = 0;
+    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
+        sum += *p;
+    }
+
+    // Now write the real checksum value:
+    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
+    sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
+}
+
+// Returns number of bytes written
+static int write_pax_header_entry(char* buf, const char* key, const char* value) {
+    // start with the size of "1 key=value\n"
+    int len = strlen(key) + strlen(value) + 4;
+    if (len > 9) len++;
+    if (len > 99) len++;
+    if (len > 999) len++;
+    // since PATH_MAX is 4096 we don't expect to have to generate any single
+    // header entry longer than 9999 characters
+
+    return sprintf(buf, "%d %s=%s\n", len, key, value);
+}
+
+// Wire format to the backup manager service is chunked:  each chunk is prefixed by
+// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
+void send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
+    uint32_t chunk_size_no = htonl(size);
+    writer->WriteEntityData(&chunk_size_no, 4);
+    if (size != 0) writer->WriteEntityData(buffer, size);
+}
+
+int write_tarfile(const String8& packageName, const String8& domain,
+        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
+{
+    // In the output stream everything is stored relative to the root
+    const char* relstart = filepath.string() + rootpath.length();
+    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
+    String8 relpath(relstart);
+
+    // If relpath is empty, it means this is the top of one of the standard named
+    // domain directories, so we should just skip it
+    if (relpath.length() == 0) {
+        return 0;
+    }
+
+    // Too long a name for the ustar format?
+    //    "apps/" + packagename + '/' + domainpath < 155 chars
+    //    relpath < 100 chars
+    bool needExtended = false;
+    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
+        needExtended = true;
+    }
+
+    // Non-7bit-clean path also means needing pax extended format
+    if (!needExtended) {
+        for (size_t i = 0; i < filepath.length(); i++) {
+            if ((filepath[i] & 0x80) != 0) {
+                needExtended = true;
+                break;
+            }
+        }
+    }
+
+    int err = 0;
+    struct stat64 s;
+    if (lstat64(filepath.string(), &s) != 0) {
+        err = errno;
+        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
+        return err;
+    }
+
+    String8 fullname;   // for pax later on
+    String8 prefix;
+
+    const int isdir = S_ISDIR(s.st_mode);
+    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
+
+    // !!! TODO: use mmap when possible to avoid churning the buffer cache
+    // !!! TODO: this will break with symlinks; need to use readlink(2)
+    int fd = open(filepath.string(), O_RDONLY);
+    if (fd < 0) {
+        err = errno;
+        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
+        return err;
+    }
+
+    // read/write up to this much at a time.
+    const size_t BUFSIZE = 32 * 1024;
+    char* buf = (char *)calloc(1,BUFSIZE);
+    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch
+    char* paxData = buf + 1024;
+
+    if (buf == NULL) {
+        ALOGE("Out of mem allocating transfer buffer");
+        err = ENOMEM;
+        goto done;
+    }
+
+    // Magic fields for the ustar file format
+    strcat(buf + 257, "ustar");
+    strcat(buf + 263, "00");
+
+    // [ 265 : 32 ] user name, ignored on restore
+    // [ 297 : 32 ] group name, ignored on restore
+
+    // [ 100 :   8 ] file mode
+    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
+
+    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
+    // [ 116 :   8 ] gid -- ignored in Android format
+    snprintf(buf + 108, 8, "0%lo", s.st_uid);
+    snprintf(buf + 116, 8, "0%lo", s.st_gid);
+
+    // [ 124 :  12 ] file size in bytes
+    if (s.st_size > 077777777777LL) {
+        // very large files need a pax extended size header
+        needExtended = true;
+    }
+    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
+
+    // [ 136 :  12 ] last mod time as a UTC time_t
+    snprintf(buf + 136, 12, "%0lo", s.st_mtime);
+
+    // [ 156 :   1 ] link/file type
+    uint8_t type;
+    if (isdir) {
+        type = '5';     // tar magic: '5' == directory
+    } else if (S_ISREG(s.st_mode)) {
+        type = '0';     // tar magic: '0' == normal file
+    } else {
+        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
+        goto cleanup;
+    }
+    buf[156] = type;
+
+    // [ 157 : 100 ] name of linked file [not implemented]
+
+    {
+        // Prefix and main relative path.  Path lengths have been preflighted.
+        if (packageName.length() > 0) {
+            prefix = "apps/";
+            prefix += packageName;
+        }
+        if (domain.length() > 0) {
+            prefix.appendPath(domain);
+        }
+
+        // pax extended means we don't put in a prefix field, and put a different
+        // string in the basic name field.  We can also construct the full path name
+        // out of the substrings we've now built.
+        fullname = prefix;
+        fullname.appendPath(relpath);
+
+        // ustar:
+        //    [   0 : 100 ]; file name/path
+        //    [ 345 : 155 ] filename path prefix
+        // We only use the prefix area if fullname won't fit in the path
+        if (fullname.length() > 100) {
+            strncpy(buf, relpath.string(), 100);
+            strncpy(buf + 345, prefix.string(), 155);
+        } else {
+            strncpy(buf, fullname.string(), 100);
+        }
+    }
+
+    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
+
+    ALOGI("   Name: %s", fullname.string());
+
+    // If we're using a pax extended header, build & write that here; lengths are
+    // already preflighted
+    if (needExtended) {
+        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
+        char* p = paxData;
+
+        // construct the pax extended header data block
+        memset(paxData, 0, BUFSIZE - (paxData - buf));
+        int len;
+
+        // size header -- calc len in digits by actually rendering the number
+        // to a string - brute force but simple
+        snprintf(sizeStr, sizeof(sizeStr), "%lld", s.st_size);
+        p += write_pax_header_entry(p, "size", sizeStr);
+
+        // fullname was generated above with the ustar paths
+        p += write_pax_header_entry(p, "path", fullname.string());
+
+        // Now we know how big the pax data is
+        int paxLen = p - paxData;
+
+        // Now build the pax *header* templated on the ustar header
+        memcpy(paxHeader, buf, 512);
+
+        String8 leaf = fullname.getPathLeaf();
+        memset(paxHeader, 0, 100);                  // rewrite the name area
+        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
+        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
+        strncpy(paxHeader + 345, prefix.string(), 155);
+
+        paxHeader[156] = 'x';                       // mark it as a pax extended header
+
+        // [ 124 :  12 ] size of pax extended header data
+        memset(paxHeader + 124, 0, 12);
+        snprintf(paxHeader + 124, 12, "%011o", p - paxData);
+
+        // Checksum and write the pax block header
+        calc_tar_checksum(paxHeader);
+        send_tarfile_chunk(writer, paxHeader, 512);
+
+        // Now write the pax data itself
+        int paxblocks = (paxLen + 511) / 512;
+        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
+    }
+
+    // Checksum and write the 512-byte ustar file header block to the output
+    calc_tar_checksum(buf);
+    send_tarfile_chunk(writer, buf, 512);
+
+    // Now write the file data itself, for real files.  We honor tar's convention that
+    // only full 512-byte blocks are sent to write().
+    if (!isdir) {
+        off64_t toWrite = s.st_size;
+        while (toWrite > 0) {
+            size_t toRead = (toWrite < BUFSIZE) ? toWrite : BUFSIZE;
+            ssize_t nRead = read(fd, buf, toRead);
+            if (nRead < 0) {
+                err = errno;
+                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
+                        err, strerror(err));
+                break;
+            } else if (nRead == 0) {
+                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
+                        filepath.string());
+                err = EIO;
+                break;
+            }
+
+            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
+            // depends on the OS guarantee that for ordinary files, read() will never return
+            // less than the number of bytes requested.
+            ssize_t partial = (nRead+512) % 512;
+            if (partial > 0) {
+                ssize_t remainder = 512 - partial;
+                memset(buf + nRead, 0, remainder);
+                nRead += remainder;
+            }
+            send_tarfile_chunk(writer, buf, nRead);
+            toWrite -= nRead;
+        }
+    }
+
+cleanup:
+    free(buf);
+done:
+    close(fd);
+    return err;
+}
+// end tarfile
+
+
+
+#define RESTORE_BUF_SIZE (8*1024)
+
+RestoreHelperBase::RestoreHelperBase()
+{
+    m_buf = malloc(RESTORE_BUF_SIZE);
+    m_loggedUnknownMetadata = false;
+}
+
+RestoreHelperBase::~RestoreHelperBase()
+{
+    free(m_buf);
+}
+
+status_t
+RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
+{
+    ssize_t err;
+    size_t dataSize;
+    String8 key;
+    int fd;
+    void* buf = m_buf;
+    ssize_t amt;
+    int mode;
+    int crc;
+    struct stat st;
+    FileRec r;
+
+    err = in->ReadEntityHeader(&key, &dataSize);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // Get the metadata block off the head of the file entity and use that to
+    // set up the output file
+    file_metadata_v1 metadata;
+    amt = in->ReadEntityData(&metadata, sizeof(metadata));
+    if (amt != sizeof(metadata)) {
+        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
+                (long)amt, strerror(errno));
+        return EIO;
+    }
+    metadata.version = fromlel(metadata.version);
+    metadata.mode = fromlel(metadata.mode);
+    if (metadata.version > CURRENT_METADATA_VERSION) {
+        if (!m_loggedUnknownMetadata) {
+            m_loggedUnknownMetadata = true;
+            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
+                    metadata.version, CURRENT_METADATA_VERSION);
+        }
+    }
+    mode = metadata.mode;
+
+    // Write the file and compute the crc
+    crc = crc32(0L, Z_NULL, 0);
+    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
+    if (fd == -1) {
+        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
+        return errno;
+    }
+    
+    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
+        err = write(fd, buf, amt);
+        if (err != amt) {
+            close(fd);
+            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
+            return errno;
+        }
+        crc = crc32(crc, (Bytef*)buf, amt);
+    }
+
+    close(fd);
+
+    // Record for the snapshot
+    err = stat(filename.string(), &st);
+    if (err != 0) {
+        ALOGW("Error stating file that we just created %s", filename.string());
+        return errno;
+    }
+
+    r.file = filename;
+    r.deleted = false;
+    r.s.modTime_sec = st.st_mtime;
+    r.s.modTime_nsec = 0; // workaround sim breakage
+    //r.s.modTime_nsec = st.st_mtime_nsec;
+    r.s.mode = st.st_mode;
+    r.s.size = st.st_size;
+    r.s.crc32 = crc;
+
+    m_files.add(key, r);
+
+    return NO_ERROR;
+}
+
+status_t
+RestoreHelperBase::WriteSnapshot(int fd)
+{
+    return write_snapshot_file(fd, m_files);;
+}
+
+#if TEST_BACKUP_HELPERS
+
+#define SCRATCH_DIR "/data/backup_helper_test/"
+
+static int
+write_text_file(const char* path, const char* data)
+{
+    int amt;
+    int fd;
+    int len;
+
+    fd = creat(path, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "creat %s failed\n", path);
+        return errno;
+    }
+
+    len = strlen(data);
+    amt = write(fd, data, len);
+    if (amt != len) {
+        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
+        return errno;
+    }
+
+    close(fd);
+
+    return 0;
+}
+
+static int
+compare_file(const char* path, const unsigned char* data, int len)
+{
+    int fd;
+    int amt;
+
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
+        return errno;
+    }
+
+    unsigned char* contents = (unsigned char*)malloc(len);
+    if (contents == NULL) {
+        fprintf(stderr, "malloc(%d) failed\n", len);
+        return ENOMEM;
+    }
+
+    bool sizesMatch = true;
+    amt = lseek(fd, 0, SEEK_END);
+    if (amt != len) {
+        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
+        sizesMatch = false;
+    }
+    lseek(fd, 0, SEEK_SET);
+
+    int readLen = amt < len ? amt : len;
+    amt = read(fd, contents, readLen);
+    if (amt != readLen) {
+        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
+    }
+
+    bool contentsMatch = true;
+    for (int i=0; i<readLen; i++) {
+        if (data[i] != contents[i]) {
+            if (contentsMatch) {
+                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
+                contentsMatch = false;
+            }
+            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
+        }
+    }
+
+    free(contents);
+    return contentsMatch && sizesMatch ? 0 : 1;
+}
+
+int
+backup_helper_test_empty()
+{
+    int err;
+    int fd;
+    KeyedVector<String8,FileRec> snapshot;
+    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+
+    // write
+    fd = creat(filename, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "error creating %s\n", filename);
+        return 1;
+    }
+
+    err = write_snapshot_file(fd, snapshot);
+
+    close(fd);
+
+    if (err != 0) {
+        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
+        return err;
+    }
+
+    static const unsigned char correct_data[] = {
+        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
+        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
+    };
+
+    err = compare_file(filename, correct_data, sizeof(correct_data));
+    if (err != 0) {
+        return err;
+    }
+
+    // read
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "error opening for read %s\n", filename);
+        return 1;
+    }
+
+    KeyedVector<String8,FileState> readSnapshot;
+    err = read_snapshot_file(fd, &readSnapshot);
+    if (err != 0) {
+        fprintf(stderr, "read_snapshot_file failed %d\n", err);
+        return err;
+    }
+
+    if (readSnapshot.size() != 0) {
+        fprintf(stderr, "readSnapshot should be length 0\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int
+backup_helper_test_four()
+{
+    int err;
+    int fd;
+    KeyedVector<String8,FileRec> snapshot;
+    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+
+    // write
+    fd = creat(filename, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "error opening %s\n", filename);
+        return 1;
+    }
+
+    String8 filenames[4];
+    FileState states[4];
+    FileRec r;
+    r.deleted = false;
+
+    states[0].modTime_sec = 0xfedcba98;
+    states[0].modTime_nsec = 0xdeadbeef;
+    states[0].mode = 0777; // decimal 511, hex 0x000001ff
+    states[0].size = 0xababbcbc;
+    states[0].crc32 = 0x12345678;
+    states[0].nameLen = -12;
+    r.s = states[0];
+    filenames[0] = String8("bytes_of_padding");
+    snapshot.add(filenames[0], r);
+
+    states[1].modTime_sec = 0x93400031;
+    states[1].modTime_nsec = 0xdeadbeef;
+    states[1].mode = 0666; // decimal 438, hex 0x000001b6
+    states[1].size = 0x88557766;
+    states[1].crc32 = 0x22334422;
+    states[1].nameLen = -1;
+    r.s = states[1];
+    filenames[1] = String8("bytes_of_padding3");
+    snapshot.add(filenames[1], r);
+
+    states[2].modTime_sec = 0x33221144;
+    states[2].modTime_nsec = 0xdeadbeef;
+    states[2].mode = 0744; // decimal 484, hex 0x000001e4
+    states[2].size = 0x11223344;
+    states[2].crc32 = 0x01122334;
+    states[2].nameLen = 0;
+    r.s = states[2];
+    filenames[2] = String8("bytes_of_padding_2");
+    snapshot.add(filenames[2], r);
+
+    states[3].modTime_sec = 0x33221144;
+    states[3].modTime_nsec = 0xdeadbeef;
+    states[3].mode = 0755; // decimal 493, hex 0x000001ed
+    states[3].size = 0x11223344;
+    states[3].crc32 = 0x01122334;
+    states[3].nameLen = 0;
+    r.s = states[3];
+    filenames[3] = String8("bytes_of_padding__1");
+    snapshot.add(filenames[3], r);
+
+    err = write_snapshot_file(fd, snapshot);
+
+    close(fd);
+
+    if (err != 0) {
+        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
+        return err;
+    }
+
+    static const unsigned char correct_data[] = {
+        // header
+        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
+        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
+
+        // bytes_of_padding
+        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
+        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
+        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
+        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
+        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
+
+        // bytes_of_padding3
+        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
+        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
+        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
+        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
+        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
+        0x33, 0xab, 0xab, 0xab,
+
+        // bytes of padding2
+        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
+        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
+        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
+        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
+        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
+        0x5f, 0x32, 0xab, 0xab,
+
+        // bytes of padding3
+        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
+        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
+        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
+        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
+        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
+        0x5f, 0x5f, 0x31, 0xab
+    };
+
+    err = compare_file(filename, correct_data, sizeof(correct_data));
+    if (err != 0) {
+        return err;
+    }
+
+    // read
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "error opening for read %s\n", filename);
+        return 1;
+    }
+
+
+    KeyedVector<String8,FileState> readSnapshot;
+    err = read_snapshot_file(fd, &readSnapshot);
+    if (err != 0) {
+        fprintf(stderr, "read_snapshot_file failed %d\n", err);
+        return err;
+    }
+
+    if (readSnapshot.size() != 4) {
+        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
+        return 1;
+    }
+
+    bool matched = true;
+    for (size_t i=0; i<readSnapshot.size(); i++) {
+        const String8& name = readSnapshot.keyAt(i);
+        const FileState state = readSnapshot.valueAt(i);
+
+        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
+                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
+                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
+            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n"
+                            "          actual={%d/%d, 0x%08x, %04o, 0x%08x, %3d} '%s'\n", i,
+                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
+                    states[i].crc32, name.length(), filenames[i].string(),
+                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
+                    state.nameLen, name.string());
+            matched = false;
+        }
+    }
+
+    return matched ? 0 : 1;
+}
+
+// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
+const unsigned char DATA_GOLDEN_FILE[] = {
+     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
+     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
+     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
+     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
+     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
+     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
+     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
+     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
+     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
+     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
+     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
+     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
+     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
+     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
+     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
+
+};
+const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
+
+static int
+test_write_header_and_entity(BackupDataWriter& writer, const char* str)
+{
+    int err;
+    String8 text(str);
+
+    err = writer.WriteEntityHeader(text, text.length()+1);
+    if (err != 0) {
+        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
+        return err;
+    }
+
+    err = writer.WriteEntityData(text.string(), text.length()+1);
+    if (err != 0) {
+        fprintf(stderr, "write failed for data '%s'\n", text.string());
+        return errno;
+    }
+
+    return err;
+}
+
+int
+backup_helper_test_data_writer()
+{
+    int err;
+    int fd;
+    const char* filename = SCRATCH_DIR "data_writer.data";
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    fd = creat(filename, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    BackupDataWriter writer(fd);
+
+    err = 0;
+    err |= test_write_header_and_entity(writer, "no_padding_");
+    err |= test_write_header_and_entity(writer, "padded_to__3");
+    err |= test_write_header_and_entity(writer, "padded_to_2__");
+    err |= test_write_header_and_entity(writer, "padded_to1");
+
+    close(fd);
+
+    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
+    if (err != 0) {
+        return err;
+    }
+
+    return err;
+}
+
+int
+test_read_header_and_entity(BackupDataReader& reader, const char* str)
+{
+    int err;
+    int bufSize = strlen(str)+1;
+    char* buf = (char*)malloc(bufSize);
+    String8 string;
+    int cookie = 0x11111111;
+    size_t actualSize;
+    bool done;
+    int type;
+    ssize_t nRead;
+
+    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
+
+    err = reader.ReadNextHeader(&done, &type);
+    if (done) {
+        fprintf(stderr, "should not be done yet\n");
+        goto finished;
+    }
+    if (err != 0) {
+        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
+        goto finished;
+    }
+    if (type != BACKUP_HEADER_ENTITY_V1) {
+        err = EINVAL;
+        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
+    }
+
+    err = reader.ReadEntityHeader(&string, &actualSize);
+    if (err != 0) {
+        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
+        goto finished;
+    }
+    if (string != str) {
+        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
+        err = EINVAL;
+        goto finished;
+    }
+    if ((int)actualSize != bufSize) {
+        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
+                actualSize);
+        err = EINVAL;
+        goto finished;
+    }
+
+    nRead = reader.ReadEntityData(buf, bufSize);
+    if (nRead < 0) {
+        err = reader.Status();
+        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
+        goto finished;
+    }
+
+    if (0 != memcmp(buf, str, bufSize)) {
+        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
+                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
+                buf[0], buf[1], buf[2], buf[3]);
+        err = EINVAL;
+        goto finished;
+    }
+
+    // The next read will confirm whether it got the right amount of data.
+
+finished:
+    if (err != NO_ERROR) {
+        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
+    }
+    free(buf);
+    return err;
+}
+
+int
+backup_helper_test_data_reader()
+{
+    int err;
+    int fd;
+    const char* filename = SCRATCH_DIR "data_reader.data";
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    fd = creat(filename, 0666);
+    if (fd == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
+    if (err != DATA_GOLDEN_FILE_SIZE) {
+        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
+        return errno;
+    }
+
+    close(fd);
+
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
+                filename);
+        return errno;
+    }
+
+    {
+        BackupDataReader reader(fd);
+
+        err = 0;
+
+        if (err == NO_ERROR) {
+            err = test_read_header_and_entity(reader, "no_padding_");
+        }
+
+        if (err == NO_ERROR) {
+            err = test_read_header_and_entity(reader, "padded_to__3");
+        }
+
+        if (err == NO_ERROR) {
+            err = test_read_header_and_entity(reader, "padded_to_2__");
+        }
+
+        if (err == NO_ERROR) {
+            err = test_read_header_and_entity(reader, "padded_to1");
+        }
+    }
+
+    close(fd);
+
+    return err;
+}
+
+static int
+get_mod_time(const char* filename, struct timeval times[2])
+{
+    int err;
+    struct stat64 st;
+    err = stat64(filename, &st);
+    if (err != 0) {
+        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
+        return errno;
+    }
+    times[0].tv_sec = st.st_atime;
+    times[1].tv_sec = st.st_mtime;
+
+    // If st_atime is a macro then struct stat64 uses struct timespec
+    // to store the access and modif time values and typically
+    // st_*time_nsec is not defined. In glibc, this is controlled by
+    // __USE_MISC.
+#ifdef __USE_MISC
+#if !defined(st_atime) || defined(st_atime_nsec)
+#error "Check if this __USE_MISC conditional is still needed."
+#endif
+    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
+    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
+#else
+    times[0].tv_usec = st.st_atime_nsec / 1000;
+    times[1].tv_usec = st.st_mtime_nsec / 1000;
+#endif
+
+    return 0;
+}
+
+int
+backup_helper_test_files()
+{
+    int err;
+    int oldSnapshotFD;
+    int dataStreamFD;
+    int newSnapshotFD;
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
+    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
+    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
+    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
+    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
+    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
+
+    char const* files_before[] = {
+        SCRATCH_DIR "data/b",
+        SCRATCH_DIR "data/c",
+        SCRATCH_DIR "data/d",
+        SCRATCH_DIR "data/e",
+        SCRATCH_DIR "data/f"
+    };
+
+    char const* keys_before[] = {
+        "data/b",
+        "data/c",
+        "data/d",
+        "data/e",
+        "data/f"
+    };
+
+    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
+    if (dataStreamFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
+    if (newSnapshotFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+
+        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    close(dataStreamFD);
+    close(newSnapshotFD);
+
+    sleep(3);
+
+    struct timeval d_times[2];
+    struct timeval e_times[2];
+
+    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
+    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
+    if (err != 0) {
+        return err;
+    }
+
+    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
+    unlink(SCRATCH_DIR "data/c");
+    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
+    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
+    utimes(SCRATCH_DIR "data/d", d_times);
+    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
+    utimes(SCRATCH_DIR "data/e", e_times);
+    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
+    unlink(SCRATCH_DIR "data/f");
+
+    char const* files_after[] = {
+        SCRATCH_DIR "data/a", // added
+        SCRATCH_DIR "data/b", // same
+        SCRATCH_DIR "data/c", // different mod time
+        SCRATCH_DIR "data/d", // different size (same mod time)
+        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
+        SCRATCH_DIR "data/g"  // added
+    };
+
+    char const* keys_after[] = {
+        "data/a", // added
+        "data/b", // same
+        "data/c", // different mod time
+        "data/d", // different size (same mod time)
+        "data/e", // different contents (same mod time, same size)
+        "data/g"  // added
+    };
+
+    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
+    if (oldSnapshotFD == -1) {
+        fprintf(stderr, "error opening: %s\n", strerror(errno));
+        return errno;
+    }
+
+    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
+    if (dataStreamFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
+    if (newSnapshotFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+
+        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
+        if (err != 0) {
+            return err;
+        }
+}
+
+    close(oldSnapshotFD);
+    close(dataStreamFD);
+    close(newSnapshotFD);
+
+    return 0;
+}
+
+int
+backup_helper_test_null_base()
+{
+    int err;
+    int oldSnapshotFD;
+    int dataStreamFD;
+    int newSnapshotFD;
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
+
+    char const* files[] = {
+        SCRATCH_DIR "data/a",
+    };
+
+    char const* keys[] = {
+        "a",
+    };
+
+    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
+    if (dataStreamFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
+    if (newSnapshotFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+
+        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    close(dataStreamFD);
+    close(newSnapshotFD);
+
+    return 0;
+}
+
+int
+backup_helper_test_missing_file()
+{
+    int err;
+    int oldSnapshotFD;
+    int dataStreamFD;
+    int newSnapshotFD;
+
+    system("rm -r " SCRATCH_DIR);
+    mkdir(SCRATCH_DIR, 0777);
+    mkdir(SCRATCH_DIR "data", 0777);
+
+    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
+
+    char const* files[] = {
+        SCRATCH_DIR "data/a",
+        SCRATCH_DIR "data/b",
+        SCRATCH_DIR "data/c",
+    };
+
+    char const* keys[] = {
+        "a",
+        "b",
+        "c",
+    };
+
+    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
+    if (dataStreamFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
+    if (newSnapshotFD == -1) {
+        fprintf(stderr, "error creating: %s\n", strerror(errno));
+        return errno;
+    }
+
+    {
+        BackupDataWriter dataStream(dataStreamFD);
+
+        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    close(dataStreamFD);
+    close(newSnapshotFD);
+
+    return 0;
+}
+
+
+#endif // TEST_BACKUP_HELPERS
+
+}
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
new file mode 100644
index 0000000..0f54edb
--- /dev/null
+++ b/libs/androidfw/CursorWindow.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2006-2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "CursorWindow"
+
+#include <androidfw/CursorWindow.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+namespace android {
+
+CursorWindow::CursorWindow(const String8& name, int ashmemFd,
+        void* data, size_t size, bool readOnly) :
+        mName(name), mAshmemFd(ashmemFd), mData(data), mSize(size), mReadOnly(readOnly) {
+    mHeader = static_cast<Header*>(mData);
+}
+
+CursorWindow::~CursorWindow() {
+    ::munmap(mData, mSize);
+    ::close(mAshmemFd);
+}
+
+status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
+    String8 ashmemName("CursorWindow: ");
+    ashmemName.append(name);
+
+    status_t result;
+    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
+    if (ashmemFd < 0) {
+        result = -errno;
+    } else {
+        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
+        if (result >= 0) {
+            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
+            if (data == MAP_FAILED) {
+                result = -errno;
+            } else {
+                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
+                if (result >= 0) {
+                    CursorWindow* window = new CursorWindow(name, ashmemFd,
+                            data, size, false /*readOnly*/);
+                    result = window->clear();
+                    if (!result) {
+                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
+                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
+                                window->mHeader->freeOffset,
+                                window->mHeader->numRows,
+                                window->mHeader->numColumns,
+                                window->mSize, window->mData);
+                        *outCursorWindow = window;
+                        return OK;
+                    }
+                    delete window;
+                }
+            }
+            ::munmap(data, size);
+        }
+        ::close(ashmemFd);
+    }
+    *outCursorWindow = NULL;
+    return result;
+}
+
+status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {
+    String8 name = parcel->readString8();
+
+    status_t result;
+    int ashmemFd = parcel->readFileDescriptor();
+    if (ashmemFd == int(BAD_TYPE)) {
+        result = BAD_TYPE;
+    } else {
+        ssize_t size = ashmem_get_size_region(ashmemFd);
+        if (size < 0) {
+            result = UNKNOWN_ERROR;
+        } else {
+            int dupAshmemFd = ::dup(ashmemFd);
+            if (dupAshmemFd < 0) {
+                result = -errno;
+            } else {
+                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);
+                if (data == MAP_FAILED) {
+                    result = -errno;
+                } else {
+                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,
+                            data, size, true /*readOnly*/);
+                    LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, "
+                            "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
+                            window->mHeader->freeOffset,
+                            window->mHeader->numRows,
+                            window->mHeader->numColumns,
+                            window->mSize, window->mData);
+                    *outCursorWindow = window;
+                    return OK;
+                }
+                ::close(dupAshmemFd);
+            }
+        }
+    }
+    *outCursorWindow = NULL;
+    return result;
+}
+
+status_t CursorWindow::writeToParcel(Parcel* parcel) {
+    status_t status = parcel->writeString8(mName);
+    if (!status) {
+        status = parcel->writeDupFileDescriptor(mAshmemFd);
+    }
+    return status;
+}
+
+status_t CursorWindow::clear() {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    mHeader->freeOffset = sizeof(Header) + sizeof(RowSlotChunk);
+    mHeader->firstChunkOffset = sizeof(Header);
+    mHeader->numRows = 0;
+    mHeader->numColumns = 0;
+
+    RowSlotChunk* firstChunk = static_cast<RowSlotChunk*>(offsetToPtr(mHeader->firstChunkOffset));
+    firstChunk->nextChunkOffset = 0;
+    return OK;
+}
+
+status_t CursorWindow::setNumColumns(uint32_t numColumns) {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    uint32_t cur = mHeader->numColumns;
+    if ((cur > 0 || mHeader->numRows > 0) && cur != numColumns) {
+        ALOGE("Trying to go from %d columns to %d", cur, numColumns);
+        return INVALID_OPERATION;
+    }
+    mHeader->numColumns = numColumns;
+    return OK;
+}
+
+status_t CursorWindow::allocRow() {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    // Fill in the row slot
+    RowSlot* rowSlot = allocRowSlot();
+    if (rowSlot == NULL) {
+        return NO_MEMORY;
+    }
+
+    // Allocate the slots for the field directory
+    size_t fieldDirSize = mHeader->numColumns * sizeof(FieldSlot);
+    uint32_t fieldDirOffset = alloc(fieldDirSize, true /*aligned*/);
+    if (!fieldDirOffset) {
+        mHeader->numRows--;
+        LOG_WINDOW("The row failed, so back out the new row accounting "
+                "from allocRowSlot %d", mHeader->numRows);
+        return NO_MEMORY;
+    }
+    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(fieldDirOffset));
+    memset(fieldDir, 0, fieldDirSize);
+
+    LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n",
+            mHeader->numRows - 1, offsetFromPtr(rowSlot), fieldDirSize, fieldDirOffset);
+    rowSlot->offset = fieldDirOffset;
+    return OK;
+}
+
+status_t CursorWindow::freeLastRow() {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    if (mHeader->numRows > 0) {
+        mHeader->numRows--;
+    }
+    return OK;
+}
+
+uint32_t CursorWindow::alloc(size_t size, bool aligned) {
+    uint32_t padding;
+    if (aligned) {
+        // 4 byte alignment
+        padding = (~mHeader->freeOffset + 1) & 3;
+    } else {
+        padding = 0;
+    }
+
+    uint32_t offset = mHeader->freeOffset + padding;
+    uint32_t nextFreeOffset = offset + size;
+    if (nextFreeOffset > mSize) {
+        ALOGW("Window is full: requested allocation %d bytes, "
+                "free space %d bytes, window size %d bytes",
+                size, freeSpace(), mSize);
+        return 0;
+    }
+
+    mHeader->freeOffset = nextFreeOffset;
+    return offset;
+}
+
+CursorWindow::RowSlot* CursorWindow::getRowSlot(uint32_t row) {
+    uint32_t chunkPos = row;
+    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
+            offsetToPtr(mHeader->firstChunkOffset));
+    while (chunkPos >= ROW_SLOT_CHUNK_NUM_ROWS) {
+        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
+    }
+    return &chunk->slots[chunkPos];
+}
+
+CursorWindow::RowSlot* CursorWindow::allocRowSlot() {
+    uint32_t chunkPos = mHeader->numRows;
+    RowSlotChunk* chunk = static_cast<RowSlotChunk*>(
+            offsetToPtr(mHeader->firstChunkOffset));
+    while (chunkPos > ROW_SLOT_CHUNK_NUM_ROWS) {
+        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+        chunkPos -= ROW_SLOT_CHUNK_NUM_ROWS;
+    }
+    if (chunkPos == ROW_SLOT_CHUNK_NUM_ROWS) {
+        if (!chunk->nextChunkOffset) {
+            chunk->nextChunkOffset = alloc(sizeof(RowSlotChunk), true /*aligned*/);
+            if (!chunk->nextChunkOffset) {
+                return NULL;
+            }
+        }
+        chunk = static_cast<RowSlotChunk*>(offsetToPtr(chunk->nextChunkOffset));
+        chunk->nextChunkOffset = 0;
+        chunkPos = 0;
+    }
+    mHeader->numRows += 1;
+    return &chunk->slots[chunkPos];
+}
+
+CursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {
+    if (row >= mHeader->numRows || column >= mHeader->numColumns) {
+        ALOGE("Failed to read row %d, column %d from a CursorWindow which "
+                "has %d rows, %d columns.",
+                row, column, mHeader->numRows, mHeader->numColumns);
+        return NULL;
+    }
+    RowSlot* rowSlot = getRowSlot(row);
+    if (!rowSlot) {
+        ALOGE("Failed to find rowSlot for row %d.", row);
+        return NULL;
+    }
+    FieldSlot* fieldDir = static_cast<FieldSlot*>(offsetToPtr(rowSlot->offset));
+    return &fieldDir[column];
+}
+
+status_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {
+    return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);
+}
+
+status_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,
+        size_t sizeIncludingNull) {
+    return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);
+}
+
+status_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,
+        const void* value, size_t size, int32_t type) {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    FieldSlot* fieldSlot = getFieldSlot(row, column);
+    if (!fieldSlot) {
+        return BAD_VALUE;
+    }
+
+    uint32_t offset = alloc(size);
+    if (!offset) {
+        return NO_MEMORY;
+    }
+
+    memcpy(offsetToPtr(offset), value, size);
+
+    fieldSlot->type = type;
+    fieldSlot->data.buffer.offset = offset;
+    fieldSlot->data.buffer.size = size;
+    return OK;
+}
+
+status_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    FieldSlot* fieldSlot = getFieldSlot(row, column);
+    if (!fieldSlot) {
+        return BAD_VALUE;
+    }
+
+    fieldSlot->type = FIELD_TYPE_INTEGER;
+    fieldSlot->data.l = value;
+    return OK;
+}
+
+status_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    FieldSlot* fieldSlot = getFieldSlot(row, column);
+    if (!fieldSlot) {
+        return BAD_VALUE;
+    }
+
+    fieldSlot->type = FIELD_TYPE_FLOAT;
+    fieldSlot->data.d = value;
+    return OK;
+}
+
+status_t CursorWindow::putNull(uint32_t row, uint32_t column) {
+    if (mReadOnly) {
+        return INVALID_OPERATION;
+    }
+
+    FieldSlot* fieldSlot = getFieldSlot(row, column);
+    if (!fieldSlot) {
+        return BAD_VALUE;
+    }
+
+    fieldSlot->type = FIELD_TYPE_NULL;
+    fieldSlot->data.buffer.offset = 0;
+    fieldSlot->data.buffer.size = 0;
+    return OK;
+}
+
+}; // namespace android
diff --git a/libs/androidfw/MODULE_LICENSE_APACHE2 b/libs/androidfw/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/androidfw/MODULE_LICENSE_APACHE2
diff --git a/libs/androidfw/NOTICE b/libs/androidfw/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/androidfw/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
new file mode 100644
index 0000000..21e06c8
--- /dev/null
+++ b/libs/androidfw/ObbFile.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LOG_TAG "ObbFile"
+
+#include <androidfw/ObbFile.h>
+#include <utils/Compat.h>
+#include <utils/Log.h>
+
+//#define DEBUG 1
+
+#define kFooterTagSize 8  /* last two 32-bit integers */
+
+#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
+                           * 32-bit package version (4 bytes)
+                           * 32-bit flags (4 bytes)
+                           * 64-bit salt (8 bytes)
+                           * 32-bit package name size (4 bytes)
+                           * >=1-character package name (1 byte)
+                           * 32-bit footer size (4 bytes)
+                           * 32-bit footer marker (4 bytes)
+                           */
+
+#define kMaxBufSize    32768 /* Maximum file read buffer */
+
+#define kSignature     0x01059983U /* ObbFile signature */
+
+#define kSigVersion    1 /* We only know about signature version 1 */
+
+/* offsets in version 1 of the header */
+#define kPackageVersionOffset 4
+#define kFlagsOffset          8
+#define kSaltOffset           12
+#define kPackageNameLenOffset 20
+#define kPackageNameOffset    24
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+
+namespace android {
+
+ObbFile::ObbFile()
+        : mPackageName("")
+        , mVersion(-1)
+        , mFlags(0)
+{
+    memset(mSalt, 0, sizeof(mSalt));
+}
+
+ObbFile::~ObbFile() {
+}
+
+bool ObbFile::readFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDONLY);
+    if (fd < 0) {
+        ALOGW("couldn't open file %s: %s", filename, strerror(errno));
+        goto out;
+    }
+    success = readFrom(fd);
+    close(fd);
+
+    if (!success) {
+        ALOGW("failed to read from %s (fd=%d)\n", filename, fd);
+    }
+
+out:
+    return success;
+}
+
+bool ObbFile::readFrom(int fd)
+{
+    if (fd < 0) {
+        ALOGW("attempt to read from invalid fd\n");
+        return false;
+    }
+
+    return parseObbFile(fd);
+}
+
+bool ObbFile::parseObbFile(int fd)
+{
+    off64_t fileLength = lseek64(fd, 0, SEEK_END);
+
+    if (fileLength < kFooterMinSize) {
+        if (fileLength < 0) {
+            ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
+        } else {
+            ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
+        }
+        return false;
+    }
+
+    ssize_t actual;
+    size_t footerSize;
+
+    {
+        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
+
+        char *footer = new char[kFooterTagSize];
+        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
+        if (actual != kFooterTagSize) {
+            ALOGW("couldn't read footer signature: %s\n", strerror(errno));
+            return false;
+        }
+
+        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
+        if (fileSig != kSignature) {
+            ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
+                    kSignature, fileSig);
+            return false;
+        }
+
+        footerSize = get4LE((unsigned char*)footer);
+        if (footerSize > (size_t)fileLength - kFooterTagSize
+                || footerSize > kMaxBufSize) {
+            ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
+                    footerSize, fileLength);
+            return false;
+        }
+
+        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
+            ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
+                    footerSize, kFooterMinSize - kFooterTagSize);
+            return false;
+        }
+    }
+
+    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
+    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
+        ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
+        return false;
+    }
+
+    mFooterStart = fileOffset;
+
+    char* scanBuf = (char*)malloc(footerSize);
+    if (scanBuf == NULL) {
+        ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
+        return false;
+    }
+
+    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
+    // readAmount is guaranteed to be less than kMaxBufSize
+    if (actual != (ssize_t)footerSize) {
+        ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+#ifdef DEBUG
+    for (int i = 0; i < footerSize; ++i) {
+        ALOGI("char: 0x%02x\n", scanBuf[i]);
+    }
+#endif
+
+    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
+    if (sigVersion != kSigVersion) {
+        ALOGW("Unsupported ObbFile version %d\n", sigVersion);
+        free(scanBuf);
+        return false;
+    }
+
+    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
+    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
+
+    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
+
+    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
+    if (packageNameLen == 0
+            || packageNameLen > (footerSize - kPackageNameOffset)) {
+        ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
+                packageNameLen, footerSize - kPackageNameOffset);
+        free(scanBuf);
+        return false;
+    }
+
+    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
+    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
+
+    free(scanBuf);
+
+#ifdef DEBUG
+    ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
+#endif
+
+    return true;
+}
+
+bool ObbFile::writeTo(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_WRONLY);
+    if (fd < 0) {
+        goto out;
+    }
+    success = writeTo(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        ALOGW("failed to write to %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::writeTo(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    lseek64(fd, 0, SEEK_END);
+
+    if (mPackageName.size() == 0 || mVersion == -1) {
+        ALOGW("tried to write uninitialized ObbFile data\n");
+        return false;
+    }
+
+    unsigned char intBuf[sizeof(uint32_t)+1];
+    memset(&intBuf, 0, sizeof(intBuf));
+
+    put4LE(intBuf, kSigVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write signature version: %s\n", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, mVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write package version\n");
+        return false;
+    }
+
+    put4LE(intBuf, mFlags);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write package version\n");
+        return false;
+    }
+
+    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
+        ALOGW("couldn't write salt: %s\n", strerror(errno));
+        return false;
+    }
+
+    size_t packageNameLen = mPackageName.size();
+    put4LE(intBuf, packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write package name length: %s\n", strerror(errno));
+        return false;
+    }
+
+    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
+        ALOGW("couldn't write package name: %s\n", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kPackageNameOffset + packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write footer size: %s\n", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kSignature);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        ALOGW("couldn't write footer magic signature: %s\n", strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+
+bool ObbFile::removeFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDWR);
+    if (fd < 0) {
+        goto out;
+    }
+    success = removeFrom(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::removeFrom(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    if (!readFrom(fd)) {
+        return false;
+    }
+
+    ftruncate(fd, mFooterStart);
+
+    return true;
+}
+
+}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
new file mode 100644
index 0000000..1cc3563
--- /dev/null
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -0,0 +1,5796 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ResourceType"
+//#define LOG_NDEBUG 0
+
+#include <androidfw/ResourceTypes.h>
+#include <utils/Atomic.h>
+#include <utils/ByteOrder.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define STRING_POOL_NOISY(x) //x
+#define XML_NOISY(x) //x
+#define TABLE_NOISY(x) //x
+#define TABLE_GETENTRY(x) //x
+#define TABLE_SUPER_NOISY(x) //x
+#define LOAD_TABLE_NOISY(x) //x
+#define TABLE_THEME(x) //x
+
+namespace android {
+
+#ifdef HAVE_WINSOCK
+#undef  nhtol
+#undef  htonl
+
+#ifdef HAVE_LITTLE_ENDIAN
+#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#define htonl(x)    ntohl(x)
+#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#define htons(x)    ntohs(x)
+#else
+#define ntohl(x)    (x)
+#define htonl(x)    (x)
+#define ntohs(x)    (x)
+#define htons(x)    (x)
+#endif
+#endif
+
+#define IDMAP_MAGIC         0x706d6469
+// size measured in sizeof(uint32_t)
+#define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t))
+
+static void printToLogFunc(void* cookie, const char* txt)
+{
+    ALOGV("%s", txt);
+}
+
+// Standard C isspace() is only required to look at the low byte of its input, so
+// produces incorrect results for UTF-16 characters.  For safety's sake, assume that
+// any high-byte UTF-16 code point is not whitespace.
+inline int isspace16(char16_t c) {
+    return (c < 0x0080 && isspace(c));
+}
+
+// range checked; guaranteed to NUL-terminate within the stated number of available slots
+// NOTE: if this truncates the dst string due to running out of space, no attempt is
+// made to avoid splitting surrogate pairs.
+static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
+{
+    uint16_t* last = dst + avail - 1;
+    while (*src && (dst < last)) {
+        char16_t s = dtohs(*src);
+        *dst++ = s;
+        src++;
+    }
+    *dst = 0;
+}
+
+static status_t validate_chunk(const ResChunk_header* chunk,
+                               size_t minSize,
+                               const uint8_t* dataEnd,
+                               const char* name)
+{
+    const uint16_t headerSize = dtohs(chunk->headerSize);
+    const uint32_t size = dtohl(chunk->size);
+
+    if (headerSize >= minSize) {
+        if (headerSize <= size) {
+            if (((headerSize|size)&0x3) == 0) {
+                if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
+                    return NO_ERROR;
+                }
+                ALOGW("%s data size %p extends beyond resource end %p.",
+                     name, (void*)size,
+                     (void*)(dataEnd-((const uint8_t*)chunk)));
+                return BAD_TYPE;
+            }
+            ALOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
+                 name, (int)size, (int)headerSize);
+            return BAD_TYPE;
+        }
+        ALOGW("%s size %p is smaller than header size %p.",
+             name, (void*)size, (void*)(int)headerSize);
+        return BAD_TYPE;
+    }
+    ALOGW("%s header size %p is too small.",
+         name, (void*)(int)headerSize);
+    return BAD_TYPE;
+}
+
+inline void Res_value::copyFrom_dtoh(const Res_value& src)
+{
+    size = dtohs(src.size);
+    res0 = src.res0;
+    dataType = src.dataType;
+    data = dtohl(src.data);
+}
+
+void Res_png_9patch::deviceToFile()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = htonl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = htonl(yDivs[i]);
+    }
+    paddingLeft = htonl(paddingLeft);
+    paddingRight = htonl(paddingRight);
+    paddingTop = htonl(paddingTop);
+    paddingBottom = htonl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = htonl(colors[i]);
+    }
+}
+
+void Res_png_9patch::fileToDevice()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = ntohl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = ntohl(yDivs[i]);
+    }
+    paddingLeft = ntohl(paddingLeft);
+    paddingRight = ntohl(paddingRight);
+    paddingTop = ntohl(paddingTop);
+    paddingBottom = ntohl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = ntohl(colors[i]);
+    }
+}
+
+size_t Res_png_9patch::serializedSize()
+{
+    // The size of this struct is 32 bytes on the 32-bit target system
+    // 4 * int8_t
+    // 4 * int32_t
+    // 3 * pointer
+    return 32
+            + numXDivs * sizeof(int32_t)
+            + numYDivs * sizeof(int32_t)
+            + numColors * sizeof(uint32_t);
+}
+
+void* Res_png_9patch::serialize()
+{
+    // Use calloc since we're going to leave a few holes in the data
+    // and want this to run cleanly under valgrind
+    void* newData = calloc(1, serializedSize());
+    serialize(newData);
+    return newData;
+}
+
+void Res_png_9patch::serialize(void * outData)
+{
+    char* data = (char*) outData;
+    memmove(data, &wasDeserialized, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+    memmove(data + 12, &paddingLeft, 16);   // copy paddingXXXX
+    data += 32;
+
+    memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
+    data +=  numXDivs * sizeof(int32_t);
+    memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
+    data +=  numYDivs * sizeof(int32_t);
+    memmove(data, this->colors, numColors * sizeof(uint32_t));
+}
+
+static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
+    char* patch = (char*) inData;
+    if (inData != outData) {
+        memmove(&outData->wasDeserialized, patch, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+        memmove(&outData->paddingLeft, patch + 12, 4);     // copy  wasDeserialized, numXDivs, numYDivs, numColors
+    }
+    outData->wasDeserialized = true;
+    char* data = (char*)outData;
+    data +=  sizeof(Res_png_9patch);
+    outData->xDivs = (int32_t*) data;
+    data +=  outData->numXDivs * sizeof(int32_t);
+    outData->yDivs = (int32_t*) data;
+    data +=  outData->numYDivs * sizeof(int32_t);
+    outData->colors = (uint32_t*) data;
+}
+
+static bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes)
+{
+    if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) {
+        ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes);
+        return false;
+    }
+    if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess
+        ALOGW("idmap assertion failed: invalid magic found (is 0x%08x, expected 0x%08x)\n",
+             *map, htodl(IDMAP_MAGIC));
+        return false;
+    }
+    return true;
+}
+
+static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key, uint32_t* outValue)
+{
+    // see README for details on the format of map
+    if (!assertIdmapHeader(map, sizeBytes)) {
+        return UNKNOWN_ERROR;
+    }
+    map = map + IDMAP_HEADER_SIZE; // skip ahead to data segment
+    // size of data block, in uint32_t
+    const size_t size = (sizeBytes - ResTable::IDMAP_HEADER_SIZE_BYTES) / sizeof(uint32_t);
+    const uint32_t type = Res_GETTYPE(key) + 1; // add one, idmap stores "public" type id
+    const uint32_t entry = Res_GETENTRY(key);
+    const uint32_t typeCount = *map;
+
+    if (type > typeCount) {
+        ALOGW("Resource ID map: type=%d exceeds number of types=%d\n", type, typeCount);
+        return UNKNOWN_ERROR;
+    }
+    if (typeCount > size) {
+        ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size);
+        return UNKNOWN_ERROR;
+    }
+    const uint32_t typeOffset = map[type];
+    if (typeOffset == 0) {
+        *outValue = 0;
+        return NO_ERROR;
+    }
+    if (typeOffset + 1 > size) {
+        ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n",
+             typeOffset, (int)size);
+        return UNKNOWN_ERROR;
+    }
+    const uint32_t entryCount = map[typeOffset];
+    const uint32_t entryOffset = map[typeOffset + 1];
+    if (entryCount == 0 || entry < entryOffset || entry - entryOffset > entryCount - 1) {
+        *outValue = 0;
+        return NO_ERROR;
+    }
+    const uint32_t index = typeOffset + 2 + entry - entryOffset;
+    if (index > size) {
+        ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size);
+        *outValue = 0;
+        return NO_ERROR;
+    }
+    *outValue = map[index];
+
+    return NO_ERROR;
+}
+
+static status_t getIdmapPackageId(const uint32_t* map, size_t mapSize, uint32_t *outId)
+{
+    if (!assertIdmapHeader(map, mapSize)) {
+        return UNKNOWN_ERROR;
+    }
+    const uint32_t* p = map + IDMAP_HEADER_SIZE + 1;
+    while (*p == 0) {
+        ++p;
+    }
+    *outId = (map[*p + IDMAP_HEADER_SIZE + 2] >> 24) & 0x000000ff;
+    return NO_ERROR;
+}
+
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+    if (sizeof(void*) != sizeof(int32_t)) {
+        ALOGE("Cannot deserialize on non 32-bit system\n");
+        return NULL;
+    }
+    deserializeInternal(inData, (Res_png_9patch*) inData);
+    return (Res_png_9patch*) inData;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResStringPool::ResStringPool()
+    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
+{
+}
+
+ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
+    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
+{
+    setTo(data, size, copyData);
+}
+
+ResStringPool::~ResStringPool()
+{
+    uninit();
+}
+
+status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
+{
+    if (!data || !size) {
+        return (mError=BAD_TYPE);
+    }
+
+    uninit();
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    if (copyData || notDeviceEndian) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResStringPool_header*)data;
+
+    if (notDeviceEndian) {
+        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
+        h->header.headerSize = dtohs(mHeader->header.headerSize);
+        h->header.type = dtohs(mHeader->header.type);
+        h->header.size = dtohl(mHeader->header.size);
+        h->stringCount = dtohl(mHeader->stringCount);
+        h->styleCount = dtohl(mHeader->styleCount);
+        h->flags = dtohl(mHeader->flags);
+        h->stringsStart = dtohl(mHeader->stringsStart);
+        h->stylesStart = dtohl(mHeader->stylesStart);
+    }
+
+    if (mHeader->header.headerSize > mHeader->header.size
+            || mHeader->header.size > size) {
+        ALOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
+                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    mSize = mHeader->header.size;
+    mEntries = (const uint32_t*)
+        (((const uint8_t*)data)+mHeader->header.headerSize);
+
+    if (mHeader->stringCount > 0) {
+        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?
+            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
+                > size) {
+            ALOGW("Bad string block: entry of %d items extends past data size %d\n",
+                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+
+        size_t charSize;
+        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
+            charSize = sizeof(uint8_t);
+        } else {
+            charSize = sizeof(char16_t);
+        }
+
+        mStrings = (const void*)
+            (((const uint8_t*)data)+mHeader->stringsStart);
+        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
+            ALOGW("Bad string block: string pool starts at %d, after total size %d\n",
+                    (int)mHeader->stringsStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        if (mHeader->styleCount == 0) {
+            mStringPoolSize =
+                (mHeader->header.size-mHeader->stringsStart)/charSize;
+        } else {
+            // check invariant: styles starts before end of data
+            if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) {
+                ALOGW("Bad style block: style block starts at %d past data size of %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->header.size);
+                return (mError=BAD_TYPE);
+            }
+            // check invariant: styles follow the strings
+            if (mHeader->stylesStart <= mHeader->stringsStart) {
+                ALOGW("Bad style block: style block starts at %d, before strings at %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);
+                return (mError=BAD_TYPE);
+            }
+            mStringPoolSize =
+                (mHeader->stylesStart-mHeader->stringsStart)/charSize;
+        }
+
+        // check invariant: stringCount > 0 requires a string pool to exist
+        if (mStringPoolSize == 0) {
+            ALOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
+            return (mError=BAD_TYPE);
+        }
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntries);
+            for (i=0; i<mHeader->stringCount; i++) {
+                e[i] = dtohl(mEntries[i]);
+            }
+            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
+                const char16_t* strings = (const char16_t*)mStrings;
+                char16_t* s = const_cast<char16_t*>(strings);
+                for (i=0; i<mStringPoolSize; i++) {
+                    s[i] = dtohs(strings[i]);
+                }
+            }
+        }
+
+        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
+                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+                ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
+            ALOGW("Bad string block: last string is not 0-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mStrings = NULL;
+        mStringPoolSize = 0;
+    }
+
+    if (mHeader->styleCount > 0) {
+        mEntryStyles = mEntries + mHeader->stringCount;
+        // invariant: integer overflow in calculating mEntryStyles
+        if (mEntryStyles < mEntries) {
+            ALOGW("Bad string block: integer overflow finding styles\n");
+            return (mError=BAD_TYPE);
+        }
+
+        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
+            ALOGW("Bad string block: entry of %d styles extends past data size %d\n",
+                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+        mStyles = (const uint32_t*)
+            (((const uint8_t*)data)+mHeader->stylesStart);
+        if (mHeader->stylesStart >= mHeader->header.size) {
+            ALOGW("Bad string block: style pool starts %d, after total size %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        mStylePoolSize =
+            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
+            for (i=0; i<mHeader->styleCount; i++) {
+                e[i] = dtohl(mEntryStyles[i]);
+            }
+            uint32_t* s = const_cast<uint32_t*>(mStyles);
+            for (i=0; i<mStylePoolSize; i++) {
+                s[i] = dtohl(mStyles[i]);
+            }
+        }
+
+        const ResStringPool_span endSpan = {
+            { htodl(ResStringPool_span::END) },
+            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
+        };
+        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
+                   &endSpan, sizeof(endSpan)) != 0) {
+            ALOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mEntryStyles = NULL;
+        mStyles = NULL;
+        mStylePoolSize = 0;
+    }
+
+    return (mError=NO_ERROR);
+}
+
+status_t ResStringPool::getError() const
+{
+    return mError;
+}
+
+void ResStringPool::uninit()
+{
+    mError = NO_INIT;
+    if (mHeader != NULL && mCache != NULL) {
+        for (size_t x = 0; x < mHeader->stringCount; x++) {
+            if (mCache[x] != NULL) {
+                free(mCache[x]);
+                mCache[x] = NULL;
+            }
+        }
+        free(mCache);
+        mCache = NULL;
+    }
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+}
+
+/**
+ * Strings in UTF-16 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that
+ * much data in a string, you're abusing them.
+ *
+ * If the high bit is set, then there are two characters or 4 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const char16_t** str)
+{
+    size_t len = **str;
+    if ((len & 0x8000) != 0) {
+        (*str)++;
+        len = ((len & 0x7FFF) << 16) | **str;
+    }
+    (*str)++;
+    return len;
+}
+
+/**
+ * Strings in UTF-8 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFF (32767 bytes), but you should consider storing
+ * text in another way if you're using that much data in a single string.
+ *
+ * If the high bit is set, then there are two characters or 2 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const uint8_t** str)
+{
+    size_t len = **str;
+    if ((len & 0x80) != 0) {
+        (*str)++;
+        len = ((len & 0x7F) << 8) | **str;
+    }
+    (*str)++;
+    return len;
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
+        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
+        if (off < (mStringPoolSize-1)) {
+            if (!isUTF8) {
+                const char16_t* strings = (char16_t*)mStrings;
+                const char16_t* str = strings+off;
+
+                *u16len = decodeLength(&str);
+                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
+                    return str;
+                } else {
+                    ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
+                }
+            } else {
+                const uint8_t* strings = (uint8_t*)mStrings;
+                const uint8_t* u8str = strings+off;
+
+                *u16len = decodeLength(&u8str);
+                size_t u8len = decodeLength(&u8str);
+
+                // encLen must be less than 0x7FFF due to encoding.
+                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
+                    AutoMutex lock(mDecodeLock);
+
+                    if (mCache == NULL) {
+#ifndef HAVE_ANDROID_OS
+                        STRING_POOL_NOISY(ALOGI("CREATING STRING CACHE OF %d bytes",
+                                mHeader->stringCount*sizeof(char16_t**)));
+#else
+                        // We do not want to be in this case when actually running Android.
+                        ALOGW("CREATING STRING CACHE OF %d bytes",
+                                mHeader->stringCount*sizeof(char16_t**));
+#endif
+                        mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
+                        if (mCache == NULL) {
+                            ALOGW("No memory trying to allocate decode cache table of %d bytes\n",
+                                    (int)(mHeader->stringCount*sizeof(char16_t**)));
+                            return NULL;
+                        }
+                    }
+
+                    if (mCache[idx] != NULL) {
+                        return mCache[idx];
+                    }
+
+                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);
+                    if (actualLen < 0 || (size_t)actualLen != *u16len) {
+                        ALOGW("Bad string block: string #%lld decoded length is not correct "
+                                "%lld vs %llu\n",
+                                (long long)idx, (long long)actualLen, (long long)*u16len);
+                        return NULL;
+                    }
+
+                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));
+                    if (!u16str) {
+                        ALOGW("No memory when trying to allocate decode cache for string #%d\n",
+                                (int)idx);
+                        return NULL;
+                    }
+
+                    STRING_POOL_NOISY(ALOGI("Caching UTF8 string: %s", u8str));
+                    utf8_to_utf16(u8str, u8len, u16str);
+                    mCache[idx] = u16str;
+                    return u16str;
+                } else {
+                    ALOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n",
+                            (long long)idx, (long long)(u8str+u8len-strings),
+                            (long long)mStringPoolSize);
+                }
+            }
+        } else {
+            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint16_t)),
+                    (int)(mStringPoolSize*sizeof(uint16_t)));
+        }
+    }
+    return NULL;
+}
+
+const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) {
+            return NULL;
+        }
+        const uint32_t off = mEntries[idx]/sizeof(char);
+        if (off < (mStringPoolSize-1)) {
+            const uint8_t* strings = (uint8_t*)mStrings;
+            const uint8_t* str = strings+off;
+            *outLen = decodeLength(&str);
+            size_t encLen = decodeLength(&str);
+            if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+                return (const char*)str;
+            } else {
+                ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                        (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+            }
+        } else {
+            ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint16_t)),
+                    (int)(mStringPoolSize*sizeof(uint16_t)));
+        }
+    }
+    return NULL;
+}
+
+const String8 ResStringPool::string8ObjectAt(size_t idx) const
+{
+    size_t len;
+    const char *str = (const char*)string8At(idx, &len);
+    if (str != NULL) {
+        return String8(str);
+    }
+    return String8(stringAt(idx, &len));
+}
+
+const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
+{
+    return styleAt(ref.index);
+}
+
+const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
+{
+    if (mError == NO_ERROR && idx < mHeader->styleCount) {
+        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
+        if (off < mStylePoolSize) {
+            return (const ResStringPool_span*)(mStyles+off);
+        } else {
+            ALOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint32_t)),
+                    (int)(mStylePoolSize*sizeof(uint32_t)));
+        }
+    }
+    return NULL;
+}
+
+ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    size_t len;
+
+    if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {
+        STRING_POOL_NOISY(ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string()));
+
+        // The string pool contains UTF 8 strings; we don't want to cause
+        // temporary UTF-16 strings to be created as we search.
+        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+            // Do a binary search for the string...  this is a little tricky,
+            // because the strings are sorted with strzcmp16().  So to match
+            // the ordering, we need to convert strings in the pool to UTF-16.
+            // But we don't want to hit the cache, so instead we will have a
+            // local temporary allocation for the conversions.
+            char16_t* convBuffer = (char16_t*)malloc(strLen+4);
+            ssize_t l = 0;
+            ssize_t h = mHeader->stringCount-1;
+
+            ssize_t mid;
+            while (l <= h) {
+                mid = l + (h - l)/2;
+                const uint8_t* s = (const uint8_t*)string8At(mid, &len);
+                int c;
+                if (s != NULL) {
+                    char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3);
+                    *end = 0;
+                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);
+                } else {
+                    c = -1;
+                }
+                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                             (const char*)s, c, (int)l, (int)mid, (int)h));
+                if (c == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    free(convBuffer);
+                    return mid;
+                } else if (c < 0) {
+                    l = mid + 1;
+                } else {
+                    h = mid - 1;
+                }
+            }
+            free(convBuffer);
+        } else {
+            // It is unusual to get the ID from an unsorted string block...
+            // most often this happens because we want to get IDs for style
+            // span tags; since those always appear at the end of the string
+            // block, start searching at the back.
+            String8 str8(str, strLen);
+            const size_t str8Len = str8.size();
+            for (int i=mHeader->stringCount-1; i>=0; i--) {
+                const char* s = string8At(i, &len);
+                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
+                             String8(s).string(),
+                             i));
+                if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return i;
+                }
+            }
+        }
+
+    } else {
+        STRING_POOL_NOISY(ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string()));
+
+        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+            // Do a binary search for the string...
+            ssize_t l = 0;
+            ssize_t h = mHeader->stringCount-1;
+
+            ssize_t mid;
+            while (l <= h) {
+                mid = l + (h - l)/2;
+                const char16_t* s = stringAt(mid, &len);
+                int c = s ? strzcmp16(s, len, str, strLen) : -1;
+                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                             String8(s).string(),
+                             c, (int)l, (int)mid, (int)h));
+                if (c == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return mid;
+                } else if (c < 0) {
+                    l = mid + 1;
+                } else {
+                    h = mid - 1;
+                }
+            }
+        } else {
+            // It is unusual to get the ID from an unsorted string block...
+            // most often this happens because we want to get IDs for style
+            // span tags; since those always appear at the end of the string
+            // block, start searching at the back.
+            for (int i=mHeader->stringCount-1; i>=0; i--) {
+                const char16_t* s = stringAt(i, &len);
+                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
+                             String8(s).string(),
+                             i));
+                if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return i;
+                }
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+size_t ResStringPool::size() const
+{
+    return (mError == NO_ERROR) ? mHeader->stringCount : 0;
+}
+
+size_t ResStringPool::styleCount() const
+{
+    return (mError == NO_ERROR) ? mHeader->styleCount : 0;
+}
+
+size_t ResStringPool::bytes() const
+{
+    return (mError == NO_ERROR) ? mHeader->header.size : 0;
+}
+
+bool ResStringPool::isSorted() const
+{
+    return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;
+}
+
+bool ResStringPool::isUTF8() const
+{
+    return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResXMLParser::ResXMLParser(const ResXMLTree& tree)
+    : mTree(tree), mEventCode(BAD_DOCUMENT)
+{
+}
+
+void ResXMLParser::restart()
+{
+    mCurNode = NULL;
+    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
+}
+const ResStringPool& ResXMLParser::getStrings() const
+{
+    return mTree.mStrings;
+}
+
+ResXMLParser::event_code_t ResXMLParser::getEventType() const
+{
+    return mEventCode;
+}
+
+ResXMLParser::event_code_t ResXMLParser::next()
+{
+    if (mEventCode == START_DOCUMENT) {
+        mCurNode = mTree.mRootNode;
+        mCurExt = mTree.mRootExt;
+        return (mEventCode=mTree.mRootCode);
+    } else if (mEventCode >= FIRST_CHUNK_CODE) {
+        return nextNode();
+    }
+    return mEventCode;
+}
+
+int32_t ResXMLParser::getCommentID() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
+}
+
+const uint16_t* ResXMLParser::getComment(size_t* outLen) const
+{
+    int32_t id = getCommentID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+uint32_t ResXMLParser::getLineNumber() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
+}
+
+int32_t ResXMLParser::getTextID() const
+{
+    if (mEventCode == TEXT) {
+        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getText(size_t* outLen) const
+{
+    int32_t id = getTextID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
+{
+    if (mEventCode == TEXT) {
+        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
+        return sizeof(Res_value);
+    }
+    return BAD_TYPE;
+}
+
+int32_t ResXMLParser::getNamespacePrefixID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
+{
+    int32_t id = getNamespacePrefixID();
+    //printf("prefix=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getNamespaceUriID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
+{
+    int32_t id = getNamespaceUriID();
+    //printf("uri=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getElementNamespaceID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
+{
+    int32_t id = getElementNamespaceID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getElementNameID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
+{
+    int32_t id = getElementNameID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+size_t ResXMLParser::getAttributeCount() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
+    }
+    return 0;
+}
+
+int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->ns.index);
+        }
+    }
+    return -2;
+}
+
+const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNamespaceID(idx);
+    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNamespaceID(idx);
+    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getAttributeNameID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->name.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNameID(idx);
+    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNameID(idx);
+    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
+}
+
+uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
+{
+    int32_t id = getAttributeNameID(idx);
+    if (id >= 0 && (size_t)id < mTree.mNumResIds) {
+        return dtohl(mTree.mResIds[id]);
+    }
+    return 0;
+}
+
+int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->rawValue.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeValueStringID(idx);
+    //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getAttributeDataType(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return attr->typedValue.dataType;
+        }
+    }
+    return Res_value::TYPE_NULL;
+}
+
+int32_t ResXMLParser::getAttributeData(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->typedValue.data);
+        }
+    }
+    return 0;
+}
+
+ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            outValue->copyFrom_dtoh(attr->typedValue);
+            return sizeof(Res_value);
+        }
+    }
+    return BAD_TYPE;
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
+{
+    String16 nsStr(ns != NULL ? ns : "");
+    String16 attrStr(attr);
+    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
+                            attrStr.string(), attrStr.size());
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
+                                       const char16_t* attr, size_t attrLen) const
+{
+    if (mEventCode == START_TAG) {
+        if (attr == NULL) {
+            return NAME_NOT_FOUND;
+        }
+        const size_t N = getAttributeCount();
+        if (mTree.mStrings.isUTF8()) {
+            String8 ns8, attr8;
+            if (ns != NULL) {
+                ns8 = String8(ns, nsLen);
+            }
+            attr8 = String8(attr, attrLen);
+            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen,
+                    attr8.string(), attrLen));
+            for (size_t i=0; i<N; i++) {
+                size_t curNsLen = 0, curAttrLen = 0;
+                const char* curNs = getAttributeNamespace8(i, &curNsLen);
+                const char* curAttr = getAttributeName8(i, &curAttrLen);
+                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen,
+                        curAttr, curAttrLen));
+                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
+                        && memcmp(attr8.string(), curAttr, attrLen) == 0) {
+                    if (ns == NULL) {
+                        if (curNs == NULL) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    } else if (curNs != NULL) {
+                        //printf(" --> ns=%s, curNs=%s\n",
+                        //       String8(ns).string(), String8(curNs).string());
+                        if (memcmp(ns8.string(), curNs, nsLen) == 0) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    }
+                }
+            }
+        } else {
+            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)",
+                    String8(ns, nsLen).string(), nsLen,
+                    String8(attr, attrLen).string(), attrLen));
+            for (size_t i=0; i<N; i++) {
+                size_t curNsLen = 0, curAttrLen = 0;
+                const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
+                const char16_t* curAttr = getAttributeName(i, &curAttrLen);
+                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)",
+                        String8(curNs, curNsLen).string(), curNsLen,
+                        String8(curAttr, curAttrLen).string(), curAttrLen));
+                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
+                        && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {
+                    if (ns == NULL) {
+                        if (curNs == NULL) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    } else if (curNs != NULL) {
+                        //printf(" --> ns=%s, curNs=%s\n",
+                        //       String8(ns).string(), String8(curNs).string());
+                        if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfID() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfClass() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfStyle() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ResXMLParser::event_code_t ResXMLParser::nextNode()
+{
+    if (mEventCode < 0) {
+        return mEventCode;
+    }
+
+    do {
+        const ResXMLTree_node* next = (const ResXMLTree_node*)
+            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
+        //ALOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
+        
+        if (((const uint8_t*)next) >= mTree.mDataEnd) {
+            mCurNode = NULL;
+            return (mEventCode=END_DOCUMENT);
+        }
+
+        if (mTree.validateNode(next) != NO_ERROR) {
+            mCurNode = NULL;
+            return (mEventCode=BAD_DOCUMENT);
+        }
+
+        mCurNode = next;
+        const uint16_t headerSize = dtohs(next->header.headerSize);
+        const uint32_t totalSize = dtohl(next->header.size);
+        mCurExt = ((const uint8_t*)next) + headerSize;
+        size_t minExtSize = 0;
+        event_code_t eventCode = (event_code_t)dtohs(next->header.type);
+        switch ((mEventCode=eventCode)) {
+            case RES_XML_START_NAMESPACE_TYPE:
+            case RES_XML_END_NAMESPACE_TYPE:
+                minExtSize = sizeof(ResXMLTree_namespaceExt);
+                break;
+            case RES_XML_START_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_attrExt);
+                break;
+            case RES_XML_END_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_endElementExt);
+                break;
+            case RES_XML_CDATA_TYPE:
+                minExtSize = sizeof(ResXMLTree_cdataExt);
+                break;
+            default:
+                ALOGW("Unknown XML block: header type %d in node at %d\n",
+                     (int)dtohs(next->header.type),
+                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
+                continue;
+        }
+        
+        if ((totalSize-headerSize) < minExtSize) {
+            ALOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
+                 (int)dtohs(next->header.type),
+                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
+                 (int)(totalSize-headerSize), (int)minExtSize);
+            return (mEventCode=BAD_DOCUMENT);
+        }
+        
+        //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
+        //       mCurNode, mCurExt, headerSize, minExtSize);
+        
+        return eventCode;
+    } while (true);
+}
+
+void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
+{
+    pos->eventCode = mEventCode;
+    pos->curNode = mCurNode;
+    pos->curExt = mCurExt;
+}
+
+void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
+{
+    mEventCode = pos.eventCode;
+    mCurNode = pos.curNode;
+    mCurExt = pos.curExt;
+}
+
+
+// --------------------------------------------------------------------
+
+static volatile int32_t gCount = 0;
+
+ResXMLTree::ResXMLTree()
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    restart();
+}
+
+ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //ALOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    setTo(data, size, copyData);
+}
+
+ResXMLTree::~ResXMLTree()
+{
+    //ALOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
+    uninit();
+}
+
+status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
+{
+    uninit();
+    mEventCode = START_DOCUMENT;
+
+    if (!data || !size) {
+        return (mError=BAD_TYPE);
+    }
+
+    if (copyData) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResXMLTree_header*)data;
+    mSize = dtohl(mHeader->header.size);
+    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
+        ALOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
+             (int)dtohs(mHeader->header.headerSize),
+             (int)dtohl(mHeader->header.size), (int)size);
+        mError = BAD_TYPE;
+        restart();
+        return mError;
+    }
+    mDataEnd = ((const uint8_t*)mHeader) + mSize;
+
+    mStrings.uninit();
+    mRootNode = NULL;
+    mResIds = NULL;
+    mNumResIds = 0;
+
+    // First look for a couple interesting chunks: the string block
+    // and first XML node.
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
+    const ResChunk_header* lastChunk = chunk;
+    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
+        if (err != NO_ERROR) {
+            mError = err;
+            goto done;
+        }
+        const uint16_t type = dtohs(chunk->type);
+        const size_t size = dtohl(chunk->size);
+        XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
+                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
+        if (type == RES_STRING_POOL_TYPE) {
+            mStrings.setTo(chunk, size);
+        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
+            mResIds = (const uint32_t*)
+                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
+            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
+        } else if (type >= RES_XML_FIRST_CHUNK_TYPE
+                   && type <= RES_XML_LAST_CHUNK_TYPE) {
+            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mCurNode = (const ResXMLTree_node*)lastChunk;
+            if (nextNode() == BAD_DOCUMENT) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mRootNode = mCurNode;
+            mRootExt = mCurExt;
+            mRootCode = mEventCode;
+            break;
+        } else {
+            XML_NOISY(printf("Skipping unknown chunk!\n"));
+        }
+        lastChunk = chunk;
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + size);
+    }
+
+    if (mRootNode == NULL) {
+        ALOGW("Bad XML block: no root element node found\n");
+        mError = BAD_TYPE;
+        goto done;
+    }
+
+    mError = mStrings.getError();
+
+done:
+    restart();
+    return mError;
+}
+
+status_t ResXMLTree::getError() const
+{
+    return mError;
+}
+
+void ResXMLTree::uninit()
+{
+    mError = NO_INIT;
+    mStrings.uninit();
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+    restart();
+}
+
+status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
+{
+    const uint16_t eventCode = dtohs(node->header.type);
+
+    status_t err = validate_chunk(
+        &node->header, sizeof(ResXMLTree_node),
+        mDataEnd, "ResXMLTree_node");
+
+    if (err >= NO_ERROR) {
+        // Only perform additional validation on START nodes
+        if (eventCode != RES_XML_START_ELEMENT_TYPE) {
+            return NO_ERROR;
+        }
+
+        const uint16_t headerSize = dtohs(node->header.headerSize);
+        const uint32_t size = dtohl(node->header.size);
+        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
+            (((const uint8_t*)node) + headerSize);
+        // check for sensical values pulled out of the stream so far...
+        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
+                && ((void*)attrExt > (void*)node)) {
+            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
+                * dtohs(attrExt->attributeCount);
+            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
+                return NO_ERROR;
+            }
+            ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
+                    (unsigned int)(size-headerSize));
+        }
+        else {
+            ALOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
+                (unsigned int)headerSize, (unsigned int)size);
+        }
+        return BAD_TYPE;
+    }
+
+    return err;
+
+#if 0
+    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
+
+    const uint16_t headerSize = dtohs(node->header.headerSize);
+    const uint32_t size = dtohl(node->header.size);
+
+    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
+        if (size >= headerSize) {
+            if (((const uint8_t*)node) <= (mDataEnd-size)) {
+                if (!isStart) {
+                    return NO_ERROR;
+                }
+                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
+                        <= (size-headerSize)) {
+                    return NO_ERROR;
+                }
+                ALOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
+                        (int)(size-headerSize));
+                return BAD_TYPE;
+            }
+            ALOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
+                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
+            return BAD_TYPE;
+        }
+        ALOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
+                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+                (int)headerSize, (int)size);
+        return BAD_TYPE;
+    }
+    ALOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
+            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+            (int)headerSize);
+    return BAD_TYPE;
+#endif
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {
+    const size_t size = dtohl(o.size);
+    if (size >= sizeof(ResTable_config)) {
+        *this = o;
+    } else {
+        memcpy(this, &o, size);
+        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
+    }
+}
+
+void ResTable_config::copyFromDtoH(const ResTable_config& o) {
+    copyFromDeviceNoSwap(o);
+    size = sizeof(ResTable_config);
+    mcc = dtohs(mcc);
+    mnc = dtohs(mnc);
+    density = dtohs(density);
+    screenWidth = dtohs(screenWidth);
+    screenHeight = dtohs(screenHeight);
+    sdkVersion = dtohs(sdkVersion);
+    minorVersion = dtohs(minorVersion);
+    smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
+    screenWidthDp = dtohs(screenWidthDp);
+    screenHeightDp = dtohs(screenHeightDp);
+}
+
+void ResTable_config::swapHtoD() {
+    size = htodl(size);
+    mcc = htods(mcc);
+    mnc = htods(mnc);
+    density = htods(density);
+    screenWidth = htods(screenWidth);
+    screenHeight = htods(screenHeight);
+    sdkVersion = htods(sdkVersion);
+    minorVersion = htods(minorVersion);
+    smallestScreenWidthDp = htods(smallestScreenWidthDp);
+    screenWidthDp = htods(screenWidthDp);
+    screenHeightDp = htods(screenHeightDp);
+}
+
+int ResTable_config::compare(const ResTable_config& o) const {
+    int32_t diff = (int32_t)(imsi - o.imsi);
+    if (diff != 0) return diff;
+    diff = (int32_t)(locale - o.locale);
+    if (diff != 0) return diff;
+    diff = (int32_t)(screenType - o.screenType);
+    if (diff != 0) return diff;
+    diff = (int32_t)(input - o.input);
+    if (diff != 0) return diff;
+    diff = (int32_t)(screenSize - o.screenSize);
+    if (diff != 0) return diff;
+    diff = (int32_t)(version - o.version);
+    if (diff != 0) return diff;
+    diff = (int32_t)(screenLayout - o.screenLayout);
+    if (diff != 0) return diff;
+    diff = (int32_t)(uiMode - o.uiMode);
+    if (diff != 0) return diff;
+    diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
+    if (diff != 0) return diff;
+    diff = (int32_t)(screenSizeDp - o.screenSizeDp);
+    return (int)diff;
+}
+
+int ResTable_config::compareLogical(const ResTable_config& o) const {
+    if (mcc != o.mcc) {
+        return mcc < o.mcc ? -1 : 1;
+    }
+    if (mnc != o.mnc) {
+        return mnc < o.mnc ? -1 : 1;
+    }
+    if (language[0] != o.language[0]) {
+        return language[0] < o.language[0] ? -1 : 1;
+    }
+    if (language[1] != o.language[1]) {
+        return language[1] < o.language[1] ? -1 : 1;
+    }
+    if (country[0] != o.country[0]) {
+        return country[0] < o.country[0] ? -1 : 1;
+    }
+    if (country[1] != o.country[1]) {
+        return country[1] < o.country[1] ? -1 : 1;
+    }
+    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) {
+        return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1;
+    }
+    if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+        return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;
+    }
+    if (screenWidthDp != o.screenWidthDp) {
+        return screenWidthDp < o.screenWidthDp ? -1 : 1;
+    }
+    if (screenHeightDp != o.screenHeightDp) {
+        return screenHeightDp < o.screenHeightDp ? -1 : 1;
+    }
+    if (screenWidth != o.screenWidth) {
+        return screenWidth < o.screenWidth ? -1 : 1;
+    }
+    if (screenHeight != o.screenHeight) {
+        return screenHeight < o.screenHeight ? -1 : 1;
+    }
+    if (density != o.density) {
+        return density < o.density ? -1 : 1;
+    }
+    if (orientation != o.orientation) {
+        return orientation < o.orientation ? -1 : 1;
+    }
+    if (touchscreen != o.touchscreen) {
+        return touchscreen < o.touchscreen ? -1 : 1;
+    }
+    if (input != o.input) {
+        return input < o.input ? -1 : 1;
+    }
+    if (screenLayout != o.screenLayout) {
+        return screenLayout < o.screenLayout ? -1 : 1;
+    }
+    if (uiMode != o.uiMode) {
+        return uiMode < o.uiMode ? -1 : 1;
+    }
+    if (version != o.version) {
+        return version < o.version ? -1 : 1;
+    }
+    return 0;
+}
+
+int ResTable_config::diff(const ResTable_config& o) const {
+    int diffs = 0;
+    if (mcc != o.mcc) diffs |= CONFIG_MCC;
+    if (mnc != o.mnc) diffs |= CONFIG_MNC;
+    if (locale != o.locale) diffs |= CONFIG_LOCALE;
+    if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
+    if (density != o.density) diffs |= CONFIG_DENSITY;
+    if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
+    if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
+            diffs |= CONFIG_KEYBOARD_HIDDEN;
+    if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
+    if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
+    if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
+    if (version != o.version) diffs |= CONFIG_VERSION;
+    if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR;
+    if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT;
+    if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
+    if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
+    if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
+    return diffs;
+}
+
+bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {
+    // The order of the following tests defines the importance of one
+    // configuration parameter over another.  Those tests first are more
+    // important, trumping any values in those following them.
+    if (imsi || o.imsi) {
+        if (mcc != o.mcc) {
+            if (!mcc) return false;
+            if (!o.mcc) return true;
+        }
+
+        if (mnc != o.mnc) {
+            if (!mnc) return false;
+            if (!o.mnc) return true;
+        }
+    }
+
+    if (locale || o.locale) {
+        if (language[0] != o.language[0]) {
+            if (!language[0]) return false;
+            if (!o.language[0]) return true;
+        }
+
+        if (country[0] != o.country[0]) {
+            if (!country[0]) return false;
+            if (!o.country[0]) return true;
+        }
+    }
+
+    if (screenLayout || o.screenLayout) {
+        if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) {
+            if (!(screenLayout & MASK_LAYOUTDIR)) return false;
+            if (!(o.screenLayout & MASK_LAYOUTDIR)) return true;
+        }
+    }
+
+    if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+            if (!smallestScreenWidthDp) return false;
+            if (!o.smallestScreenWidthDp) return true;
+        }
+    }
+
+    if (screenSizeDp || o.screenSizeDp) {
+        if (screenWidthDp != o.screenWidthDp) {
+            if (!screenWidthDp) return false;
+            if (!o.screenWidthDp) return true;
+        }
+
+        if (screenHeightDp != o.screenHeightDp) {
+            if (!screenHeightDp) return false;
+            if (!o.screenHeightDp) return true;
+        }
+    }
+
+    if (screenLayout || o.screenLayout) {
+        if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
+            if (!(screenLayout & MASK_SCREENSIZE)) return false;
+            if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
+        }
+        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
+            if (!(screenLayout & MASK_SCREENLONG)) return false;
+            if (!(o.screenLayout & MASK_SCREENLONG)) return true;
+        }
+    }
+
+    if (orientation != o.orientation) {
+        if (!orientation) return false;
+        if (!o.orientation) return true;
+    }
+
+    if (uiMode || o.uiMode) {
+        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
+            if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
+            if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
+        }
+        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
+            if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
+            if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
+        }
+    }
+
+    // density is never 'more specific'
+    // as the default just equals 160
+
+    if (touchscreen != o.touchscreen) {
+        if (!touchscreen) return false;
+        if (!o.touchscreen) return true;
+    }
+
+    if (input || o.input) {
+        if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
+            if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
+            if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
+        }
+
+        if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
+            if (!(inputFlags & MASK_NAVHIDDEN)) return false;
+            if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
+        }
+
+        if (keyboard != o.keyboard) {
+            if (!keyboard) return false;
+            if (!o.keyboard) return true;
+        }
+
+        if (navigation != o.navigation) {
+            if (!navigation) return false;
+            if (!o.navigation) return true;
+        }
+    }
+
+    if (screenSize || o.screenSize) {
+        if (screenWidth != o.screenWidth) {
+            if (!screenWidth) return false;
+            if (!o.screenWidth) return true;
+        }
+
+        if (screenHeight != o.screenHeight) {
+            if (!screenHeight) return false;
+            if (!o.screenHeight) return true;
+        }
+    }
+
+    if (version || o.version) {
+        if (sdkVersion != o.sdkVersion) {
+            if (!sdkVersion) return false;
+            if (!o.sdkVersion) return true;
+        }
+
+        if (minorVersion != o.minorVersion) {
+            if (!minorVersion) return false;
+            if (!o.minorVersion) return true;
+        }
+    }
+    return false;
+}
+
+bool ResTable_config::isBetterThan(const ResTable_config& o,
+        const ResTable_config* requested) const {
+    if (requested) {
+        if (imsi || o.imsi) {
+            if ((mcc != o.mcc) && requested->mcc) {
+                return (mcc);
+            }
+
+            if ((mnc != o.mnc) && requested->mnc) {
+                return (mnc);
+            }
+        }
+
+        if (locale || o.locale) {
+            if ((language[0] != o.language[0]) && requested->language[0]) {
+                return (language[0]);
+            }
+
+            if ((country[0] != o.country[0]) && requested->country[0]) {
+                return (country[0]);
+            }
+        }
+
+        if (screenLayout || o.screenLayout) {
+            if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0
+                    && (requested->screenLayout & MASK_LAYOUTDIR)) {
+                int myLayoutDir = screenLayout & MASK_LAYOUTDIR;
+                int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;
+                return (myLayoutDir > oLayoutDir);
+            }
+        }
+
+        if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+            // The configuration closest to the actual size is best.
+            // We assume that larger configs have already been filtered
+            // out at this point.  That means we just want the largest one.
+            if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+                return smallestScreenWidthDp > o.smallestScreenWidthDp;
+            }
+        }
+
+        if (screenSizeDp || o.screenSizeDp) {
+            // "Better" is based on the sum of the difference between both
+            // width and height from the requested dimensions.  We are
+            // assuming the invalid configs (with smaller dimens) have
+            // already been filtered.  Note that if a particular dimension
+            // is unspecified, we will end up with a large value (the
+            // difference between 0 and the requested dimension), which is
+            // good since we will prefer a config that has specified a
+            // dimension value.
+            int myDelta = 0, otherDelta = 0;
+            if (requested->screenWidthDp) {
+                myDelta += requested->screenWidthDp - screenWidthDp;
+                otherDelta += requested->screenWidthDp - o.screenWidthDp;
+            }
+            if (requested->screenHeightDp) {
+                myDelta += requested->screenHeightDp - screenHeightDp;
+                otherDelta += requested->screenHeightDp - o.screenHeightDp;
+            }
+            //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+            //    screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+            //    requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+            if (myDelta != otherDelta) {
+                return myDelta < otherDelta;
+            }
+        }
+
+        if (screenLayout || o.screenLayout) {
+            if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
+                    && (requested->screenLayout & MASK_SCREENSIZE)) {
+                // A little backwards compatibility here: undefined is
+                // considered equivalent to normal.  But only if the
+                // requested size is at least normal; otherwise, small
+                // is better than the default.
+                int mySL = (screenLayout & MASK_SCREENSIZE);
+                int oSL = (o.screenLayout & MASK_SCREENSIZE);
+                int fixedMySL = mySL;
+                int fixedOSL = oSL;
+                if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+                    if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+                    if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+                }
+                // For screen size, the best match is the one that is
+                // closest to the requested screen size, but not over
+                // (the not over part is dealt with in match() below).
+                if (fixedMySL == fixedOSL) {
+                    // If the two are the same, but 'this' is actually
+                    // undefined, then the other is really a better match.
+                    if (mySL == 0) return false;
+                    return true;
+                }
+                if (fixedMySL != fixedOSL) {
+                    return fixedMySL > fixedOSL;
+                }
+            }
+            if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
+                    && (requested->screenLayout & MASK_SCREENLONG)) {
+                return (screenLayout & MASK_SCREENLONG);
+            }
+        }
+
+        if ((orientation != o.orientation) && requested->orientation) {
+            return (orientation);
+        }
+
+        if (uiMode || o.uiMode) {
+            if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
+                    && (requested->uiMode & MASK_UI_MODE_TYPE)) {
+                return (uiMode & MASK_UI_MODE_TYPE);
+            }
+            if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
+                    && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
+                return (uiMode & MASK_UI_MODE_NIGHT);
+            }
+        }
+
+        if (screenType || o.screenType) {
+            if (density != o.density) {
+                // density is tough.  Any density is potentially useful
+                // because the system will scale it.  Scaling down
+                // is generally better than scaling up.
+                // Default density counts as 160dpi (the system default)
+                // TODO - remove 160 constants
+                int h = (density?density:160);
+                int l = (o.density?o.density:160);
+                bool bImBigger = true;
+                if (l > h) {
+                    int t = h;
+                    h = l;
+                    l = t;
+                    bImBigger = false;
+                }
+
+                int reqValue = (requested->density?requested->density:160);
+                if (reqValue >= h) {
+                    // requested value higher than both l and h, give h
+                    return bImBigger;
+                }
+                if (l >= reqValue) {
+                    // requested value lower than both l and h, give l
+                    return !bImBigger;
+                }
+                // saying that scaling down is 2x better than up
+                if (((2 * l) - reqValue) * h > reqValue * reqValue) {
+                    return !bImBigger;
+                } else {
+                    return bImBigger;
+                }
+            }
+
+            if ((touchscreen != o.touchscreen) && requested->touchscreen) {
+                return (touchscreen);
+            }
+        }
+
+        if (input || o.input) {
+            const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
+            const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
+            if (keysHidden != oKeysHidden) {
+                const int reqKeysHidden =
+                        requested->inputFlags & MASK_KEYSHIDDEN;
+                if (reqKeysHidden) {
+
+                    if (!keysHidden) return false;
+                    if (!oKeysHidden) return true;
+                    // For compatibility, we count KEYSHIDDEN_NO as being
+                    // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
+                    // these by making an exact match more specific.
+                    if (reqKeysHidden == keysHidden) return true;
+                    if (reqKeysHidden == oKeysHidden) return false;
+                }
+            }
+
+            const int navHidden = inputFlags & MASK_NAVHIDDEN;
+            const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
+            if (navHidden != oNavHidden) {
+                const int reqNavHidden =
+                        requested->inputFlags & MASK_NAVHIDDEN;
+                if (reqNavHidden) {
+
+                    if (!navHidden) return false;
+                    if (!oNavHidden) return true;
+                }
+            }
+
+            if ((keyboard != o.keyboard) && requested->keyboard) {
+                return (keyboard);
+            }
+
+            if ((navigation != o.navigation) && requested->navigation) {
+                return (navigation);
+            }
+        }
+
+        if (screenSize || o.screenSize) {
+            // "Better" is based on the sum of the difference between both
+            // width and height from the requested dimensions.  We are
+            // assuming the invalid configs (with smaller sizes) have
+            // already been filtered.  Note that if a particular dimension
+            // is unspecified, we will end up with a large value (the
+            // difference between 0 and the requested dimension), which is
+            // good since we will prefer a config that has specified a
+            // size value.
+            int myDelta = 0, otherDelta = 0;
+            if (requested->screenWidth) {
+                myDelta += requested->screenWidth - screenWidth;
+                otherDelta += requested->screenWidth - o.screenWidth;
+            }
+            if (requested->screenHeight) {
+                myDelta += requested->screenHeight - screenHeight;
+                otherDelta += requested->screenHeight - o.screenHeight;
+            }
+            if (myDelta != otherDelta) {
+                return myDelta < otherDelta;
+            }
+        }
+
+        if (version || o.version) {
+            if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
+                return (sdkVersion > o.sdkVersion);
+            }
+
+            if ((minorVersion != o.minorVersion) &&
+                    requested->minorVersion) {
+                return (minorVersion);
+            }
+        }
+
+        return false;
+    }
+    return isMoreSpecificThan(o);
+}
+
+bool ResTable_config::match(const ResTable_config& settings) const {
+    if (imsi != 0) {
+        if (mcc != 0 && mcc != settings.mcc) {
+            return false;
+        }
+        if (mnc != 0 && mnc != settings.mnc) {
+            return false;
+        }
+    }
+    if (locale != 0) {
+        if (language[0] != 0
+            && (language[0] != settings.language[0]
+                || language[1] != settings.language[1])) {
+            return false;
+        }
+        if (country[0] != 0
+            && (country[0] != settings.country[0]
+                || country[1] != settings.country[1])) {
+            return false;
+        }
+    }
+    if (screenConfig != 0) {
+        const int layoutDir = screenLayout&MASK_LAYOUTDIR;
+        const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;
+        if (layoutDir != 0 && layoutDir != setLayoutDir) {
+            return false;
+        }
+
+        const int screenSize = screenLayout&MASK_SCREENSIZE;
+        const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
+        // Any screen sizes for larger screens than the setting do not
+        // match.
+        if (screenSize != 0 && screenSize > setScreenSize) {
+            return false;
+        }
+
+        const int screenLong = screenLayout&MASK_SCREENLONG;
+        const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
+        if (screenLong != 0 && screenLong != setScreenLong) {
+            return false;
+        }
+
+        const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
+        const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
+        if (uiModeType != 0 && uiModeType != setUiModeType) {
+            return false;
+        }
+
+        const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
+        const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
+        if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
+            return false;
+        }
+
+        if (smallestScreenWidthDp != 0
+                && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
+            return false;
+        }
+    }
+    if (screenSizeDp != 0) {
+        if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
+            //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
+            return false;
+        }
+        if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
+            //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
+            return false;
+        }
+    }
+    if (screenType != 0) {
+        if (orientation != 0 && orientation != settings.orientation) {
+            return false;
+        }
+        // density always matches - we can scale it.  See isBetterThan
+        if (touchscreen != 0 && touchscreen != settings.touchscreen) {
+            return false;
+        }
+    }
+    if (input != 0) {
+        const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+        const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
+        if (keysHidden != 0 && keysHidden != setKeysHidden) {
+            // For compatibility, we count a request for KEYSHIDDEN_NO as also
+            // matching the more recent KEYSHIDDEN_SOFT.  Basically
+            // KEYSHIDDEN_NO means there is some kind of keyboard available.
+            //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
+            if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
+                //ALOGI("No match!");
+                return false;
+            }
+        }
+        const int navHidden = inputFlags&MASK_NAVHIDDEN;
+        const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
+        if (navHidden != 0 && navHidden != setNavHidden) {
+            return false;
+        }
+        if (keyboard != 0 && keyboard != settings.keyboard) {
+            return false;
+        }
+        if (navigation != 0 && navigation != settings.navigation) {
+            return false;
+        }
+    }
+    if (screenSize != 0) {
+        if (screenWidth != 0 && screenWidth > settings.screenWidth) {
+            return false;
+        }
+        if (screenHeight != 0 && screenHeight > settings.screenHeight) {
+            return false;
+        }
+    }
+    if (version != 0) {
+        if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
+            return false;
+        }
+        if (minorVersion != 0 && minorVersion != settings.minorVersion) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void ResTable_config::getLocale(char str[6]) const {
+    memset(str, 0, 6);
+    if (language[0]) {
+        str[0] = language[0];
+        str[1] = language[1];
+        if (country[0]) {
+            str[2] = '_';
+            str[3] = country[0];
+            str[4] = country[1];
+        }
+    }
+}
+
+String8 ResTable_config::toString() const {
+    String8 res;
+
+    if (mcc != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("%dmcc", dtohs(mcc));
+    }
+    if (mnc != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("%dmnc", dtohs(mnc));
+    }
+    if (language[0] != 0) {
+        if (res.size() > 0) res.append("-");
+        res.append(language, 2);
+    }
+    if (country[0] != 0) {
+        if (res.size() > 0) res.append("-");
+        res.append(country, 2);
+    }
+    if ((screenLayout&MASK_LAYOUTDIR) != 0) {
+        if (res.size() > 0) res.append("-");
+        switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) {
+            case ResTable_config::LAYOUTDIR_LTR:
+                res.append("ldltr");
+                break;
+            case ResTable_config::LAYOUTDIR_RTL:
+                res.append("ldrtl");
+                break;
+            default:
+                res.appendFormat("layoutDir=%d",
+                        dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR));
+                break;
+        }
+    }
+    if (smallestScreenWidthDp != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp));
+    }
+    if (screenWidthDp != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("w%ddp", dtohs(screenWidthDp));
+    }
+    if (screenHeightDp != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("h%ddp", dtohs(screenHeightDp));
+    }
+    if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {
+            case ResTable_config::SCREENSIZE_SMALL:
+                res.append("small");
+                break;
+            case ResTable_config::SCREENSIZE_NORMAL:
+                res.append("normal");
+                break;
+            case ResTable_config::SCREENSIZE_LARGE:
+                res.append("large");
+                break;
+            case ResTable_config::SCREENSIZE_XLARGE:
+                res.append("xlarge");
+                break;
+            default:
+                res.appendFormat("screenLayoutSize=%d",
+                        dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));
+                break;
+        }
+    }
+    if ((screenLayout&MASK_SCREENLONG) != 0) {
+        if (res.size() > 0) res.append("-");
+        switch (screenLayout&ResTable_config::MASK_SCREENLONG) {
+            case ResTable_config::SCREENLONG_NO:
+                res.append("notlong");
+                break;
+            case ResTable_config::SCREENLONG_YES:
+                res.append("long");
+                break;
+            default:
+                res.appendFormat("screenLayoutLong=%d",
+                        dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));
+                break;
+        }
+    }
+    if (orientation != ORIENTATION_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (orientation) {
+            case ResTable_config::ORIENTATION_PORT:
+                res.append("port");
+                break;
+            case ResTable_config::ORIENTATION_LAND:
+                res.append("land");
+                break;
+            case ResTable_config::ORIENTATION_SQUARE:
+                res.append("square");
+                break;
+            default:
+                res.appendFormat("orientation=%d", dtohs(orientation));
+                break;
+        }
+    }
+    if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {
+            case ResTable_config::UI_MODE_TYPE_DESK:
+                res.append("desk");
+                break;
+            case ResTable_config::UI_MODE_TYPE_CAR:
+                res.append("car");
+                break;
+            case ResTable_config::UI_MODE_TYPE_TELEVISION:
+                res.append("television");
+                break;
+            case ResTable_config::UI_MODE_TYPE_APPLIANCE:
+                res.append("appliance");
+                break;
+            default:
+                res.appendFormat("uiModeType=%d",
+                        dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));
+                break;
+        }
+    }
+    if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {
+        if (res.size() > 0) res.append("-");
+        switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {
+            case ResTable_config::UI_MODE_NIGHT_NO:
+                res.append("notnight");
+                break;
+            case ResTable_config::UI_MODE_NIGHT_YES:
+                res.append("night");
+                break;
+            default:
+                res.appendFormat("uiModeNight=%d",
+                        dtohs(uiMode&MASK_UI_MODE_NIGHT));
+                break;
+        }
+    }
+    if (density != DENSITY_DEFAULT) {
+        if (res.size() > 0) res.append("-");
+        switch (density) {
+            case ResTable_config::DENSITY_LOW:
+                res.append("ldpi");
+                break;
+            case ResTable_config::DENSITY_MEDIUM:
+                res.append("mdpi");
+                break;
+            case ResTable_config::DENSITY_TV:
+                res.append("tvdpi");
+                break;
+            case ResTable_config::DENSITY_HIGH:
+                res.append("hdpi");
+                break;
+            case ResTable_config::DENSITY_XHIGH:
+                res.append("xhdpi");
+                break;
+            case ResTable_config::DENSITY_XXHIGH:
+                res.append("xxhdpi");
+                break;
+            case ResTable_config::DENSITY_NONE:
+                res.append("nodpi");
+                break;
+            default:
+                res.appendFormat("%ddpi", dtohs(density));
+                break;
+        }
+    }
+    if (touchscreen != TOUCHSCREEN_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (touchscreen) {
+            case ResTable_config::TOUCHSCREEN_NOTOUCH:
+                res.append("notouch");
+                break;
+            case ResTable_config::TOUCHSCREEN_FINGER:
+                res.append("finger");
+                break;
+            case ResTable_config::TOUCHSCREEN_STYLUS:
+                res.append("stylus");
+                break;
+            default:
+                res.appendFormat("touchscreen=%d", dtohs(touchscreen));
+                break;
+        }
+    }
+    if (keyboard != KEYBOARD_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (keyboard) {
+            case ResTable_config::KEYBOARD_NOKEYS:
+                res.append("nokeys");
+                break;
+            case ResTable_config::KEYBOARD_QWERTY:
+                res.append("qwerty");
+                break;
+            case ResTable_config::KEYBOARD_12KEY:
+                res.append("12key");
+                break;
+            default:
+                res.appendFormat("keyboard=%d", dtohs(keyboard));
+                break;
+        }
+    }
+    if ((inputFlags&MASK_KEYSHIDDEN) != 0) {
+        if (res.size() > 0) res.append("-");
+        switch (inputFlags&MASK_KEYSHIDDEN) {
+            case ResTable_config::KEYSHIDDEN_NO:
+                res.append("keysexposed");
+                break;
+            case ResTable_config::KEYSHIDDEN_YES:
+                res.append("keyshidden");
+                break;
+            case ResTable_config::KEYSHIDDEN_SOFT:
+                res.append("keyssoft");
+                break;
+        }
+    }
+    if (navigation != NAVIGATION_ANY) {
+        if (res.size() > 0) res.append("-");
+        switch (navigation) {
+            case ResTable_config::NAVIGATION_NONAV:
+                res.append("nonav");
+                break;
+            case ResTable_config::NAVIGATION_DPAD:
+                res.append("dpad");
+                break;
+            case ResTable_config::NAVIGATION_TRACKBALL:
+                res.append("trackball");
+                break;
+            case ResTable_config::NAVIGATION_WHEEL:
+                res.append("wheel");
+                break;
+            default:
+                res.appendFormat("navigation=%d", dtohs(navigation));
+                break;
+        }
+    }
+    if ((inputFlags&MASK_NAVHIDDEN) != 0) {
+        if (res.size() > 0) res.append("-");
+        switch (inputFlags&MASK_NAVHIDDEN) {
+            case ResTable_config::NAVHIDDEN_NO:
+                res.append("navsexposed");
+                break;
+            case ResTable_config::NAVHIDDEN_YES:
+                res.append("navhidden");
+                break;
+            default:
+                res.appendFormat("inputFlagsNavHidden=%d",
+                        dtohs(inputFlags&MASK_NAVHIDDEN));
+                break;
+        }
+    }
+    if (screenSize != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight));
+    }
+    if (version != 0) {
+        if (res.size() > 0) res.append("-");
+        res.appendFormat("v%d", dtohs(sdkVersion));
+        if (minorVersion != 0) {
+            res.appendFormat(".%d", dtohs(minorVersion));
+        }
+    }
+
+    return res;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+struct ResTable::Header
+{
+    Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),
+        resourceIDMap(NULL), resourceIDMapSize(0) { }
+
+    ~Header()
+    {
+        free(resourceIDMap);
+    }
+
+    ResTable* const                 owner;
+    void*                           ownedData;
+    const ResTable_header*          header;
+    size_t                          size;
+    const uint8_t*                  dataEnd;
+    size_t                          index;
+    void*                           cookie;
+
+    ResStringPool                   values;
+    uint32_t*                       resourceIDMap;
+    size_t                          resourceIDMapSize;
+};
+
+struct ResTable::Type
+{
+    Type(const Header* _header, const Package* _package, size_t count)
+        : header(_header), package(_package), entryCount(count),
+          typeSpec(NULL), typeSpecFlags(NULL) { }
+    const Header* const             header;
+    const Package* const            package;
+    const size_t                    entryCount;
+    const ResTable_typeSpec*        typeSpec;
+    const uint32_t*                 typeSpecFlags;
+    Vector<const ResTable_type*>    configs;
+};
+
+struct ResTable::Package
+{
+    Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
+        : owner(_owner), header(_header), package(_package) { }
+    ~Package()
+    {
+        size_t i = types.size();
+        while (i > 0) {
+            i--;
+            delete types[i];
+        }
+    }
+    
+    ResTable* const                 owner;
+    const Header* const             header;
+    const ResTable_package* const   package;
+    Vector<Type*>                   types;
+
+    ResStringPool                   typeStrings;
+    ResStringPool                   keyStrings;
+    
+    const Type* getType(size_t idx) const {
+        return idx < types.size() ? types[idx] : NULL;
+    }
+};
+
+// A group of objects describing a particular resource package.
+// The first in 'package' is always the root object (from the resource
+// table that defined the package); the ones after are skins on top of it.
+struct ResTable::PackageGroup
+{
+    PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id)
+        : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { }
+    ~PackageGroup() {
+        clearBagCache();
+        const size_t N = packages.size();
+        for (size_t i=0; i<N; i++) {
+            Package* pkg = packages[i];
+            if (pkg->owner == owner) {
+                delete pkg;
+            }
+        }
+    }
+
+    void clearBagCache() {
+        if (bags) {
+            TABLE_NOISY(printf("bags=%p\n", bags));
+            Package* pkg = packages[0];
+            TABLE_NOISY(printf("typeCount=%x\n", typeCount));
+            for (size_t i=0; i<typeCount; i++) {
+                TABLE_NOISY(printf("type=%d\n", i));
+                const Type* type = pkg->getType(i);
+                if (type != NULL) {
+                    bag_set** typeBags = bags[i];
+                    TABLE_NOISY(printf("typeBags=%p\n", typeBags));
+                    if (typeBags) {
+                        TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
+                        const size_t N = type->entryCount;
+                        for (size_t j=0; j<N; j++) {
+                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
+                                free(typeBags[j]);
+                        }
+                        free(typeBags);
+                    }
+                }
+            }
+            free(bags);
+            bags = NULL;
+        }
+    }
+    
+    ResTable* const                 owner;
+    String16 const                  name;
+    uint32_t const                  id;
+    Vector<Package*>                packages;
+    
+    // This is for finding typeStrings and other common package stuff.
+    Package*                        basePackage;
+
+    // For quick access.
+    size_t                          typeCount;
+    
+    // Computed attribute bags, first indexed by the type and second
+    // by the entry in that type.
+    bag_set***                      bags;
+};
+
+struct ResTable::bag_set
+{
+    size_t numAttrs;    // number in array
+    size_t availAttrs;  // total space in array
+    uint32_t typeSpecFlags;
+    // Followed by 'numAttr' bag_entry structures.
+};
+
+ResTable::Theme::Theme(const ResTable& table)
+    : mTable(table)
+{
+    memset(mPackages, 0, sizeof(mPackages));
+}
+
+ResTable::Theme::~Theme()
+{
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi != NULL) {
+            free_package(pi);
+        }
+    }
+}
+
+void ResTable::Theme::free_package(package_info* pi)
+{
+    for (size_t j=0; j<pi->numTypes; j++) {
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            free(te);
+        }
+    }
+    free(pi);
+}
+
+ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
+{
+    package_info* newpi = (package_info*)malloc(
+        sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
+    newpi->numTypes = pi->numTypes;
+    for (size_t j=0; j<newpi->numTypes; j++) {
+        size_t cnt = pi->types[j].numEntries;
+        newpi->types[j].numEntries = cnt;
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+            newpi->types[j].entries = newte;
+            memcpy(newte, te, cnt*sizeof(theme_entry));
+        } else {
+            newpi->types[j].entries = NULL;
+        }
+    }
+    return newpi;
+}
+
+status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
+{
+    const bag_entry* bag;
+    uint32_t bagTypeSpecFlags = 0;
+    mTable.lock();
+    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
+    TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+    if (N < 0) {
+        mTable.unlock();
+        return N;
+    }
+
+    uint32_t curPackage = 0xffffffff;
+    ssize_t curPackageIndex = 0;
+    package_info* curPI = NULL;
+    uint32_t curType = 0xffffffff;
+    size_t numEntries = 0;
+    theme_entry* curEntries = NULL;
+
+    const bag_entry* end = bag + N;
+    while (bag < end) {
+        const uint32_t attrRes = bag->map.name.ident;
+        const uint32_t p = Res_GETPACKAGE(attrRes);
+        const uint32_t t = Res_GETTYPE(attrRes);
+        const uint32_t e = Res_GETENTRY(attrRes);
+
+        if (curPackage != p) {
+            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
+            if (pidx < 0) {
+                ALOGE("Style contains key with bad package: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curPackage = p;
+            curPackageIndex = pidx;
+            curPI = mPackages[pidx];
+            if (curPI == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[pidx];
+                int cnt = grp->typeCount;
+                curPI = (package_info*)malloc(
+                    sizeof(package_info) + (cnt*sizeof(type_info)));
+                curPI->numTypes = cnt;
+                memset(curPI->types, 0, cnt*sizeof(type_info));
+                mPackages[pidx] = curPI;
+            }
+            curType = 0xffffffff;
+        }
+        if (curType != t) {
+            if (t >= curPI->numTypes) {
+                ALOGE("Style contains key with bad type: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curType = t;
+            curEntries = curPI->types[t].entries;
+            if (curEntries == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
+                const Type* type = grp->packages[0]->getType(t);
+                int cnt = type != NULL ? type->entryCount : 0;
+                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
+                curPI->types[t].numEntries = cnt;
+                curPI->types[t].entries = curEntries;
+            }
+            numEntries = curPI->types[t].numEntries;
+        }
+        if (e >= numEntries) {
+            ALOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
+            bag++;
+            continue;
+        }
+        theme_entry* curEntry = curEntries + e;
+        TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+                   attrRes, bag->map.value.dataType, bag->map.value.data,
+             curEntry->value.dataType));
+        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
+            curEntry->stringBlock = bag->stringBlock;
+            curEntry->typeSpecFlags |= bagTypeSpecFlags;
+            curEntry->value = bag->map.value;
+        }
+
+        bag++;
+    }
+
+    mTable.unlock();
+
+    //ALOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+status_t ResTable::Theme::setTo(const Theme& other)
+{
+    //ALOGI("Setting theme %p from theme %p...\n", this, &other);
+    //dumpToLog();
+    //other.dumpToLog();
+    
+    if (&mTable == &other.mTable) {
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    } else {
+        // @todo: need to really implement this, not just copy
+        // the system package (which is still wrong because it isn't
+        // fixing up resource references).
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (i == 0 && other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    }
+
+    //ALOGI("Final theme:");
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
+        uint32_t* outTypeSpecFlags) const
+{
+    int cnt = 20;
+
+    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
+    
+    do {
+        const ssize_t p = mTable.getResourcePackageIndex(resID);
+        const uint32_t t = Res_GETTYPE(resID);
+        const uint32_t e = Res_GETENTRY(resID);
+
+        TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
+
+        if (p >= 0) {
+            const package_info* const pi = mPackages[p];
+            TABLE_THEME(ALOGI("Found package: %p", pi));
+            if (pi != NULL) {
+                TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
+                if (t < pi->numTypes) {
+                    const type_info& ti = pi->types[t];
+                    TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
+                    if (e < ti.numEntries) {
+                        const theme_entry& te = ti.entries[e];
+                        if (outTypeSpecFlags != NULL) {
+                            *outTypeSpecFlags |= te.typeSpecFlags;
+                        }
+                        TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
+                                te.value.dataType, te.value.data));
+                        const uint8_t type = te.value.dataType;
+                        if (type == Res_value::TYPE_ATTRIBUTE) {
+                            if (cnt > 0) {
+                                cnt--;
+                                resID = te.value.data;
+                                continue;
+                            }
+                            ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
+                            return BAD_INDEX;
+                        } else if (type != Res_value::TYPE_NULL) {
+                            *outValue = te.value;
+                            return te.stringBlock;
+                        }
+                        return BAD_INDEX;
+                    }
+                }
+            }
+        }
+        break;
+
+    } while (true);
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
+        ssize_t blockIndex, uint32_t* outLastRef,
+        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
+{
+    //printf("Resolving type=0x%x\n", inOutValue->dataType);
+    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
+        uint32_t newTypeSpecFlags;
+        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
+        TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
+             (int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
+        //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
+        if (blockIndex < 0) {
+            return blockIndex;
+        }
+    }
+    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
+            inoutTypeSpecFlags, inoutConfig);
+}
+
+void ResTable::Theme::dumpToLog() const
+{
+    ALOGI("Theme %p:\n", this);
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi == NULL) continue;
+        
+        ALOGI("  Package #0x%02x:\n", (int)(i+1));
+        for (size_t j=0; j<pi->numTypes; j++) {
+            type_info& ti = pi->types[j];
+            if (ti.numEntries == 0) continue;
+            
+            ALOGI("    Type #0x%02x:\n", (int)(j+1));
+            for (size_t k=0; k<ti.numEntries; k++) {
+                theme_entry& te = ti.entries[k];
+                if (te.value.dataType == Res_value::TYPE_NULL) continue;
+                ALOGI("      0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
+                     (int)Res_MAKEID(i, j, k),
+                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);
+            }
+        }
+    }
+}
+
+ResTable::ResTable()
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    //ALOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    add(data, size, cookie, copyData);
+    LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
+    //ALOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::~ResTable()
+{
+    //ALOGI("Destroying ResTable in %p\n", this);
+    uninit();
+}
+
+inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
+{
+    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData,
+                       const void* idmap)
+{
+    return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap));
+}
+
+status_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap)
+{
+    const void* data = asset->getBuffer(true);
+    if (data == NULL) {
+        ALOGW("Unable to get buffer of resource asset file");
+        return UNKNOWN_ERROR;
+    }
+    size_t size = (size_t)asset->getLength();
+    return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap));
+}
+
+status_t ResTable::add(ResTable* src)
+{
+    mError = src->mError;
+    
+    for (size_t i=0; i<src->mHeaders.size(); i++) {
+        mHeaders.add(src->mHeaders[i]);
+    }
+    
+    for (size_t i=0; i<src->mPackageGroups.size(); i++) {
+        PackageGroup* srcPg = src->mPackageGroups[i];
+        PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id);
+        for (size_t j=0; j<srcPg->packages.size(); j++) {
+            pg->packages.add(srcPg->packages[j]);
+        }
+        pg->basePackage = srcPg->basePackage;
+        pg->typeCount = srcPg->typeCount;
+        mPackageGroups.add(pg);
+    }
+    
+    memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap));
+    
+    return mError;
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie,
+                       Asset* asset, bool copyData, const Asset* idmap)
+{
+    if (!data) return NO_ERROR;
+    Header* header = new Header(this);
+    header->index = mHeaders.size();
+    header->cookie = cookie;
+    if (idmap != NULL) {
+        const size_t idmap_size = idmap->getLength();
+        const void* idmap_data = const_cast<Asset*>(idmap)->getBuffer(true);
+        header->resourceIDMap = (uint32_t*)malloc(idmap_size);
+        if (header->resourceIDMap == NULL) {
+            delete header;
+            return (mError = NO_MEMORY);
+        }
+        memcpy((void*)header->resourceIDMap, idmap_data, idmap_size);
+        header->resourceIDMapSize = idmap_size;
+    }
+    mHeaders.add(header);
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    LOAD_TABLE_NOISY(
+        ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d "
+             "idmap=%p\n", data, size, cookie, asset, copyData, idmap));
+    
+    if (copyData || notDeviceEndian) {
+        header->ownedData = malloc(size);
+        if (header->ownedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(header->ownedData, data, size);
+        data = header->ownedData;
+    }
+
+    header->header = (const ResTable_header*)data;
+    header->size = dtohl(header->header->header.size);
+    //ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
+    //     dtohl(header->header->header.size), header->header->header.size);
+    LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
+    LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
+                                  16, 16, 0, false, printToLogFunc));
+    if (dtohs(header->header->header.headerSize) > header->size
+            || header->size > size) {
+        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
+        ALOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size);
+        return (mError=BAD_TYPE);
+    }
+    header->dataEnd = ((const uint8_t*)header->header) + header->size;
+
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)header->header)
+                                 + dtohs(header->header->header.headerSize));
+    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
+        if (err != NO_ERROR) {
+            return (mError=err);
+        }
+        TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_STRING_POOL_TYPE) {
+            if (header->values.getError() != NO_ERROR) {
+                // Only use the first string chunk; ignore any others that
+                // may appear.
+                status_t err = header->values.setTo(chunk, csize);
+                if (err != NO_ERROR) {
+                    return (mError=err);
+                }
+            } else {
+                ALOGW("Multiple string chunks found in resource table.");
+            }
+        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
+            if (curPackage >= dtohl(header->header->packageCount)) {
+                ALOGW("More package chunks were found than the %d declared in the header.",
+                     dtohl(header->header->packageCount));
+                return (mError=BAD_TYPE);
+            }
+            uint32_t idmap_id = 0;
+            if (idmap != NULL) {
+                uint32_t tmp;
+                if (getIdmapPackageId(header->resourceIDMap,
+                                      header->resourceIDMapSize,
+                                      &tmp) == NO_ERROR) {
+                    idmap_id = tmp;
+                }
+            }
+            if (parsePackage((ResTable_package*)chunk, header, idmap_id) != NO_ERROR) {
+                return mError;
+            }
+            curPackage++;
+        } else {
+            ALOGW("Unknown chunk type %p in table at %p.\n",
+                 (void*)(int)(ctype),
+                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (curPackage < dtohl(header->header->packageCount)) {
+        ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
+             (int)curPackage, dtohl(header->header->packageCount));
+        return (mError=BAD_TYPE);
+    }
+    mError = header->values.getError();
+    if (mError != NO_ERROR) {
+        ALOGW("No string values found in resource table!");
+    }
+
+    TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
+    return mError;
+}
+
+status_t ResTable::getError() const
+{
+    return mError;
+}
+
+void ResTable::uninit()
+{
+    mError = NO_INIT;
+    size_t N = mPackageGroups.size();
+    for (size_t i=0; i<N; i++) {
+        PackageGroup* g = mPackageGroups[i];
+        delete g;
+    }
+    N = mHeaders.size();
+    for (size_t i=0; i<N; i++) {
+        Header* header = mHeaders[i];
+        if (header->owner == this) {
+            if (header->ownedData) {
+                free(header->ownedData);
+            }
+            delete header;
+        }
+    }
+
+    mPackageGroups.clear();
+    mHeaders.clear();
+}
+
+bool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const
+{
+    if (mError != NO_ERROR) {
+        return false;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            ALOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            ALOGW("No known package when getting name for resource number 0x%08x", resID);
+        }
+        return false;
+    }
+    if (t < 0) {
+        ALOGW("No type identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        ALOGW("Bad identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (grp->packages.size() > 0) {
+        const Package* const package = grp->packages[0];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
+        if (offset <= 0) {
+            return false;
+        }
+
+        outName->package = grp->name.string();
+        outName->packageLen = grp->name.size();
+        if (allowUtf8) {
+            outName->type8 = grp->basePackage->typeStrings.string8At(t, &outName->typeLen);
+            outName->name8 = grp->basePackage->keyStrings.string8At(
+                dtohl(entry->key.index), &outName->nameLen);
+        } else {
+            outName->type8 = NULL;
+            outName->name8 = NULL;
+        }
+        if (outName->type8 == NULL) {
+            outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
+            // If we have a bad index for some reason, we should abort.
+            if (outName->type == NULL) {
+                return false;
+            }
+        }
+        if (outName->name8 == NULL) {
+            outName->name = grp->basePackage->keyStrings.stringAt(
+                dtohl(entry->key.index), &outName->nameLen);
+            // If we have a bad index for some reason, we should abort.
+            if (outName->name == NULL) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,
+        uint32_t* outSpecFlags, ResTable_config* outConfig) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            ALOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        } else {
+            ALOGW("No known package when getting value for resource number 0x%08x", resID);
+        }
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        ALOGW("No type identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    const Res_value* bestValue = NULL;
+    const Package* bestPackage = NULL;
+    ResTable_config bestItem;
+    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
+
+    if (outSpecFlags != NULL) *outSpecFlags = 0;
+
+    // Look through all resource packages, starting with the most
+    // recently added.
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        ALOGW("Bad identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    // Allow overriding density
+    const ResTable_config* desiredConfig = &mParams;
+    ResTable_config* overrideConfig = NULL;
+    if (density > 0) {
+        overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));
+        if (overrideConfig == NULL) {
+            ALOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));
+            return BAD_INDEX;
+        }
+        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));
+        overrideConfig->density = density;
+        desiredConfig = overrideConfig;
+    }
+
+    ssize_t rc = BAD_VALUE;
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+        int T = t;
+        int E = e;
+
+        const Package* const package = grp->packages[ip];
+        if (package->header->resourceIDMap) {
+            uint32_t overlayResID = 0x0;
+            status_t retval = idmapLookup(package->header->resourceIDMap,
+                                          package->header->resourceIDMapSize,
+                                          resID, &overlayResID);
+            if (retval == NO_ERROR && overlayResID != 0x0) {
+                // for this loop iteration, this is the type and entry we really want
+                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
+                T = Res_GETTYPE(overlayResID);
+                E = Res_GETENTRY(overlayResID);
+            } else {
+                // resource not present in overlay package, continue with the next package
+                continue;
+            }
+        }
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        ssize_t offset = getEntry(package, T, E, desiredConfig, &type, &entry, &typeClass);
+        if (offset <= 0) {
+            // No {entry, appropriate config} pair found in package. If this
+            // package is an overlay package (ip != 0), this simply means the
+            // overlay package did not specify a default.
+            // Non-overlay packages are still required to provide a default.
+            if (offset < 0 && ip == 0) {
+                ALOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
+                        resID, T, E, ip, (int)offset);
+                rc = offset;
+                goto out;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
+            if (!mayBeBag) {
+                ALOGW("Requesting resource %p failed because it is complex\n",
+                     (void*)resID);
+            }
+            continue;
+        }
+
+        TABLE_NOISY(aout << "Resource type data: "
+              << HexDump(type, dtohl(type->header.size)) << endl);
+
+        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
+            ALOGW("ResTable_item at %d is beyond type chunk data %d",
+                 (int)offset, dtohl(type->header.size));
+            rc = BAD_TYPE;
+            goto out;
+        }
+
+        const Res_value* item =
+            (const Res_value*)(((const uint8_t*)type) + offset);
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(type->config);
+
+        if (outSpecFlags != NULL) {
+            if (typeClass->typeSpecFlags != NULL) {
+                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
+            } else {
+                *outSpecFlags = -1;
+            }
+        }
+
+        if (bestPackage != NULL &&
+            (bestItem.isMoreSpecificThan(thisConfig) || bestItem.diff(thisConfig) == 0)) {
+            // Discard thisConfig not only if bestItem is more specific, but also if the two configs
+            // are identical (diff == 0), or overlay packages will not take effect.
+            continue;
+        }
+        
+        bestItem = thisConfig;
+        bestValue = item;
+        bestPackage = package;
+    }
+
+    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
+
+    if (bestValue) {
+        outValue->size = dtohs(bestValue->size);
+        outValue->res0 = bestValue->res0;
+        outValue->dataType = bestValue->dataType;
+        outValue->data = dtohl(bestValue->data);
+        if (outConfig != NULL) {
+            *outConfig = bestItem;
+        }
+        TABLE_NOISY(size_t len;
+              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
+                     bestPackage->header->index,
+                     outValue->dataType,
+                     outValue->dataType == bestValue->TYPE_STRING
+                     ? String8(bestPackage->header->values.stringAt(
+                         outValue->data, &len)).string()
+                     : "",
+                     outValue->data));
+        rc = bestPackage->header->index;
+        goto out;
+    }
+
+out:
+    if (overrideConfig != NULL) {
+        free(overrideConfig);
+    }
+
+    return rc;
+}
+
+ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
+        ResTable_config* outConfig) const
+{
+    int count=0;
+    while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
+           && value->data != 0 && count < 20) {
+        if (outLastRef) *outLastRef = value->data;
+        uint32_t lastRef = value->data;
+        uint32_t newFlags = 0;
+        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,
+                outConfig);
+        if (newIndex == BAD_INDEX) {
+            return BAD_INDEX;
+        }
+        TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
+             (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
+        //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
+        if (newIndex < 0) {
+            // This can fail if the resource being referenced is a style...
+            // in this case, just return the reference, and expect the
+            // caller to deal with.
+            return blockIndex;
+        }
+        blockIndex = newIndex;
+        count++;
+    }
+    return blockIndex;
+}
+
+const char16_t* ResTable::valueToString(
+    const Res_value* value, size_t stringBlock,
+    char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
+{
+    if (!value) {
+        return NULL;
+    }
+    if (value->dataType == value->TYPE_STRING) {
+        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
+    }
+    // XXX do int to string conversions.
+    return NULL;
+}
+
+ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
+{
+    mLock.lock();
+    ssize_t err = getBagLocked(resID, outBag);
+    if (err < NO_ERROR) {
+        //printf("*** get failed!  unlocking\n");
+        mLock.unlock();
+    }
+    return err;
+}
+
+void ResTable::unlockBag(const bag_entry* bag) const
+{
+    //printf("<<< unlockBag %p\n", this);
+    mLock.unlock();
+}
+
+void ResTable::lock() const
+{
+    mLock.lock();
+}
+
+void ResTable::unlock() const
+{
+    mLock.unlock();
+}
+
+ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
+        uint32_t* outTypeSpecFlags) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        ALOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        ALOGW("No type identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
+    PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        ALOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
+        return false;
+    }
+
+    if (t >= (int)grp->typeCount) {
+        ALOGW("Type identifier 0x%x is larger than type count 0x%x",
+             t+1, (int)grp->typeCount);
+        return BAD_INDEX;
+    }
+
+    const Package* const basePackage = grp->packages[0];
+
+    const Type* const typeConfigs = basePackage->getType(t);
+
+    const size_t NENTRY = typeConfigs->entryCount;
+    if (e >= (int)NENTRY) {
+        ALOGW("Entry identifier 0x%x is larger than entry count 0x%x",
+             e, (int)typeConfigs->entryCount);
+        return BAD_INDEX;
+    }
+
+    // First see if we've already computed this bag...
+    if (grp->bags) {
+        bag_set** typeSet = grp->bags[t];
+        if (typeSet) {
+            bag_set* set = typeSet[e];
+            if (set) {
+                if (set != (bag_set*)0xFFFFFFFF) {
+                    if (outTypeSpecFlags != NULL) {
+                        *outTypeSpecFlags = set->typeSpecFlags;
+                    }
+                    *outBag = (bag_entry*)(set+1);
+                    //ALOGI("Found existing bag for: %p\n", (void*)resID);
+                    return set->numAttrs;
+                }
+                ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
+                     resID);
+                return BAD_INDEX;
+            }
+        }
+    }
+
+    // Bag not found, we need to compute it!
+    if (!grp->bags) {
+        grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*));
+        if (!grp->bags) return NO_MEMORY;
+    }
+
+    bag_set** typeSet = grp->bags[t];
+    if (!typeSet) {
+        typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));
+        if (!typeSet) return NO_MEMORY;
+        grp->bags[t] = typeSet;
+    }
+
+    // Mark that we are currently working on this one.
+    typeSet[e] = (bag_set*)0xFFFFFFFF;
+
+    // This is what we are building.
+    bag_set* set = NULL;
+
+    TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
+    
+    ResTable_config bestConfig;
+    memset(&bestConfig, 0, sizeof(bestConfig));
+
+    // Now collect all bag attributes from all packages.
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+        int T = t;
+        int E = e;
+
+        const Package* const package = grp->packages[ip];
+        if (package->header->resourceIDMap) {
+            uint32_t overlayResID = 0x0;
+            status_t retval = idmapLookup(package->header->resourceIDMap,
+                                          package->header->resourceIDMapSize,
+                                          resID, &overlayResID);
+            if (retval == NO_ERROR && overlayResID != 0x0) {
+                // for this loop iteration, this is the type and entry we really want
+                ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
+                T = Res_GETTYPE(overlayResID);
+                E = Res_GETENTRY(overlayResID);
+            } else {
+                // resource not present in overlay package, continue with the next package
+                continue;
+            }
+        }
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E);
+        ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass);
+        ALOGV("Resulting offset=%d\n", offset);
+        if (offset <= 0) {
+            // No {entry, appropriate config} pair found in package. If this
+            // package is an overlay package (ip != 0), this simply means the
+            // overlay package did not specify a default.
+            // Non-overlay packages are still required to provide a default.
+            if (offset < 0 && ip == 0) {
+                if (set) free(set);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
+            ALOGW("Skipping entry %p in package table %d because it is not complex!\n",
+                 (void*)resID, (int)ip);
+            continue;
+        }
+
+        if (set != NULL && !type->config.isBetterThan(bestConfig, NULL)) {
+            continue;
+        }
+        bestConfig = type->config;
+        if (set) {
+            free(set);
+            set = NULL;
+        }
+
+        const uint16_t entrySize = dtohs(entry->size);
+        const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
+        const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
+        
+        size_t N = count;
+
+        TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
+                         entrySize, parent, count));
+
+        // If this map inherits from another, we need to start
+        // with its parent's values.  Otherwise start out empty.
+        TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
+                           entrySize, parent));
+        if (parent) {
+            const bag_entry* parentBag;
+            uint32_t parentTypeSpecFlags = 0;
+            const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
+            const size_t NT = ((NP >= 0) ? NP : 0) + N;
+            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
+            if (set == NULL) {
+                return NO_MEMORY;
+            }
+            if (NP > 0) {
+                memcpy(set+1, parentBag, NP*sizeof(bag_entry));
+                set->numAttrs = NP;
+                TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
+            } else {
+                TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
+                set->numAttrs = 0;
+            }
+            set->availAttrs = NT;
+            set->typeSpecFlags = parentTypeSpecFlags;
+        } else {
+            set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
+            if (set == NULL) {
+                return NO_MEMORY;
+            }
+            set->numAttrs = 0;
+            set->availAttrs = N;
+            set->typeSpecFlags = 0;
+        }
+
+        if (typeClass->typeSpecFlags != NULL) {
+            set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[E]);
+        } else {
+            set->typeSpecFlags = -1;
+        }
+        
+        // Now merge in the new attributes...
+        ssize_t curOff = offset;
+        const ResTable_map* map;
+        bag_entry* entries = (bag_entry*)(set+1);
+        size_t curEntry = 0;
+        uint32_t pos = 0;
+        TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
+                     set, entries, set->availAttrs));
+        while (pos < count) {
+            TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
+
+            if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
+                ALOGW("ResTable_map at %d is beyond type chunk data %d",
+                     (int)curOff, dtohl(type->header.size));
+                return BAD_TYPE;
+            }
+            map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
+            N++;
+
+            const uint32_t newName = htodl(map->name.ident);
+            bool isInside;
+            uint32_t oldName = 0;
+            while ((isInside=(curEntry < set->numAttrs))
+                    && (oldName=entries[curEntry].map.name.ident) < newName) {
+                TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
+                             curEntry, entries[curEntry].map.name.ident));
+                curEntry++;
+            }
+
+            if ((!isInside) || oldName != newName) {
+                // This is a new attribute...  figure out what to do with it.
+                if (set->numAttrs >= set->availAttrs) {
+                    // Need to alloc more memory...
+                    const size_t newAvail = set->availAttrs+N;
+                    set = (bag_set*)realloc(set,
+                                            sizeof(bag_set)
+                                            + sizeof(bag_entry)*newAvail);
+                    if (set == NULL) {
+                        return NO_MEMORY;
+                    }
+                    set->availAttrs = newAvail;
+                    entries = (bag_entry*)(set+1);
+                    TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
+                                 set, entries, set->availAttrs));
+                }
+                if (isInside) {
+                    // Going in the middle, need to make space.
+                    memmove(entries+curEntry+1, entries+curEntry,
+                            sizeof(bag_entry)*(set->numAttrs-curEntry));
+                    set->numAttrs++;
+                }
+                TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
+                             curEntry, newName));
+            } else {
+                TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
+                             curEntry, oldName));
+            }
+
+            bag_entry* cur = entries+curEntry;
+
+            cur->stringBlock = package->header->index;
+            cur->map.name.ident = newName;
+            cur->map.value.copyFrom_dtoh(map->value);
+            TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
+                         curEntry, cur, cur->stringBlock, cur->map.name.ident,
+                         cur->map.value.dataType, cur->map.value.data));
+
+            // On to the next!
+            curEntry++;
+            pos++;
+            const size_t size = dtohs(map->value.size);
+            curOff += size + sizeof(*map)-sizeof(map->value);
+        };
+        if (curEntry > set->numAttrs) {
+            set->numAttrs = curEntry;
+        }
+    }
+
+    // And this is it...
+    typeSet[e] = set;
+    if (set) {
+        if (outTypeSpecFlags != NULL) {
+            *outTypeSpecFlags = set->typeSpecFlags;
+        }
+        *outBag = (bag_entry*)(set+1);
+        TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
+        return set->numAttrs;
+    }
+    return BAD_INDEX;
+}
+
+void ResTable::setParameters(const ResTable_config* params)
+{
+    mLock.lock();
+    TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
+    mParams = *params;
+    for (size_t i=0; i<mPackageGroups.size(); i++) {
+        TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
+        mPackageGroups[i]->clearBagCache();
+    }
+    mLock.unlock();
+}
+
+void ResTable::getParameters(ResTable_config* params) const
+{
+    mLock.lock();
+    *params = mParams;
+    mLock.unlock();
+}
+
+struct id_name_map {
+    uint32_t id;
+    size_t len;
+    char16_t name[6];
+};
+
+const static id_name_map ID_NAMES[] = {
+    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },
+    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },
+    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },
+    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },
+    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
+    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },
+    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },
+    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },
+    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },
+    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },
+};
+
+uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
+                                     const char16_t* type, size_t typeLen,
+                                     const char16_t* package,
+                                     size_t packageLen,
+                                     uint32_t* outTypeSpecFlags) const
+{
+    TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
+
+    // Check for internal resource identifier as the very first thing, so
+    // that we will always find them even when there are no resources.
+    if (name[0] == '^') {
+        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
+        size_t len;
+        for (int i=0; i<N; i++) {
+            const id_name_map* m = ID_NAMES + i;
+            len = m->len;
+            if (len != nameLen) {
+                continue;
+            }
+            for (size_t j=1; j<len; j++) {
+                if (m->name[j] != name[j]) {
+                    goto nope;
+                }
+            }
+            if (outTypeSpecFlags) {
+                *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
+            }
+            return m->id;
+nope:
+            ;
+        }
+        if (nameLen > 7) {
+            if (name[1] == 'i' && name[2] == 'n'
+                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
+                && name[6] == '_') {
+                int index = atoi(String8(name + 7, nameLen - 7).string());
+                if (Res_CHECKID(index)) {
+                    ALOGW("Array resource index: %d is too large.",
+                         index);
+                    return 0;
+                }
+                if (outTypeSpecFlags) {
+                    *outTypeSpecFlags = ResTable_typeSpec::SPEC_PUBLIC;
+                }
+                return  Res_MAKEARRAY(index);
+            }
+        }
+        return 0;
+    }
+
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+
+    bool fakePublic = false;
+
+    // Figure out the package and type we are looking in...
+
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* const nameEnd = name+nameLen;
+    const char16_t* p = name;
+    while (p < nameEnd) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') typeEnd = p;
+        p++;
+    }
+    if (*name == '@') {
+        name++;
+        if (*name == '*') {
+            fakePublic = true;
+            name++;
+        }
+    }
+    if (name >= nameEnd) {
+        return 0;
+    }
+
+    if (packageEnd) {
+        package = name;
+        packageLen = packageEnd-name;
+        name = packageEnd+1;
+    } else if (!package) {
+        return 0;
+    }
+
+    if (typeEnd) {
+        type = name;
+        typeLen = typeEnd-name;
+        name = typeEnd+1;
+    } else if (!type) {
+        return 0;
+    }
+
+    if (name >= nameEnd) {
+        return 0;
+    }
+    nameLen = nameEnd-name;
+
+    TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
+                 String8(type, typeLen).string(),
+                 String8(name, nameLen).string(),
+                 String8(package, packageLen).string()));
+
+    const size_t NG = mPackageGroups.size();
+    for (size_t ig=0; ig<NG; ig++) {
+        const PackageGroup* group = mPackageGroups[ig];
+
+        if (strzcmp16(package, packageLen,
+                      group->name.string(), group->name.size())) {
+            TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen);
+        if (ti < 0) {
+            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen);
+        if (ei < 0) {
+            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
+
+        const Type* const typeConfigs = group->packages[0]->getType(ti);
+        if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
+            TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
+                               String8(group->name).string(), ti));
+        }
+        
+        size_t NTC = typeConfigs->configs.size();
+        for (size_t tci=0; tci<NTC; tci++) {
+            const ResTable_type* const ty = typeConfigs->configs[tci];
+            const uint32_t typeOffset = dtohl(ty->entriesStart);
+
+            const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
+            const uint32_t* const eindex = (const uint32_t*)
+                (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
+
+            const size_t NE = dtohl(ty->entryCount);
+            for (size_t i=0; i<NE; i++) {
+                uint32_t offset = dtohl(eindex[i]);
+                if (offset == ResTable_type::NO_ENTRY) {
+                    continue;
+                }
+                
+                offset += typeOffset;
+                
+                if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
+                    ALOGW("ResTable_entry at %d is beyond type chunk data %d",
+                         offset, dtohl(ty->header.size));
+                    return 0;
+                }
+                if ((offset&0x3) != 0) {
+                    ALOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
+                         (int)offset, (int)group->id, (int)ti+1, (int)i,
+                         String8(package, packageLen).string(),
+                         String8(type, typeLen).string(),
+                         String8(name, nameLen).string());
+                    return 0;
+                }
+                
+                const ResTable_entry* const entry = (const ResTable_entry*)
+                    (((const uint8_t*)ty) + offset);
+                if (dtohs(entry->size) < sizeof(*entry)) {
+                    ALOGW("ResTable_entry size %d is too small", dtohs(entry->size));
+                    return BAD_TYPE;
+                }
+
+                TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
+                                         i, ei, dtohl(entry->key.index)));
+                if (dtohl(entry->key.index) == (size_t)ei) {
+                    if (outTypeSpecFlags) {
+                        *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
+                        if (fakePublic) {
+                            *outTypeSpecFlags |= ResTable_typeSpec::SPEC_PUBLIC;
+                        }
+                    }
+                    return Res_MAKEID(group->id-1, ti, i);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
+                                 String16* outPackage,
+                                 String16* outType,
+                                 String16* outName,
+                                 const String16* defType,
+                                 const String16* defPackage,
+                                 const char** outErrorMsg,
+                                 bool* outPublicOnly)
+{
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* p = refStr;
+    const char16_t* const end = p + refLen;
+    while (p < end) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') {
+            typeEnd = p;
+            break;
+        }
+        p++;
+    }
+    p = refStr;
+    if (*p == '@') p++;
+
+    if (outPublicOnly != NULL) {
+        *outPublicOnly = true;
+    }
+    if (*p == '*') {
+        p++;
+        if (outPublicOnly != NULL) {
+            *outPublicOnly = false;
+        }
+    }
+
+    if (packageEnd) {
+        *outPackage = String16(p, packageEnd-p);
+        p = packageEnd+1;
+    } else {
+        if (!defPackage) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource package specified";
+            }
+            return false;
+        }
+        *outPackage = *defPackage;
+    }
+    if (typeEnd) {
+        *outType = String16(p, typeEnd-p);
+        p = typeEnd+1;
+    } else {
+        if (!defType) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource type specified";
+            }
+            return false;
+        }
+        *outType = *defType;
+    }
+    *outName = String16(p, end-p);
+    if(**outPackage == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource package cannot be an empty string";
+        }
+        return false;
+    }
+    if(**outType == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource type cannot be an empty string";
+        }
+        return false;
+    }
+    if(**outName == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource id cannot be an empty string";
+        }
+        return false;
+    }
+    return true;
+}
+
+static uint32_t get_hex(char c, bool* outError)
+{
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 0xa;
+    } else if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 0xa;
+    }
+    *outError = true;
+    return 0;
+}
+
+struct unit_entry
+{
+    const char* name;
+    size_t len;
+    uint8_t type;
+    uint32_t unit;
+    float scale;
+};
+
+static const unit_entry unitNames[] = {
+    { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
+    { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
+    { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
+    { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
+    { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
+    { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
+    { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
+    { NULL, 0, 0, 0, 0 }
+};
+
+static bool parse_unit(const char* str, Res_value* outValue,
+                       float* outScale, const char** outEnd)
+{
+    const char* end = str;
+    while (*end != 0 && !isspace((unsigned char)*end)) {
+        end++;
+    }
+    const size_t len = end-str;
+
+    const char* realEnd = end;
+    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
+        realEnd++;
+    }
+    if (*realEnd != 0) {
+        return false;
+    }
+    
+    const unit_entry* cur = unitNames;
+    while (cur->name) {
+        if (len == cur->len && strncmp(cur->name, str, len) == 0) {
+            outValue->dataType = cur->type;
+            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
+            *outScale = cur->scale;
+            *outEnd = end;
+            //printf("Found unit %s for %s\n", cur->name, str);
+            return true;
+        }
+        cur++;
+    }
+
+    return false;
+}
+
+
+bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    size_t i = 0;
+    int32_t val = 0;
+    bool neg = false;
+
+    if (*s == '-') {
+        neg = true;
+        i++;
+    }
+
+    if (s[i] < '0' || s[i] > '9') {
+        return false;
+    }
+
+    // Decimal or hex?
+    if (s[i] == '0' && s[i+1] == 'x') {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_HEX;
+        i += 2;
+        bool error = false;
+        while (i < len && !error) {
+            val = (val*16) + get_hex(s[i], &error);
+            i++;
+        }
+        if (error) {
+            return false;
+        }
+    } else {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_DEC;
+        while (i < len) {
+            if (s[i] < '0' || s[i] > '9') {
+                return false;
+            }
+            val = (val*10) + s[i]-'0';
+            i++;
+        }
+    }
+
+    if (neg) val = -val;
+
+    while (i < len && isspace16(s[i])) {
+        i++;
+    }
+
+    if (i == len) {
+        if (outValue)
+            outValue->data = val;
+        return true;
+    }
+
+    return false;
+}
+
+bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    char buf[128];
+    int i=0;
+    while (len > 0 && *s != 0 && i < 126) {
+        if (*s > 255) {
+            return false;
+        }
+        buf[i++] = *s++;
+        len--;
+    }
+
+    if (len > 0) {
+        return false;
+    }
+    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+        return false;
+    }
+
+    buf[i] = 0;
+    const char* end;
+    float f = strtof(buf, (char**)&end);
+
+    if (*end != 0 && !isspace((unsigned char)*end)) {
+        // Might be a unit...
+        float scale;
+        if (parse_unit(end, outValue, &scale, &end)) {
+            f *= scale;
+            const bool neg = f < 0;
+            if (neg) f = -f;
+            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
+            uint32_t radix;
+            uint32_t shift;
+            if ((bits&0x7fffff) == 0) {
+                // Always use 23p0 if there is no fraction, just to make
+                // things easier to read.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            } else if ((bits&0xffffffffff800000LL) == 0) {
+                // Magnitude is zero -- can fit in 0 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_0p23;
+                shift = 0;
+            } else if ((bits&0xffffffff80000000LL) == 0) {
+                // Magnitude can fit in 8 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_8p15;
+                shift = 8;
+            } else if ((bits&0xffffff8000000000LL) == 0) {
+                // Magnitude can fit in 16 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_16p7;
+                shift = 16;
+            } else {
+                // Magnitude needs entire range, so no fractional part.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            }
+            int32_t mantissa = (int32_t)(
+                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
+            if (neg) {
+                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
+            }
+            outValue->data |= 
+                (radix<<Res_value::COMPLEX_RADIX_SHIFT)
+                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
+            //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
+            //       f * (neg ? -1 : 1), bits, f*(1<<23),
+            //       radix, shift, outValue->data);
+            return true;
+        }
+        return false;
+    }
+
+    while (*end != 0 && isspace((unsigned char)*end)) {
+        end++;
+    }
+
+    if (*end == 0) {
+        if (outValue) {
+            outValue->dataType = outValue->TYPE_FLOAT;
+            *(float*)(&outValue->data) = f;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool ResTable::stringToValue(Res_value* outValue, String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces, bool coerceType,
+                             uint32_t attrID,
+                             const String16* defType,
+                             const String16* defPackage,
+                             Accessor* accessor,
+                             void* accessorCookie,
+                             uint32_t attrType,
+                             bool enforcePrivate) const
+{
+    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
+    const char* errorMsg = NULL;
+
+    outValue->size = sizeof(Res_value);
+    outValue->res0 = 0;
+
+    // First strip leading/trailing whitespace.  Do this before handling
+    // escapes, so they can be used to force whitespace into the string.
+    if (!preserveSpaces) {
+        while (len > 0 && isspace16(*s)) {
+            s++;
+            len--;
+        }
+        while (len > 0 && isspace16(s[len-1])) {
+            len--;
+        }
+        // If the string ends with '\', then we keep the space after it.
+        if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
+            len++;
+        }
+    }
+
+    //printf("Value for: %s\n", String8(s, len).string());
+
+    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
+    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
+    bool fromAccessor = false;
+    if (attrID != 0 && !Res_INTERNALID(attrID)) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
+        if (cnt >= 0) {
+            while (cnt > 0) {
+                //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
+                switch (bag->map.name.ident) {
+                case ResTable_map::ATTR_TYPE:
+                    attrType = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MIN:
+                    attrMin = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MAX:
+                    attrMax = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_L10N:
+                    l10nReq = bag->map.value.data;
+                    break;
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
+            fromAccessor = true;
+            if (attrType == ResTable_map::TYPE_ENUM
+                    || attrType == ResTable_map::TYPE_FLAGS
+                    || attrType == ResTable_map::TYPE_INTEGER) {
+                accessor->getAttributeMin(attrID, &attrMin);
+                accessor->getAttributeMax(attrID, &attrMax);
+            }
+            if (localizationSetting) {
+                l10nReq = accessor->getAttributeL10N(attrID);
+            }
+        }
+    }
+
+    const bool canStringCoerce =
+        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
+
+    if (*s == '@') {
+        outValue->dataType = outValue->TYPE_REFERENCE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+        
+        //printf("Looking up ref: %s\n", String8(s, len).string());
+
+        // It's a reference!
+        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
+            outValue->data = 0;
+            return true;
+        } else {
+            bool createIfNotFound = false;
+            const char16_t* resourceRefName;
+            int resourceNameLen;
+            if (len > 2 && s[1] == '+') {
+                createIfNotFound = true;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else if (len > 2 && s[1] == '*') {
+                enforcePrivate = false;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else {
+                createIfNotFound = false;
+                resourceRefName = s + 1;
+                resourceNameLen = len - 1;
+            }
+            String16 package, type, name;
+            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
+                                   defType, defPackage, &errorMsg)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, errorMsg);
+                }
+                return false;
+            }
+
+            uint32_t specFlags = 0;
+            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
+                    type.size(), package.string(), package.size(), &specFlags);
+            if (rid != 0) {
+                if (enforcePrivate) {
+                    if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                        if (accessor != NULL) {
+                            accessor->reportError(accessorCookie, "Resource is not public.");
+                        }
+                        return false;
+                    }
+                }
+                if (!accessor) {
+                    outValue->data = rid;
+                    return true;
+                }
+                rid = Res_MAKEID(
+                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                    Res_GETTYPE(rid), Res_GETENTRY(rid));
+                TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
+                       String8(package).string(), String8(type).string(),
+                       String8(name).string(), rid));
+                outValue->data = rid;
+                return true;
+            }
+
+            if (accessor) {
+                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
+                                                                       createIfNotFound);
+                if (rid != 0) {
+                    TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
+                           String8(package).string(), String8(type).string(),
+                           String8(name).string(), rid));
+                    outValue->data = rid;
+                    return true;
+                }
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    // if we got to here, and localization is required and it's not a reference,
+    // complain and bail.
+    if (l10nReq == ResTable_map::L10N_SUGGESTED) {
+        if (localizationSetting) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, "This attribute must be localized.");
+            }
+        }
+    }
+    
+    if (*s == '#') {
+        // It's a color!  Convert to an integer of the form 0xaarrggbb.
+        uint32_t color = 0;
+        bool error = false;
+        if (len == 4) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[1], &error) << 16;
+            color |= get_hex(s[2], &error) << 12;
+            color |= get_hex(s[2], &error) << 8;
+            color |= get_hex(s[3], &error) << 4;
+            color |= get_hex(s[3], &error);
+        } else if (len == 5) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[1], &error) << 24;
+            color |= get_hex(s[2], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[3], &error) << 8;
+            color |= get_hex(s[4], &error) << 4;
+            color |= get_hex(s[4], &error);
+        } else if (len == 7) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[4], &error) << 8;
+            color |= get_hex(s[5], &error) << 4;
+            color |= get_hex(s[6], &error);
+        } else if (len == 9) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[2], &error) << 24;
+            color |= get_hex(s[3], &error) << 20;
+            color |= get_hex(s[4], &error) << 16;
+            color |= get_hex(s[5], &error) << 12;
+            color |= get_hex(s[6], &error) << 8;
+            color |= get_hex(s[7], &error) << 4;
+            color |= get_hex(s[8], &error);
+        } else {
+            error = true;
+        }
+        if (!error) {
+            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie,
+                                "Color types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->data = color;
+                //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
+                return true;
+            }
+        } else {
+            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Color value not valid --"
+                            " must be #rgb, #argb, #rrggbb, or #aarrggbb");
+                }
+                #if 0
+                fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
+                        "Resource File", //(const char*)in->getPrintableSource(),
+                        String8(*curTag).string(),
+                        String8(s, len).string());
+                #endif
+                return false;
+            }
+        }
+    }
+
+    if (*s == '?') {
+        outValue->dataType = outValue->TYPE_ATTRIBUTE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+
+        //printf("Looking up attr: %s\n", String8(s, len).string());
+
+        static const String16 attr16("attr");
+        String16 package, type, name;
+        if (!expandResourceRef(s+1, len-1, &package, &type, &name,
+                               &attr16, defPackage, &errorMsg)) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, errorMsg);
+            }
+            return false;
+        }
+
+        //printf("Pkg: %s, Type: %s, Name: %s\n",
+        //       String8(package).string(), String8(type).string(),
+        //       String8(name).string());
+        uint32_t specFlags = 0;
+        uint32_t rid = 
+            identifierForName(name.string(), name.size(),
+                              type.string(), type.size(),
+                              package.string(), package.size(), &specFlags);
+        if (rid != 0) {
+            if (enforcePrivate) {
+                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Attribute is not public.");
+                    }
+                    return false;
+                }
+            }
+            if (!accessor) {
+                outValue->data = rid;
+                return true;
+            }
+            rid = Res_MAKEID(
+                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                Res_GETTYPE(rid), Res_GETENTRY(rid));
+            //printf("Incl %s:%s/%s: 0x%08x\n",
+            //       String8(package).string(), String8(type).string(),
+            //       String8(name).string(), rid);
+            outValue->data = rid;
+            return true;
+        }
+
+        if (accessor) {
+            uint32_t rid = accessor->getCustomResource(package, type, name);
+            if (rid != 0) {
+                //printf("Mine %s:%s/%s: 0x%08x\n",
+                //       String8(package).string(), String8(type).string(),
+                //       String8(name).string(), rid);
+                outValue->data = rid;
+                return true;
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    if (stringToInt(s, len, outValue)) {
+        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
+            // If this type does not allow integers, but does allow floats,
+            // fall through on this error case because the float type should
+            // be able to accept any integer value.
+            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer types not allowed");
+                }
+                return false;
+            }
+        } else {
+            if (((int32_t)outValue->data) < ((int32_t)attrMin)
+                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer value out of range");
+                }
+                return false;
+            }
+            return true;
+        }
+    }
+
+    if (stringToFloat(s, len, outValue)) {
+        if (outValue->dataType == Res_value::TYPE_DIMENSION) {
+            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Dimension types not allowed");
+                }
+                return false;
+            }
+        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
+            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Fraction types not allowed");
+                }
+                return false;
+            }
+        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Float types not allowed");
+                }
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    if (len == 4) {
+        if ((s[0] == 't' || s[0] == 'T') &&
+            (s[1] == 'r' || s[1] == 'R') &&
+            (s[2] == 'u' || s[2] == 'U') &&
+            (s[3] == 'e' || s[3] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = (uint32_t)-1;
+                return true;
+            }
+        }
+    }
+
+    if (len == 5) {
+        if ((s[0] == 'f' || s[0] == 'F') &&
+            (s[1] == 'a' || s[1] == 'A') &&
+            (s[2] == 'l' || s[2] == 'L') &&
+            (s[3] == 's' || s[3] == 'S') &&
+            (s[4] == 'e' || s[4] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = 0;
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for enum\n", cnt);
+        if (cnt >= 0) {
+            resource_name rname;
+            while (cnt > 0) {
+                if (!Res_INTERNALID(bag->map.name.ident)) {
+                    //printf("Trying attr #%08x\n", bag->map.name.ident);
+                    if (getResourceName(bag->map.name.ident, false, &rname)) {
+                        #if 0
+                        printf("Matching %s against %s (0x%08x)\n",
+                               String8(s, len).string(),
+                               String8(rname.name, rname.nameLen).string(),
+                               bag->map.name.ident);
+                        #endif
+                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
+                            outValue->dataType = bag->map.value.dataType;
+                            outValue->data = bag->map.value.data;
+                            unlockBag(bag);
+                            return true;
+                        }
+                    }
+    
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        }
+
+        if (fromAccessor) {
+            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for flags\n", cnt);
+        if (cnt >= 0) {
+            bool failed = false;
+            resource_name rname;
+            outValue->dataType = Res_value::TYPE_INT_HEX;
+            outValue->data = 0;
+            const char16_t* end = s + len;
+            const char16_t* pos = s;
+            while (pos < end && !failed) {
+                const char16_t* start = pos;
+                pos++;
+                while (pos < end && *pos != '|') {
+                    pos++;
+                }
+                //printf("Looking for: %s\n", String8(start, pos-start).string());
+                const bag_entry* bagi = bag;
+                ssize_t i;
+                for (i=0; i<cnt; i++, bagi++) {
+                    if (!Res_INTERNALID(bagi->map.name.ident)) {
+                        //printf("Trying attr #%08x\n", bagi->map.name.ident);
+                        if (getResourceName(bagi->map.name.ident, false, &rname)) {
+                            #if 0
+                            printf("Matching %s against %s (0x%08x)\n",
+                                   String8(start,pos-start).string(),
+                                   String8(rname.name, rname.nameLen).string(),
+                                   bagi->map.name.ident);
+                            #endif
+                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
+                                outValue->data |= bagi->map.value.data;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (i >= cnt) {
+                    // Didn't find this flag identifier.
+                    failed = true;
+                }
+                if (pos < end) {
+                    pos++;
+                }
+            }
+            unlockBag(bag);
+            if (!failed) {
+                //printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+
+
+        if (fromAccessor) {
+            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
+                //printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_STRING) == 0) {
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "String types not allowed");
+        }
+        return false;
+    }
+
+    // Generic string handling...
+    outValue->dataType = outValue->TYPE_STRING;
+    if (outString) {
+        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, errorMsg);
+        }
+        return failed;
+    }
+
+    return true;
+}
+
+bool ResTable::collectString(String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces,
+                             const char** outErrorMsg,
+                             bool append)
+{
+    String16 tmp;
+
+    char quoted = 0;
+    const char16_t* p = s;
+    while (p < (s+len)) {
+        while (p < (s+len)) {
+            const char16_t c = *p;
+            if (c == '\\') {
+                break;
+            }
+            if (!preserveSpaces) {
+                if (quoted == 0 && isspace16(c)
+                    && (c != ' ' || isspace16(*(p+1)))) {
+                    break;
+                }
+                if (c == '"' && (quoted == 0 || quoted == '"')) {
+                    break;
+                }
+                if (c == '\'' && (quoted == 0 || quoted == '\'')) {
+                    /*
+                     * In practice, when people write ' instead of \'
+                     * in a string, they are doing it by accident
+                     * instead of really meaning to use ' as a quoting
+                     * character.  Warn them so they don't lose it.
+                     */
+                    if (outErrorMsg) {
+                        *outErrorMsg = "Apostrophe not preceded by \\";
+                    }
+                    return false;
+                }
+            }
+            p++;
+        }
+        if (p < (s+len)) {
+            if (p > s) {
+                tmp.append(String16(s, p-s));
+            }
+            if (!preserveSpaces && (*p == '"' || *p == '\'')) {
+                if (quoted == 0) {
+                    quoted = *p;
+                } else {
+                    quoted = 0;
+                }
+                p++;
+            } else if (!preserveSpaces && isspace16(*p)) {
+                // Space outside of a quote -- consume all spaces and
+                // leave a single plain space char.
+                tmp.append(String16(" "));
+                p++;
+                while (p < (s+len) && isspace16(*p)) {
+                    p++;
+                }
+            } else if (*p == '\\') {
+                p++;
+                if (p < (s+len)) {
+                    switch (*p) {
+                    case 't':
+                        tmp.append(String16("\t"));
+                        break;
+                    case 'n':
+                        tmp.append(String16("\n"));
+                        break;
+                    case '#':
+                        tmp.append(String16("#"));
+                        break;
+                    case '@':
+                        tmp.append(String16("@"));
+                        break;
+                    case '?':
+                        tmp.append(String16("?"));
+                        break;
+                    case '"':
+                        tmp.append(String16("\""));
+                        break;
+                    case '\'':
+                        tmp.append(String16("'"));
+                        break;
+                    case '\\':
+                        tmp.append(String16("\\"));
+                        break;
+                    case 'u':
+                    {
+                        char16_t chr = 0;
+                        int i = 0;
+                        while (i < 4 && p[1] != 0) {
+                            p++;
+                            i++;
+                            int c;
+                            if (*p >= '0' && *p <= '9') {
+                                c = *p - '0';
+                            } else if (*p >= 'a' && *p <= 'f') {
+                                c = *p - 'a' + 10;
+                            } else if (*p >= 'A' && *p <= 'F') {
+                                c = *p - 'A' + 10;
+                            } else {
+                                if (outErrorMsg) {
+                                    *outErrorMsg = "Bad character in \\u unicode escape sequence";
+                                }
+                                return false;
+                            }
+                            chr = (chr<<4) | c;
+                        }
+                        tmp.append(String16(&chr, 1));
+                    } break;
+                    default:
+                        // ignore unknown escape chars.
+                        break;
+                    }
+                    p++;
+                }
+            }
+            len -= (p-s);
+            s = p;
+        }
+    }
+
+    if (tmp.size() != 0) {
+        if (len > 0) {
+            tmp.append(String16(s, len));
+        }
+        if (append) {
+            outString->append(tmp);
+        } else {
+            outString->setTo(tmp);
+        }
+    } else {
+        if (append) {
+            outString->append(String16(s, len));
+        } else {
+            outString->setTo(s, len);
+        }
+    }
+
+    return true;
+}
+
+size_t ResTable::getBasePackageCount() const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    return mPackageGroups.size();
+}
+
+const char16_t* ResTable::getBasePackageName(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->name.string();
+}
+
+uint32_t ResTable::getBasePackageId(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->id;
+}
+
+size_t ResTable::getTableCount() const
+{
+    return mHeaders.size();
+}
+
+const ResStringPool* ResTable::getTableStringBlock(size_t index) const
+{
+    return &mHeaders[index]->values;
+}
+
+void* ResTable::getTableCookie(size_t index) const
+{
+    return mHeaders[index]->cookie;
+}
+
+void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
+{
+    const size_t I = mPackageGroups.size();
+    for (size_t i=0; i<I; i++) {
+        const PackageGroup* packageGroup = mPackageGroups[i];
+        const size_t J = packageGroup->packages.size();
+        for (size_t j=0; j<J; j++) {
+            const Package* package = packageGroup->packages[j];
+            const size_t K = package->types.size();
+            for (size_t k=0; k<K; k++) {
+                const Type* type = package->types[k];
+                if (type == NULL) continue;
+                const size_t L = type->configs.size();
+                for (size_t l=0; l<L; l++) {
+                    const ResTable_type* config = type->configs[l];
+                    const ResTable_config* cfg = &config->config;
+                    // only insert unique
+                    const size_t M = configs->size();
+                    size_t m;
+                    for (m=0; m<M; m++) {
+                        if (0 == (*configs)[m].compare(*cfg)) {
+                            break;
+                        }
+                    }
+                    // if we didn't find it
+                    if (m == M) {
+                        configs->add(*cfg);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void ResTable::getLocales(Vector<String8>* locales) const
+{
+    Vector<ResTable_config> configs;
+    ALOGV("calling getConfigurations");
+    getConfigurations(&configs);
+    ALOGV("called getConfigurations size=%d", (int)configs.size());
+    const size_t I = configs.size();
+    for (size_t i=0; i<I; i++) {
+        char locale[6];
+        configs[i].getLocale(locale);
+        const size_t J = locales->size();
+        size_t j;
+        for (j=0; j<J; j++) {
+            if (0 == strcmp(locale, (*locales)[j].string())) {
+                break;
+            }
+        }
+        if (j == J) {
+            locales->add(String8(locale));
+        }
+    }
+}
+
+ssize_t ResTable::getEntry(
+    const Package* package, int typeIndex, int entryIndex,
+    const ResTable_config* config,
+    const ResTable_type** outType, const ResTable_entry** outEntry,
+    const Type** outTypeClass) const
+{
+    ALOGV("Getting entry from package %p\n", package);
+    const ResTable_package* const pkg = package->package;
+
+    const Type* allTypes = package->getType(typeIndex);
+    ALOGV("allTypes=%p\n", allTypes);
+    if (allTypes == NULL) {
+        ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
+        return 0;
+    }
+
+    if ((size_t)entryIndex >= allTypes->entryCount) {
+        ALOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
+            entryIndex, (int)allTypes->entryCount);
+        return BAD_TYPE;
+    }
+        
+    const ResTable_type* type = NULL;
+    uint32_t offset = ResTable_type::NO_ENTRY;
+    ResTable_config bestConfig;
+    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
+    
+    const size_t NT = allTypes->configs.size();
+    for (size_t i=0; i<NT; i++) {
+        const ResTable_type* const thisType = allTypes->configs[i];
+        if (thisType == NULL) continue;
+        
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(thisType->config);
+
+        TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
+                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
+                           thisConfig.toString().string()));
+        
+        // Check to make sure this one is valid for the current parameters.
+        if (config && !thisConfig.match(*config)) {
+            TABLE_GETENTRY(ALOGI("Does not match config!\n"));
+            continue;
+        }
+        
+        // Check if there is the desired entry in this type.
+        
+        const uint8_t* const end = ((const uint8_t*)thisType)
+            + dtohl(thisType->header.size);
+        const uint32_t* const eindex = (const uint32_t*)
+            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
+        
+        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+        if (thisOffset == ResTable_type::NO_ENTRY) {
+            TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));
+            continue;
+        }
+        
+        if (type != NULL) {
+            // Check if this one is less specific than the last found.  If so,
+            // we will skip it.  We check starting with things we most care
+            // about to those we least care about.
+            if (!thisConfig.isBetterThan(bestConfig, config)) {
+                TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));
+                continue;
+            }
+        }
+        
+        type = thisType;
+        offset = thisOffset;
+        bestConfig = thisConfig;
+        TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
+        if (!config) break;
+    }
+    
+    if (type == NULL) {
+        TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));
+        return BAD_INDEX;
+    }
+    
+    offset += dtohl(type->entriesStart);
+    TABLE_NOISY(aout << "Looking in resource table " << package->header->header
+          << ", typeOff="
+          << (void*)(((const char*)type)-((const char*)package->header->header))
+          << ", offset=" << (void*)offset << endl);
+
+    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
+        ALOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
+             offset, dtohl(type->header.size));
+        return BAD_TYPE;
+    }
+    if ((offset&0x3) != 0) {
+        ALOGW("ResTable_entry at 0x%x is not on an integer boundary",
+             offset);
+        return BAD_TYPE;
+    }
+
+    const ResTable_entry* const entry = (const ResTable_entry*)
+        (((const uint8_t*)type) + offset);
+    if (dtohs(entry->size) < sizeof(*entry)) {
+        ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
+        return BAD_TYPE;
+    }
+
+    *outType = type;
+    *outEntry = entry;
+    if (outTypeClass != NULL) {
+        *outTypeClass = allTypes;
+    }
+    return offset + dtohs(entry->size);
+}
+
+status_t ResTable::parsePackage(const ResTable_package* const pkg,
+                                const Header* const header, uint32_t idmap_id)
+{
+    const uint8_t* base = (const uint8_t*)pkg;
+    status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
+                                  header->dataEnd, "ResTable_package");
+    if (err != NO_ERROR) {
+        return (mError=err);
+    }
+
+    const size_t pkgSize = dtohl(pkg->header.size);
+
+    if (dtohl(pkg->typeStrings) >= pkgSize) {
+        ALOGW("ResTable_package type strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->typeStrings)&0x3) != 0) {
+        ALOGW("ResTable_package type strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->typeStrings));
+        return (mError=BAD_TYPE);
+    }
+    if (dtohl(pkg->keyStrings) >= pkgSize) {
+        ALOGW("ResTable_package key strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->keyStrings)&0x3) != 0) {
+        ALOGW("ResTable_package key strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->keyStrings));
+        return (mError=BAD_TYPE);
+    }
+    
+    Package* package = NULL;
+    PackageGroup* group = NULL;
+    uint32_t id = idmap_id != 0 ? idmap_id : dtohl(pkg->id);
+    // If at this point id == 0, pkg is an overlay package without a
+    // corresponding idmap. During regular usage, overlay packages are
+    // always loaded alongside their idmaps, but during idmap creation
+    // the package is temporarily loaded by itself.
+    if (id < 256) {
+    
+        package = new Package(this, header, pkg);
+        if (package == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        
+        size_t idx = mPackageMap[id];
+        if (idx == 0) {
+            idx = mPackageGroups.size()+1;
+
+            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
+            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
+            group = new PackageGroup(this, String16(tmpName), id);
+            if (group == NULL) {
+                delete package;
+                return (mError=NO_MEMORY);
+            }
+
+            err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),
+                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
+            if (err != NO_ERROR) {
+                delete group;
+                delete package;
+                return (mError=err);
+            }
+            err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),
+                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
+            if (err != NO_ERROR) {
+                delete group;
+                delete package;
+                return (mError=err);
+            }
+
+            //printf("Adding new package id %d at index %d\n", id, idx);
+            err = mPackageGroups.add(group);
+            if (err < NO_ERROR) {
+                return (mError=err);
+            }
+            group->basePackage = package;
+            
+            mPackageMap[id] = (uint8_t)idx;
+        } else {
+            group = mPackageGroups.itemAt(idx-1);
+            if (group == NULL) {
+                return (mError=UNKNOWN_ERROR);
+            }
+        }
+        err = group->packages.add(package);
+        if (err < NO_ERROR) {
+            return (mError=err);
+        }
+    } else {
+        LOG_ALWAYS_FATAL("Package id out of range");
+        return NO_ERROR;
+    }
+
+    
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+    
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)pkg)
+                                 + dtohs(pkg->header.headerSize));
+    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
+    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
+        TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
+            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
+            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
+                                 endPos, "ResTable_typeSpec");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSpecSize = dtohl(typeSpec->header.size);
+            
+            LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(typeSpec->header.type),
+                                    dtohs(typeSpec->header.headerSize),
+                                    (void*)typeSize));
+            // look for block overrun or int overflow when multiplying by 4
+            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
+                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
+                    > typeSpecSize)) {
+                ALOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(typeSpec->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
+                     (void*)typeSpecSize);
+                return (mError=BAD_TYPE);
+            }
+            
+            if (typeSpec->id == 0) {
+                ALOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < typeSpec->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[typeSpec->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(typeSpec->entryCount));
+                package->types.editItemAt(typeSpec->id-1) = t;
+            } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
+                ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            t->typeSpecFlags = (const uint32_t*)(
+                    ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
+            t->typeSpec = typeSpec;
+            
+        } else if (ctype == RES_TABLE_TYPE_TYPE) {
+            const ResTable_type* type = (const ResTable_type*)(chunk);
+            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
+                                 endPos, "ResTable_type");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSize = dtohl(type->header.size);
+            
+            LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(type->header.type),
+                                    dtohs(type->header.headerSize),
+                                    (void*)typeSize));
+            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
+                > typeSize) {
+                ALOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(type->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(type->entryCount))),
+                     (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (dtohl(type->entryCount) != 0
+                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
+                ALOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
+                     (void*)dtohl(type->entriesStart), (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (type->id == 0) {
+                ALOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < type->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[type->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(type->entryCount));
+                package->types.editItemAt(type->id-1) = t;
+            } else if (dtohl(type->entryCount) != t->entryCount) {
+                ALOGW("ResTable_type entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(type->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            
+            TABLE_GETENTRY(
+                ResTable_config thisConfig;
+                thisConfig.copyFromDtoH(type->config);
+                ALOGI("Adding config to type %d: %s\n",
+                      type->id, thisConfig.toString().string()));
+            t->configs.add(type);
+        } else {
+            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
+                                          endPos, "ResTable_package:unknown");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (group->typeCount == 0) {
+        group->typeCount = package->types.size();
+    }
+    
+    return NO_ERROR;
+}
+
+status_t ResTable::createIdmap(const ResTable& overlay, uint32_t originalCrc, uint32_t overlayCrc,
+                               void** outData, size_t* outSize) const
+{
+    // see README for details on the format of map
+    if (mPackageGroups.size() == 0) {
+        return UNKNOWN_ERROR;
+    }
+    if (mPackageGroups[0]->packages.size() == 0) {
+        return UNKNOWN_ERROR;
+    }
+
+    Vector<Vector<uint32_t> > map;
+    const PackageGroup* pg = mPackageGroups[0];
+    const Package* pkg = pg->packages[0];
+    size_t typeCount = pkg->types.size();
+    // starting size is header + first item (number of types in map)
+    *outSize = (IDMAP_HEADER_SIZE + 1) * sizeof(uint32_t);
+    const String16 overlayPackage(overlay.mPackageGroups[0]->packages[0]->package->name);
+    const uint32_t pkg_id = pkg->package->id << 24;
+
+    for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
+        ssize_t first = -1;
+        ssize_t last = -1;
+        const Type* typeConfigs = pkg->getType(typeIndex);
+        ssize_t mapIndex = map.add();
+        if (mapIndex < 0) {
+            return NO_MEMORY;
+        }
+        Vector<uint32_t>& vector = map.editItemAt(mapIndex);
+        for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
+            uint32_t resID = pkg_id
+                | (0x00ff0000 & ((typeIndex+1)<<16))
+                | (0x0000ffff & (entryIndex));
+            resource_name resName;
+            if (!this->getResourceName(resID, true, &resName)) {
+                ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
+                // add dummy value, or trimming leading/trailing zeroes later will fail
+                vector.push(0);
+                continue;
+            }
+
+            const String16 overlayType(resName.type, resName.typeLen);
+            const String16 overlayName(resName.name, resName.nameLen);
+            uint32_t overlayResID = overlay.identifierForName(overlayName.string(),
+                                                              overlayName.size(),
+                                                              overlayType.string(),
+                                                              overlayType.size(),
+                                                              overlayPackage.string(),
+                                                              overlayPackage.size());
+            if (overlayResID != 0) {
+                overlayResID = pkg_id | (0x00ffffff & overlayResID);
+                last = Res_GETENTRY(resID);
+                if (first == -1) {
+                    first = Res_GETENTRY(resID);
+                }
+            }
+            vector.push(overlayResID);
+#if 0
+            if (overlayResID != 0) {
+                ALOGD("%s/%s 0x%08x -> 0x%08x\n",
+                     String8(String16(resName.type)).string(),
+                     String8(String16(resName.name)).string(),
+                     resID, overlayResID);
+            }
+#endif
+        }
+
+        if (first != -1) {
+            // shave off trailing entries which lack overlay values
+            const size_t last_past_one = last + 1;
+            if (last_past_one < vector.size()) {
+                vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
+            }
+            // shave off leading entries which lack overlay values
+            vector.removeItemsAt(0, first);
+            // store offset to first overlaid resource ID of this type
+            vector.insertAt((uint32_t)first, 0, 1);
+            // reserve space for number and offset of entries, and the actual entries
+            *outSize += (2 + vector.size()) * sizeof(uint32_t);
+        } else {
+            // no entries of current type defined in overlay package
+            vector.clear();
+            // reserve space for type offset
+            *outSize += 1 * sizeof(uint32_t);
+        }
+    }
+
+    if ((*outData = malloc(*outSize)) == NULL) {
+        return NO_MEMORY;
+    }
+    uint32_t* data = (uint32_t*)*outData;
+    *data++ = htodl(IDMAP_MAGIC);
+    *data++ = htodl(originalCrc);
+    *data++ = htodl(overlayCrc);
+    const size_t mapSize = map.size();
+    *data++ = htodl(mapSize);
+    size_t offset = mapSize;
+    for (size_t i = 0; i < mapSize; ++i) {
+        const Vector<uint32_t>& vector = map.itemAt(i);
+        const size_t N = vector.size();
+        if (N == 0) {
+            *data++ = htodl(0);
+        } else {
+            offset++;
+            *data++ = htodl(offset);
+            offset += N;
+        }
+    }
+    for (size_t i = 0; i < mapSize; ++i) {
+        const Vector<uint32_t>& vector = map.itemAt(i);
+        const size_t N = vector.size();
+        if (N == 0) {
+            continue;
+        }
+        if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
+            ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
+            return UNKNOWN_ERROR;
+        }
+        *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
+        for (size_t j = 0; j < N; ++j) {
+            const uint32_t& overlayResID = vector.itemAt(j);
+            *data++ = htodl(overlayResID);
+        }
+    }
+
+    return NO_ERROR;
+}
+
+bool ResTable::getIdmapInfo(const void* idmap, size_t sizeBytes,
+                            uint32_t* pOriginalCrc, uint32_t* pOverlayCrc)
+{
+    const uint32_t* map = (const uint32_t*)idmap;
+    if (!assertIdmapHeader(map, sizeBytes)) {
+        return false;
+    }
+    *pOriginalCrc = map[1];
+    *pOverlayCrc = map[2];
+    return true;
+}
+
+
+#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
+
+#define CHAR16_ARRAY_EQ(constant, var, len) \
+        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
+
+static void print_complex(uint32_t complex, bool isFraction)
+{
+    const float MANTISSA_MULT =
+        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
+    const float RADIX_MULTS[] = {
+        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
+        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
+    };
+
+    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK
+                   <<Res_value::COMPLEX_MANTISSA_SHIFT))
+            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)
+                            & Res_value::COMPLEX_RADIX_MASK];
+    printf("%f", value);
+    
+    if (!isFraction) {
+        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
+            case Res_value::COMPLEX_UNIT_PX: printf("px"); break;
+            case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break;
+            case Res_value::COMPLEX_UNIT_SP: printf("sp"); break;
+            case Res_value::COMPLEX_UNIT_PT: printf("pt"); break;
+            case Res_value::COMPLEX_UNIT_IN: printf("in"); break;
+            case Res_value::COMPLEX_UNIT_MM: printf("mm"); break;
+            default: printf(" (unknown unit)"); break;
+        }
+    } else {
+        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
+            case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break;
+            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break;
+            default: printf(" (unknown unit)"); break;
+        }
+    }
+}
+
+// Normalize a string for output
+String8 ResTable::normalizeForOutput( const char *input )
+{
+    String8 ret;
+    char buff[2];
+    buff[1] = '\0';
+
+    while (*input != '\0') {
+        switch (*input) {
+            // All interesting characters are in the ASCII zone, so we are making our own lives
+            // easier by scanning the string one byte at a time.
+        case '\\':
+            ret += "\\\\";
+            break;
+        case '\n':
+            ret += "\\n";
+            break;
+        case '"':
+            ret += "\\\"";
+            break;
+        default:
+            buff[0] = *input;
+            ret += buff;
+            break;
+        }
+
+        input++;
+    }
+
+    return ret;
+}
+
+void ResTable::print_value(const Package* pkg, const Res_value& value) const
+{
+    if (value.dataType == Res_value::TYPE_NULL) {
+        printf("(null)\n");
+    } else if (value.dataType == Res_value::TYPE_REFERENCE) {
+        printf("(reference) 0x%08x\n", value.data);
+    } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
+        printf("(attribute) 0x%08x\n", value.data);
+    } else if (value.dataType == Res_value::TYPE_STRING) {
+        size_t len;
+        const char* str8 = pkg->header->values.string8At(
+                value.data, &len);
+        if (str8 != NULL) {
+            printf("(string8) \"%s\"\n", normalizeForOutput(str8).string());
+        } else {
+            const char16_t* str16 = pkg->header->values.stringAt(
+                    value.data, &len);
+            if (str16 != NULL) {
+                printf("(string16) \"%s\"\n",
+                    normalizeForOutput(String8(str16, len).string()).string());
+            } else {
+                printf("(string) null\n");
+            }
+        } 
+    } else if (value.dataType == Res_value::TYPE_FLOAT) {
+        printf("(float) %g\n", *(const float*)&value.data);
+    } else if (value.dataType == Res_value::TYPE_DIMENSION) {
+        printf("(dimension) ");
+        print_complex(value.data, false);
+        printf("\n");
+    } else if (value.dataType == Res_value::TYPE_FRACTION) {
+        printf("(fraction) ");
+        print_complex(value.data, true);
+        printf("\n");
+    } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT
+            || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
+        printf("(color) #%08x\n", value.data);
+    } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {
+        printf("(boolean) %s\n", value.data ? "true" : "false");
+    } else if (value.dataType >= Res_value::TYPE_FIRST_INT
+            || value.dataType <= Res_value::TYPE_LAST_INT) {
+        printf("(int) 0x%08x or %d\n", value.data, value.data);
+    } else {
+        printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n",
+               (int)value.dataType, (int)value.data,
+               (int)value.size, (int)value.res0);
+    }
+}
+
+void ResTable::print(bool inclValues) const
+{
+    if (mError != 0) {
+        printf("mError=0x%x (%s)\n", mError, strerror(mError));
+    }
+#if 0
+    printf("mParams=%c%c-%c%c,\n",
+            mParams.language[0], mParams.language[1],
+            mParams.country[0], mParams.country[1]);
+#endif
+    size_t pgCount = mPackageGroups.size();
+    printf("Package Groups (%d)\n", (int)pgCount);
+    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
+        const PackageGroup* pg = mPackageGroups[pgIndex];
+        printf("Package Group %d id=%d packageCount=%d name=%s\n",
+                (int)pgIndex, pg->id, (int)pg->packages.size(),
+                String8(pg->name).string());
+        
+        size_t pkgCount = pg->packages.size();
+        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
+            const Package* pkg = pg->packages[pkgIndex];
+            size_t typeCount = pkg->types.size();
+            printf("  Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
+                    pkg->package->id, String8(String16(pkg->package->name)).string(),
+                    (int)typeCount);
+            for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
+                const Type* typeConfigs = pkg->getType(typeIndex);
+                if (typeConfigs == NULL) {
+                    printf("    type %d NULL\n", (int)typeIndex);
+                    continue;
+                }
+                const size_t NTC = typeConfigs->configs.size();
+                printf("    type %d configCount=%d entryCount=%d\n",
+                       (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
+                if (typeConfigs->typeSpecFlags != NULL) {
+                    for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        if (this->getResourceName(resID, true, &resName)) {
+                            String8 type8;
+                            String8 name8;
+                            if (resName.type8 != NULL) {
+                                type8 = String8(resName.type8, resName.typeLen);
+                            } else {
+                                type8 = String8(resName.type, resName.typeLen);
+                            }
+                            if (resName.name8 != NULL) {
+                                name8 = String8(resName.name8, resName.nameLen);
+                            } else {
+                                name8 = String8(resName.name, resName.nameLen);
+                            }
+                            printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
+                                resID,
+                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                type8.string(), name8.string(),
+                                dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                        } else {
+                            printf("      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
+                        }
+                    }
+                }
+                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
+                    const ResTable_type* type = typeConfigs->configs[configIndex];
+                    if ((((uint64_t)type)&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
+                        continue;
+                    }
+                    String8 configStr = type->config.toString();
+                    printf("      config %s:\n", configStr.size() > 0
+                            ? configStr.string() : "(default)");
+                    size_t entryCount = dtohl(type->entryCount);
+                    uint32_t entriesStart = dtohl(type->entriesStart);
+                    if ((entriesStart&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
+                        continue;
+                    }
+                    uint32_t typeSize = dtohl(type->header.size);
+                    if ((typeSize&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
+                        continue;
+                    }
+                    for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
+                        
+                        const uint8_t* const end = ((const uint8_t*)type)
+                            + dtohl(type->header.size);
+                        const uint32_t* const eindex = (const uint32_t*)
+                            (((const uint8_t*)type) + dtohs(type->header.headerSize));
+                        
+                        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+                        if (thisOffset == ResTable_type::NO_ENTRY) {
+                            continue;
+                        }
+                        
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        if (this->getResourceName(resID, true, &resName)) {
+                            String8 type8;
+                            String8 name8;
+                            if (resName.type8 != NULL) {
+                                type8 = String8(resName.type8, resName.typeLen);
+                            } else {
+                                type8 = String8(resName.type, resName.typeLen);
+                            }
+                            if (resName.name8 != NULL) {
+                                name8 = String8(resName.name8, resName.nameLen);
+                            } else {
+                                name8 = String8(resName.name, resName.nameLen);
+                            }
+                            printf("        resource 0x%08x %s:%s/%s: ", resID,
+                                    CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                    type8.string(), name8.string());
+                        } else {
+                            printf("        INVALID RESOURCE 0x%08x: ", resID);
+                        }
+                        if ((thisOffset&0x3) != 0) {
+                            printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
+                            continue;
+                        }
+                        if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
+                            printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
+                                   (void*)entriesStart, (void*)thisOffset,
+                                   (void*)typeSize);
+                            continue;
+                        }
+                        
+                        const ResTable_entry* ent = (const ResTable_entry*)
+                            (((const uint8_t*)type) + entriesStart + thisOffset);
+                        if (((entriesStart + thisOffset)&0x3) != 0) {
+                            printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
+                                 (void*)(entriesStart + thisOffset));
+                            continue;
+                        }
+                        
+                        uint16_t esize = dtohs(ent->size);
+                        if ((esize&0x3) != 0) {
+                            printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
+                            continue;
+                        }
+                        if ((thisOffset+esize) > typeSize) {
+                            printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
+                                   (void*)entriesStart, (void*)thisOffset,
+                                   (void*)esize, (void*)typeSize);
+                            continue;
+                        }
+                            
+                        const Res_value* valuePtr = NULL;
+                        const ResTable_map_entry* bagPtr = NULL;
+                        Res_value value;
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
+                            printf("<bag>");
+                            bagPtr = (const ResTable_map_entry*)ent;
+                        } else {
+                            valuePtr = (const Res_value*)
+                                (((const uint8_t*)ent) + esize);
+                            value.copyFrom_dtoh(*valuePtr);
+                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
+                                   (int)value.dataType, (int)value.data,
+                                   (int)value.size, (int)value.res0);
+                        }
+                        
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
+                            printf(" (PUBLIC)");
+                        }
+                        printf("\n");
+                        
+                        if (inclValues) {
+                            if (valuePtr != NULL) {
+                                printf("          ");
+                                print_value(pkg, value);
+                            } else if (bagPtr != NULL) {
+                                const int N = dtohl(bagPtr->count);
+                                const uint8_t* baseMapPtr = (const uint8_t*)ent;
+                                size_t mapOffset = esize;
+                                const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
+                                printf("          Parent=0x%08x, Count=%d\n",
+                                    dtohl(bagPtr->parent.ident), N);
+                                for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {
+                                    printf("          #%i (Key=0x%08x): ",
+                                        i, dtohl(mapPtr->name.ident));
+                                    value.copyFrom_dtoh(mapPtr->value);
+                                    print_value(pkg, value);
+                                    const size_t size = dtohs(mapPtr->value.size);
+                                    mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);
+                                    mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+}   // namespace android
diff --git a/libs/androidfw/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp
new file mode 100644
index 0000000..1dfec23
--- /dev/null
+++ b/libs/androidfw/StreamingZipInflater.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "szipinf"
+#include <utils/Log.h>
+
+#include <androidfw/StreamingZipInflater.h>
+#include <utils/FileMap.h>
+#include <string.h>
+#include <stddef.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
+
+using namespace android;
+
+/*
+ * Streaming access to compressed asset data in an open fd
+ */
+StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
+        size_t uncompSize, size_t compSize) {
+    mFd = fd;
+    mDataMap = NULL;
+    mInFileStart = compDataStart;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = compSize;
+
+    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
+    mInBuf = new uint8_t[mInBufSize];
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+/*
+ * Streaming access to compressed data held in an mmapped region of memory
+ */
+StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
+    mFd = -1;
+    mDataMap = dataMap;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = dataMap->getDataLength();
+
+    mInBuf = (uint8_t*) dataMap->getDataPtr();
+    mInBufSize = mInTotalSize;
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+StreamingZipInflater::~StreamingZipInflater() {
+    // tear down the in-flight zip state just in case
+    ::inflateEnd(&mInflateState);
+
+    if (mDataMap == NULL) {
+        delete [] mInBuf;
+    }
+    delete [] mOutBuf;
+}
+
+void StreamingZipInflater::initInflateState() {
+    ALOGV("Initializing inflate state");
+
+    memset(&mInflateState, 0, sizeof(mInflateState));
+    mInflateState.zalloc = Z_NULL;
+    mInflateState.zfree = Z_NULL;
+    mInflateState.opaque = Z_NULL;
+    mInflateState.next_in = (Bytef*)mInBuf;
+    mInflateState.next_out = (Bytef*) mOutBuf;
+    mInflateState.avail_out = mOutBufSize;
+    mInflateState.data_type = Z_UNKNOWN;
+
+    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
+    mInNextChunkOffset = 0;
+    mStreamNeedsInit = true;
+
+    if (mDataMap == NULL) {
+        ::lseek(mFd, mInFileStart, SEEK_SET);
+        mInflateState.avail_in = 0; // set when a chunk is read in
+    } else {
+        mInflateState.avail_in = mInBufSize;
+    }
+}
+
+/*
+ * Basic approach:
+ *
+ * 1. If we have undelivered uncompressed data, send it.  At this point
+ *    either we've satisfied the request, or we've exhausted the available
+ *    output data in mOutBuf.
+ *
+ * 2. While we haven't sent enough data to satisfy the request:
+ *    0. if the request is for more data than exists, bail.
+ *    a. if there is no input data to decode, read some into the input buffer
+ *       and readjust the z_stream input pointers
+ *    b. point the output to the start of the output buffer and decode what we can
+ *    c. deliver whatever output data we can
+ */
+ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
+    uint8_t* dest = (uint8_t*) outBuf;
+    size_t bytesRead = 0;
+    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
+    while (toRead > 0) {
+        // First, write from whatever we already have decoded and ready to go
+        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
+        if (deliverable > 0) {
+            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
+            mOutDeliverable += deliverable;
+            mOutCurPosition += deliverable;
+            dest += deliverable;
+            bytesRead += deliverable;
+            toRead -= deliverable;
+        }
+
+        // need more data?  time to decode some.
+        if (toRead > 0) {
+            // if we don't have any data to decode, read some in.  If we're working
+            // from mmapped data this won't happen, because the clipping to total size
+            // will prevent reading off the end of the mapped input chunk.
+            if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) {
+                int err = readNextChunk();
+                if (err < 0) {
+                    ALOGE("Unable to access asset data: %d", err);
+                    if (!mStreamNeedsInit) {
+                        ::inflateEnd(&mInflateState);
+                        initInflateState();
+                    }
+                    return -1;
+                }
+            }
+            // we know we've drained whatever is in the out buffer now, so just
+            // start from scratch there, reading all the input we have at present.
+            mInflateState.next_out = (Bytef*) mOutBuf;
+            mInflateState.avail_out = mOutBufSize;
+
+            /*
+            ALOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
+                    mInflateState.avail_in, mInflateState.avail_out,
+                    mInflateState.next_in, mInflateState.next_out);
+            */
+            int result = Z_OK;
+            if (mStreamNeedsInit) {
+                ALOGV("Initializing zlib to inflate");
+                result = inflateInit2(&mInflateState, -MAX_WBITS);
+                mStreamNeedsInit = false;
+            }
+            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
+            if (result < 0) {
+                // Whoops, inflation failed
+                ALOGE("Error inflating asset: %d", result);
+                ::inflateEnd(&mInflateState);
+                initInflateState();
+                return -1;
+            } else {
+                if (result == Z_STREAM_END) {
+                    // we know we have to have reached the target size here and will
+                    // not try to read any further, so just wind things up.
+                    ::inflateEnd(&mInflateState);
+                }
+
+                // Note how much data we got, and off we go
+                mOutDeliverable = 0;
+                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
+            }
+        }
+    }
+    return bytesRead;
+}
+
+int StreamingZipInflater::readNextChunk() {
+    assert(mDataMap == NULL);
+
+    if (mInNextChunkOffset < mInTotalSize) {
+        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
+        if (toRead > 0) {
+            ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead));
+            //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
+            if (didRead < 0) {
+                ALOGE("Error reading asset data: %s", strerror(errno));
+                return didRead;
+            } else {
+                mInNextChunkOffset += didRead;
+                mInflateState.next_in = (Bytef*) mInBuf;
+                mInflateState.avail_in = didRead;
+            }
+        }
+    }
+    return 0;
+}
+
+// seeking backwards requires uncompressing fom the beginning, so is very
+// expensive.  seeking forwards only requires uncompressing from the current
+// position to the destination.
+off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
+    if (absoluteInputPosition < mOutCurPosition) {
+        // rewind and reprocess the data from the beginning
+        if (!mStreamNeedsInit) {
+            ::inflateEnd(&mInflateState);
+        }
+        initInflateState();
+        read(NULL, absoluteInputPosition);
+    } else if (absoluteInputPosition > mOutCurPosition) {
+        read(NULL, absoluteInputPosition - mOutCurPosition);
+    }
+    // else if the target position *is* our current position, do nothing
+    return absoluteInputPosition;
+}
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
new file mode 100644
index 0000000..ec5f95c
--- /dev/null
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -0,0 +1,995 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+#define LOG_TAG "zipro"
+//#define LOG_NDEBUG 0
+#include <androidfw/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Compat.h>
+#include <utils/misc.h>
+#include <utils/threads.h>
+
+#include <zlib.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+/*
+ * We must open binary files using open(path, ... | O_BINARY) under Windows.
+ * Otherwise strange read errors will happen.
+ */
+#ifndef O_BINARY
+#  define O_BINARY  0
+#endif
+
+using namespace android;
+
+/*
+ * Zip file constants.
+ */
+#define kEOCDSignature       0x06054b50
+#define kEOCDLen             22
+#define kEOCDDiskNumber      4               // number of the current disk
+#define kEOCDDiskNumberForCD 6               // disk number with the Central Directory
+#define kEOCDNumEntries      8               // offset to #of entries in file
+#define kEOCDTotalNumEntries 10              // offset to total #of entries in spanned archives
+#define kEOCDSize            12              // size of the central directory
+#define kEOCDFileOffset      16              // offset to central directory
+#define kEOCDCommentSize     20              // offset to the length of the file comment
+
+#define kMaxCommentLen       65535           // longest possible in ushort
+#define kMaxEOCDSearch       (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature        0x04034b50
+#define kLFHLen              30              // excluding variable-len fields
+#define kLFHGPBFlags          6              // offset to GPB flags
+#define kLFHNameLen          26              // offset to filename length
+#define kLFHExtraLen         28              // offset to extra length
+
+#define kCDESignature        0x02014b50
+#define kCDELen              46              // excluding variable-len fields
+#define kCDEGPBFlags          8              // offset to GPB flags
+#define kCDEMethod           10              // offset to compression method
+#define kCDEModWhen          12              // offset to modification timestamp
+#define kCDECRC              16              // offset to entry CRC
+#define kCDECompLen          20              // offset to compressed length
+#define kCDEUncompLen        24              // offset to uncompressed length
+#define kCDENameLen          28              // offset to filename length
+#define kCDEExtraLen         30              // offset to extra length
+#define kCDECommentLen       32              // offset to comment length
+#define kCDELocalOffset      42              // offset to local hdr
+
+/* General Purpose Bit Flag */
+#define kGPFEncryptedFlag    (1 << 0)
+#define kGPFUnsupportedMask  (kGPFEncryptedFlag)
+
+/*
+ * The values we return for ZipEntryRO use 0 as an invalid value, so we
+ * want to adjust the hash table index by a fixed amount.  Using a large
+ * value helps insure that people don't mix & match arguments, e.g. to
+ * findEntryByIndex().
+ */
+#define kZipEntryAdj        10000
+
+ZipFileRO::~ZipFileRO() {
+    free(mHashTable);
+    if (mDirectoryMap)
+        mDirectoryMap->release();
+    if (mFd >= 0)
+        TEMP_FAILURE_RETRY(close(mFd));
+    if (mFileName)
+        free(mFileName);
+}
+
+/*
+ * Convert a ZipEntryRO to a hash table index, verifying that it's in a
+ * valid range.
+ */
+int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
+{
+    long ent = ((intptr_t) entry) - kZipEntryAdj;
+    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
+        ALOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
+        return -1;
+    }
+    return ent;
+}
+
+
+/*
+ * Open the specified file read-only.  We memory-map the entire thing and
+ * close the file before returning.
+ */
+status_t ZipFileRO::open(const char* zipFileName)
+{
+    int fd = -1;
+
+    assert(mDirectoryMap == NULL);
+
+    /*
+     * Open and map the specified file.
+     */
+    fd = TEMP_FAILURE_RETRY(::open(zipFileName, O_RDONLY | O_BINARY));
+    if (fd < 0) {
+        ALOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
+        return NAME_NOT_FOUND;
+    }
+
+    mFileLength = lseek64(fd, 0, SEEK_END);
+    if (mFileLength < kEOCDLen) {
+        TEMP_FAILURE_RETRY(close(fd));
+        return UNKNOWN_ERROR;
+    }
+
+    if (mFileName != NULL) {
+        free(mFileName);
+    }
+    mFileName = strdup(zipFileName);
+
+    mFd = fd;
+
+    /*
+     * Find the Central Directory and store its size and number of entries.
+     */
+    if (!mapCentralDirectory()) {
+        goto bail;
+    }
+
+    /*
+     * Verify Central Directory and create data structures for fast access.
+     */
+    if (!parseZipArchive()) {
+        goto bail;
+    }
+
+    return OK;
+
+bail:
+    free(mFileName);
+    mFileName = NULL;
+    TEMP_FAILURE_RETRY(close(fd));
+    return UNKNOWN_ERROR;
+}
+
+/*
+ * Parse the Zip archive, verifying its contents and initializing internal
+ * data structures.
+ */
+bool ZipFileRO::mapCentralDirectory(void)
+{
+    ssize_t readAmount = kMaxEOCDSearch;
+    if (readAmount > (ssize_t) mFileLength)
+        readAmount = mFileLength;
+
+    if (readAmount < kEOCDSize) {
+        ALOGW("File too short to be a zip file");
+        return false;
+    }
+
+    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
+    if (scanBuf == NULL) {
+        ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Make sure this is a Zip archive.
+     */
+    if (lseek64(mFd, 0, SEEK_SET) != 0) {
+        ALOGW("seek to start failed: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
+    if (actual != (ssize_t) sizeof(int32_t)) {
+        ALOGI("couldn't read first signature from zip archive: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    unsigned int header = get4LE(scanBuf);
+    if (header != kLFHSignature) {
+        ALOGV("Not a Zip archive (found 0x%08x)\n", header);
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Perform the traditional EOCD snipe hunt.
+     *
+     * We're searching for the End of Central Directory magic number,
+     * which appears at the start of the EOCD block.  It's followed by
+     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
+     * need to read the last part of the file into a buffer, dig through
+     * it to find the magic number, parse some values out, and use those
+     * to determine the extent of the CD.
+     *
+     * We start by pulling in the last part of the file.
+     */
+    off64_t searchStart = mFileLength - readAmount;
+
+    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
+        ALOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
+    if (actual != (ssize_t) readAmount) {
+        ALOGW("Zip: read " ZD ", expected " ZD ". Failed: %s\n",
+            (ZD_TYPE) actual, (ZD_TYPE) readAmount, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Scan backward for the EOCD magic.  In an archive without a trailing
+     * comment, we'll find it on the first try.  (We may want to consider
+     * doing an initial minimal read; if we don't find it, retry with a
+     * second read as above.)
+     */
+    int i;
+    for (i = readAmount - kEOCDLen; i >= 0; i--) {
+        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
+            ALOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        ALOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
+        free(scanBuf);
+        return false;
+    }
+
+    off64_t eocdOffset = searchStart + i;
+    const unsigned char* eocdPtr = scanBuf + i;
+
+    assert(eocdOffset < mFileLength);
+
+    /*
+     * Grab the CD offset and size, and the number of entries in the
+     * archive. After that, we can release our EOCD hunt buffer.
+     */
+    unsigned int diskNumber = get2LE(eocdPtr + kEOCDDiskNumber);
+    unsigned int diskWithCentralDir = get2LE(eocdPtr + kEOCDDiskNumberForCD);
+    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
+    unsigned int totalNumEntries = get2LE(eocdPtr + kEOCDTotalNumEntries);
+    unsigned int centralDirSize = get4LE(eocdPtr + kEOCDSize);
+    unsigned int centralDirOffset = get4LE(eocdPtr + kEOCDFileOffset);
+    unsigned int commentSize = get2LE(eocdPtr + kEOCDCommentSize);
+    free(scanBuf);
+
+    // Verify that they look reasonable.
+    if ((long long) centralDirOffset + (long long) centralDirSize > (long long) eocdOffset) {
+        ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
+            (long) centralDirOffset, centralDirSize, (long) eocdOffset);
+        return false;
+    }
+    if (numEntries == 0) {
+        ALOGW("empty archive?\n");
+        return false;
+    } else if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
+        ALOGW("spanned archives not supported");
+        return false;
+    }
+
+    // Check to see if comment is a sane size
+    if ((commentSize > (mFileLength - kEOCDLen))
+            || (eocdOffset > (mFileLength - kEOCDLen) - commentSize)) {
+        ALOGW("comment size runs off end of file");
+        return false;
+    }
+
+    ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+        numEntries, centralDirSize, centralDirOffset);
+
+    mDirectoryMap = new FileMap();
+    if (mDirectoryMap == NULL) {
+        ALOGW("Unable to create directory map: %s", strerror(errno));
+        return false;
+    }
+
+    if (!mDirectoryMap->create(mFileName, mFd, centralDirOffset, centralDirSize, true)) {
+        ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
+                (ZD_TYPE) centralDirOffset, (ZD_TYPE) (centralDirOffset + centralDirSize), strerror(errno));
+        return false;
+    }
+
+    mNumEntries = numEntries;
+    mDirectoryOffset = centralDirOffset;
+
+    return true;
+}
+
+
+/*
+ * Round up to the next highest power of 2.
+ *
+ * Found on http://graphics.stanford.edu/~seander/bithacks.html.
+ */
+static unsigned int roundUpPower2(unsigned int val)
+{
+    val--;
+    val |= val >> 1;
+    val |= val >> 2;
+    val |= val >> 4;
+    val |= val >> 8;
+    val |= val >> 16;
+    val++;
+
+    return val;
+}
+
+bool ZipFileRO::parseZipArchive(void)
+{
+    bool result = false;
+    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
+    size_t cdLength = mDirectoryMap->getDataLength();
+    int numEntries = mNumEntries;
+
+    /*
+     * Create hash table.  We have a minimum 75% load factor, possibly as
+     * low as 50% after we round off to a power of 2.
+     */
+    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
+    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
+
+    /*
+     * Walk through the central directory, adding entries to the hash
+     * table.
+     */
+    const unsigned char* ptr = cdPtr;
+    for (int i = 0; i < numEntries; i++) {
+        if (get4LE(ptr) != kCDESignature) {
+            ALOGW("Missed a central dir sig (at %d)\n", i);
+            goto bail;
+        }
+        if (ptr + kCDELen > cdPtr + cdLength) {
+            ALOGW("Ran off the end (at %d)\n", i);
+            goto bail;
+        }
+
+        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset >= mDirectoryOffset) {
+            ALOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
+            goto bail;
+        }
+
+        unsigned int gpbf = get2LE(ptr + kCDEGPBFlags);
+        if ((gpbf & kGPFUnsupportedMask) != 0) {
+            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
+            goto bail;
+        }
+
+        unsigned int nameLen = get2LE(ptr + kCDENameLen);
+        unsigned int extraLen = get2LE(ptr + kCDEExtraLen);
+        unsigned int commentLen = get2LE(ptr + kCDECommentLen);
+
+        const char *name = (const char *) ptr + kCDELen;
+
+        /* Check name for NULL characters */
+        if (memchr(name, 0, nameLen) != NULL) {
+            ALOGW("Filename contains NUL byte");
+            goto bail;
+        }
+
+        /* add the CDE filename to the hash table */
+        unsigned int hash = computeHash(name, nameLen);
+        addToHash(name, nameLen, hash);
+
+        /* We don't care about the comment or extra data. */
+        ptr += kCDELen + nameLen + extraLen + commentLen;
+        if ((size_t)(ptr - cdPtr) > cdLength) {
+            ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
+                (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
+            goto bail;
+        }
+    }
+    ALOGV("+++ zip good scan %d entries\n", numEntries);
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Simple string hash function for non-null-terminated strings.
+ */
+/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
+{
+    unsigned int hash = 0;
+
+    while (len--)
+        hash = hash * 31 + *str++;
+
+    return hash;
+}
+
+/*
+ * Add a new entry to the hash table.
+ */
+void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
+{
+    int ent = hash & (mHashTableSize-1);
+
+    /*
+     * We over-allocate the table, so we're guaranteed to find an empty slot.
+     */
+    while (mHashTable[ent].name != NULL)
+        ent = (ent + 1) & (mHashTableSize-1);
+
+    mHashTable[ent].name = str;
+    mHashTable[ent].nameLen = strLen;
+}
+
+/*
+ * Find a matching entry.
+ *
+ * Returns NULL if not found.
+ */
+ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
+{
+    /*
+     * If the ZipFileRO instance is not initialized, the entry number will
+     * end up being garbage since mHashTableSize is -1.
+     */
+    if (mHashTableSize <= 0) {
+        return NULL;
+    }
+
+    int nameLen = strlen(fileName);
+    unsigned int hash = computeHash(fileName, nameLen);
+    int ent = hash & (mHashTableSize-1);
+
+    while (mHashTable[ent].name != NULL) {
+        if (mHashTable[ent].nameLen == nameLen &&
+            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
+        {
+            /* match */
+            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
+        }
+
+        ent = (ent + 1) & (mHashTableSize-1);
+    }
+
+    return NULL;
+}
+
+/*
+ * Find the Nth entry.
+ *
+ * This currently involves walking through the sparse hash table, counting
+ * non-empty entries.  If we need to speed this up we can either allocate
+ * a parallel lookup table or (perhaps better) provide an iterator interface.
+ */
+ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= mNumEntries) {
+        ALOGW("Invalid index %d\n", idx);
+        return NULL;
+    }
+
+    for (int ent = 0; ent < mHashTableSize; ent++) {
+        if (mHashTable[ent].name != NULL) {
+            if (idx-- == 0)
+                return (ZipEntryRO) (intptr_t)(ent + kZipEntryAdj);
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the useful fields from the zip entry.
+ *
+ * Returns "false" if the offsets to the fields or the contents of the fields
+ * appear to be bogus.
+ */
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
+{
+    bool ret = false;
+
+    const int ent = entryToIndex(entry);
+    if (ent < 0) {
+        ALOGW("cannot find entry");
+        return false;
+    }
+
+    HashEntry hashEntry = mHashTable[ent];
+
+    /*
+     * Recover the start of the central directory entry from the filename
+     * pointer.  The filename is the first entry past the fixed-size data,
+     * so we can just subtract back from that.
+     */
+    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
+    off64_t cdOffset = mDirectoryOffset;
+
+    ptr -= kCDELen;
+
+    int method = get2LE(ptr + kCDEMethod);
+    if (pMethod != NULL)
+        *pMethod = method;
+
+    if (pModWhen != NULL)
+        *pModWhen = get4LE(ptr + kCDEModWhen);
+    if (pCrc32 != NULL)
+        *pCrc32 = get4LE(ptr + kCDECRC);
+
+    size_t compLen = get4LE(ptr + kCDECompLen);
+    if (pCompLen != NULL)
+        *pCompLen = compLen;
+    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
+    if (pUncompLen != NULL)
+        *pUncompLen = uncompLen;
+
+    /*
+     * If requested, determine the offset of the start of the data.  All we
+     * have is the offset to the Local File Header, which is variable size,
+     * so we have to read the contents of the struct to figure out where
+     * the actual data starts.
+     *
+     * We also need to make sure that the lengths are not so large that
+     * somebody trying to map the compressed or uncompressed data runs
+     * off the end of the mapped region.
+     *
+     * Note we don't verify compLen/uncompLen if they don't request the
+     * dataOffset, because dataOffset is expensive to determine.  However,
+     * if they don't have the file offset, they're not likely to be doing
+     * anything with the contents.
+     */
+    if (pOffset != NULL) {
+        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset + kLFHLen >= cdOffset) {
+            ALOGE("ERROR: bad local hdr offset in zip\n");
+            return false;
+        }
+
+        unsigned char lfhBuf[kLFHLen];
+
+#ifdef HAVE_PREAD
+        /*
+         * This file descriptor might be from zygote's preloaded assets,
+         * so we need to do an pread64() instead of a lseek64() + read() to
+         * guarantee atomicity across the processes with the shared file
+         * descriptors.
+         */
+        ssize_t actual =
+                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
+
+        if (actual != sizeof(lfhBuf)) {
+            ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+            return false;
+        }
+
+        if (get4LE(lfhBuf) != kLFHSignature) {
+            ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+                    "got: data=0x%08lx\n",
+                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
+            return false;
+        }
+#else /* HAVE_PREAD */
+        /*
+         * For hosts don't have pread64() we cannot guarantee atomic reads from
+         * an offset in a file. Android should never run on those platforms.
+         * File descriptors inherited from a fork() share file offsets and
+         * there would be nothing to protect from two different processes
+         * calling lseek64() concurrently.
+         */
+
+        {
+            AutoMutex _l(mFdLock);
+
+            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+                ALOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+                return false;
+            }
+
+            ssize_t actual =
+                    TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+            if (actual != sizeof(lfhBuf)) {
+                ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+                return false;
+            }
+
+            if (get4LE(lfhBuf) != kLFHSignature) {
+                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
+                ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+                        "got: offset=" ZD " data=0x%08lx\n",
+                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
+                return false;
+            }
+        }
+#endif /* HAVE_PREAD */
+
+        unsigned int gpbf = get2LE(lfhBuf + kLFHGPBFlags);
+        if ((gpbf & kGPFUnsupportedMask) != 0) {
+            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
+            return false;
+        }
+
+        off64_t dataOffset = localHdrOffset + kLFHLen
+            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
+        if (dataOffset >= cdOffset) {
+            ALOGW("bad data offset %ld in zip\n", (long) dataOffset);
+            return false;
+        }
+
+        /* check lengths */
+        if ((dataOffset >= cdOffset) || (compLen > (cdOffset - dataOffset))) {
+            ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
+                (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
+            return false;
+        }
+
+        if (method == kCompressStored &&
+            ((dataOffset >= cdOffset) ||
+             (uncompLen > (cdOffset - dataOffset))))
+        {
+            ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
+                (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
+            return false;
+        }
+
+        *pOffset = dataOffset;
+    }
+
+    return true;
+}
+
+/*
+ * Copy the entry's filename to the buffer.
+ */
+int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
+    const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    int nameLen = mHashTable[ent].nameLen;
+    if (bufLen < nameLen+1)
+        return nameLen+1;
+
+    memcpy(buffer, mHashTable[ent].name, nameLen);
+    buffer[nameLen] = '\0';
+    return 0;
+}
+
+/*
+ * Create a new FileMap object that spans the data in "entry".
+ */
+FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
+{
+    /*
+     * TODO: the efficient way to do this is to modify FileMap to allow
+     * sub-regions of a file to be mapped.  A reference-counting scheme
+     * can manage the base memory mapping.  For now, we just create a brand
+     * new mapping off of the Zip archive file descriptor.
+     */
+
+    FileMap* newMap;
+    int method;
+    size_t uncompLen;
+    size_t compLen;
+    off64_t offset;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        return NULL;
+    }
+
+    size_t actualLen;
+    if (method == kCompressStored) {
+        actualLen = uncompLen;
+    } else {
+        actualLen = compLen;
+    }
+
+    newMap = new FileMap();
+    if (!newMap->create(mFileName, mFd, offset, actualLen, true)) {
+        newMap->release();
+        return NULL;
+    }
+
+    return newMap;
+}
+
+/*
+ * Uncompress an entry, in its entirety, into the provided output buffer.
+ *
+ * This doesn't verify the data's CRC, which might be useful for
+ * uncompressed data.  The caller should be able to manage it.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
+{
+    const size_t kSequentialMin = 32768;
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0) {
+        return false;
+    }
+
+    int method;
+    size_t uncompLen, compLen;
+    off64_t offset;
+    const unsigned char* ptr;
+    FileMap *file;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        goto bail;
+    }
+
+    file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    /*
+     * Experiment with madvise hint.  When we want to uncompress a file,
+     * we pull some stuff out of the central dir entry and then hit a
+     * bunch of compressed or uncompressed data sequentially.  The CDE
+     * visit will cause a limited amount of read-ahead because it's at
+     * the end of the file.  We could end up doing lots of extra disk
+     * access if the file we're prying open is small.  Bottom line is we
+     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
+     *
+     * So, if the compressed size of the file is above a certain minimum
+     * size, temporarily boost the read-ahead in the hope that the extra
+     * pair of system calls are negated by a reduction in page faults.
+     */
+    if (compLen > kSequentialMin)
+        file->advise(FileMap::SEQUENTIAL);
+
+    if (method == kCompressStored) {
+        memcpy(buffer, ptr, uncompLen);
+    } else {
+        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
+            goto unmap;
+    }
+
+    if (compLen > kSequentialMin)
+        file->advise(FileMap::NORMAL);
+
+    result = true;
+
+unmap:
+    file->release();
+bail:
+    return result;
+}
+
+/*
+ * Uncompress an entry, in its entirety, to an open file descriptor.
+ *
+ * This doesn't verify the data's CRC, but probably should.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
+{
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0) {
+        return false;
+    }
+
+    int method;
+    size_t uncompLen, compLen;
+    off64_t offset;
+    const unsigned char* ptr;
+    FileMap *file;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        goto bail;
+    }
+
+    file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    if (method == kCompressStored) {
+        ssize_t actual = TEMP_FAILURE_RETRY(write(fd, ptr, uncompLen));
+        if (actual < 0) {
+            ALOGE("Write failed: %s\n", strerror(errno));
+            goto unmap;
+        } else if ((size_t) actual != uncompLen) {
+            ALOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
+                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
+            goto unmap;
+        } else {
+            ALOGI("+++ successful write\n");
+        }
+    } else {
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen)) {
+            goto unmap;
+        }
+    }
+
+    result = true;
+
+unmap:
+    file->release();
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to another.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
+    size_t uncompLen, size_t compLen)
+{
+    bool result = false;
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+    memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) outBuf;
+    zstream.avail_out = uncompLen;
+    zstream.data_type = Z_UNKNOWN;
+
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Expand data.
+     */
+    zerr = inflate(&zstream, Z_FINISH);
+    if (zerr != Z_STREAM_END) {
+        ALOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+            zerr, zstream.next_in, zstream.avail_in,
+            zstream.next_out, zstream.avail_out);
+        goto z_bail;
+    }
+
+    /* paranoia */
+    if (zstream.total_out != uncompLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to an open file descriptor.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
+    size_t uncompLen, size_t compLen)
+{
+    bool result = false;
+    const size_t kWriteBufSize = 32768;
+    unsigned char writeBuf[kWriteBufSize];
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+    memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) writeBuf;
+    zstream.avail_out = sizeof(writeBuf);
+    zstream.data_type = Z_UNKNOWN;
+
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have more to do.
+     */
+    do {
+        /*
+         * Expand data.
+         */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            ALOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+                zerr, zstream.next_in, zstream.avail_in,
+                zstream.next_out, zstream.avail_out);
+            goto z_bail;
+        }
+
+        /* write when we're full or when we're done */
+        if (zstream.avail_out == 0 ||
+            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
+        {
+            long writeSize = zstream.next_out - writeBuf;
+            int cc = TEMP_FAILURE_RETRY(write(fd, writeBuf, writeSize));
+            if (cc < 0) {
+                ALOGW("write failed in inflate: %s", strerror(errno));
+                goto z_bail;
+            } else if (cc != (int) writeSize) {
+                ALOGW("write failed in inflate (%d vs %ld)", cc, writeSize);
+                goto z_bail;
+            }
+
+            zstream.next_out = writeBuf;
+            zstream.avail_out = sizeof(writeBuf);
+        }
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    /* paranoia */
+    if (zstream.total_out != uncompLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
new file mode 100644
index 0000000..997eb7d
--- /dev/null
+++ b/libs/androidfw/ZipUtils.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Misc zip/gzip utility functions.
+//
+
+#define LOG_TAG "ziputil"
+
+#include <androidfw/ZipUtils.h>
+#include <androidfw/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Compat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <zlib.h>
+
+using namespace android;
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * "fd" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            ALOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = TEMP_FAILURE_RETRY(read(fd, readBuf, getSize));
+            if (cc < 0) {
+                ALOGW("inflate read failed: %s", strerror(errno));
+            } else if (cc != (int) getSize) {
+                ALOGW("inflate read failed (%d vs %ld)", cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * (This is a clone of the previous function, but it takes a FILE* instead
+ * of an fd.  We could pass fileno(fd) to the above, but we can run into
+ * trouble when "fp" has a different notion of what fd's file position is.)
+ *
+ * "fp" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * Use the undocumented "negative window bits" feature to tell zlib
+	 * that there's no zlib header waiting for it.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            ALOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = fread(readBuf, 1, getSize, fp);
+            if (cc != (int) getSize) {
+                ALOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Look at the contents of a gzip archive.  We want to know where the
+ * data starts, and how long it will be after it is uncompressed.
+ *
+ * We expect to find the CRC and length as the last 8 bytes on the file.
+ * This is a pretty reasonable thing to expect for locally-compressed
+ * files, but there's a small chance that some extra padding got thrown
+ * on (the man page talks about compressed data written to tape).  We
+ * don't currently deal with that here.  If "gzip -l" whines, we're going
+ * to fail too.
+ *
+ * On exit, "fp" is pointing at the start of the compressed data.
+ */
+/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
+    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
+{
+    enum {  // flags
+        FTEXT       = 0x01,
+        FHCRC       = 0x02,
+        FEXTRA      = 0x04,
+        FNAME       = 0x08,
+        FCOMMENT    = 0x10,
+    };
+    int ic;
+    int method, flags;
+    int i;
+
+    ic = getc(fp);
+    if (ic != 0x1f || getc(fp) != 0x8b)
+        return false;       // not gzip
+    method = getc(fp);
+    flags = getc(fp);
+
+    /* quick sanity checks */
+    if (method == EOF || flags == EOF)
+        return false;
+    if (method != ZipFileRO::kCompressDeflated)
+        return false;
+
+    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
+    for (i = 0; i < 6; i++)
+        (void) getc(fp);
+    /* consume "extra" field, if present */
+    if ((flags & FEXTRA) != 0) {
+        int len;
+
+        len = getc(fp);
+        len |= getc(fp) << 8;
+        while (len-- && getc(fp) != EOF)
+            ;
+    }
+    /* consume filename, if present */
+    if ((flags & FNAME) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume comment, if present */
+    if ((flags & FCOMMENT) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume 16-bit header CRC, if present */
+    if ((flags & FHCRC) != 0) {
+        (void) getc(fp);
+        (void) getc(fp);
+    }
+
+    if (feof(fp) || ferror(fp))
+        return false;
+
+    /* seek to the end; CRC and length are in the last 8 bytes */
+    long curPosn = ftell(fp);
+    unsigned char buf[8];
+    fseek(fp, -8, SEEK_END);
+    *pCompressedLen = ftell(fp) - curPosn;
+
+    if (fread(buf, 1, 8, fp) != 8)
+        return false;
+    /* seek back to start of compressed data */
+    fseek(fp, curPosn, SEEK_SET);
+
+    *pCompressionMethod = method;
+    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
+    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
+
+    return true;
+}
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
new file mode 100644
index 0000000..29686ef
--- /dev/null
+++ b/libs/androidfw/misc.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "misc"
+
+//
+// Miscellaneous utility functions.
+//
+#include <androidfw/misc.h>
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+using namespace android;
+
+namespace android {
+
+/*
+ * Get a file's type.
+ */
+FileType getFileType(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0) {
+        if (errno == ENOENT || errno == ENOTDIR)
+            return kFileTypeNonexistent;
+        else {
+            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
+                errno, fileName);
+            return kFileTypeUnknown;
+        }
+    } else {
+        if (S_ISREG(sb.st_mode))
+            return kFileTypeRegular;
+        else if (S_ISDIR(sb.st_mode))
+            return kFileTypeDirectory;
+        else if (S_ISCHR(sb.st_mode))
+            return kFileTypeCharDev;
+        else if (S_ISBLK(sb.st_mode))
+            return kFileTypeBlockDev;
+        else if (S_ISFIFO(sb.st_mode))
+            return kFileTypeFifo;
+#ifdef HAVE_SYMLINKS
+        else if (S_ISLNK(sb.st_mode))
+            return kFileTypeSymlink;
+        else if (S_ISSOCK(sb.st_mode))
+            return kFileTypeSocket;
+#endif
+        else
+            return kFileTypeUnknown;
+    }
+}
+
+/*
+ * Get a file's modification date.
+ */
+time_t getFileModDate(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0)
+        return (time_t) -1;
+
+    return sb.st_mtime;
+}
+
+}; // namespace android
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
new file mode 100644
index 0000000..c8e3f2b
--- /dev/null
+++ b/libs/androidfw/tests/Android.mk
@@ -0,0 +1,32 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Build the unit tests.
+test_src_files := \
+    BackupData_test.cpp \
+    ObbFile_test.cpp \
+    ZipFileRO_test.cpp
+
+shared_libraries := \
+    libandroidfw \
+    libcutils \
+    libutils \
+    libui \
+    libstlport
+
+static_libraries := \
+    libgtest \
+    libgtest_main
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval include $(BUILD_NATIVE_TEST)) \
+)
+
+# Build the manual test programs.
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/androidfw/tests/BackupData_test.cpp b/libs/androidfw/tests/BackupData_test.cpp
new file mode 100644
index 0000000..17f91ca
--- /dev/null
+++ b/libs/androidfw/tests/BackupData_test.cpp
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ObbFile_test"
+#include <androidfw/BackupHelpers.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+namespace android {
+
+#define TEST_FILENAME "/test.bd"
+
+// keys of different lengths to test padding
+#define KEY1 "key1"
+#define KEY2 "key2a"
+#define KEY3 "key3bc"
+#define KEY4 "key4def"
+
+// payloads of different lengths to test padding
+#define DATA1 "abcdefg"
+#define DATA2 "hijklmnopq"
+#define DATA3 "rstuvwxyz"
+// KEY4 is only ever deleted
+
+class BackupDataTest : public testing::Test {
+protected:
+    char* m_external_storage;
+    char* m_filename;
+    String8 mKey1;
+    String8 mKey2;
+    String8 mKey3;
+    String8 mKey4;
+
+    virtual void SetUp() {
+        m_external_storage = getenv("EXTERNAL_STORAGE");
+
+        const int totalLen = strlen(m_external_storage) + strlen(TEST_FILENAME) + 1;
+        m_filename = new char[totalLen];
+        snprintf(m_filename, totalLen, "%s%s", m_external_storage, TEST_FILENAME);
+
+        ::unlink(m_filename);
+        int fd = ::open(m_filename, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+        if (fd < 0) {
+            FAIL() << "Couldn't create " << m_filename << " for writing";
+        }
+        mKey1 = String8(KEY1);
+        mKey2 = String8(KEY2);
+        mKey3 = String8(KEY3);
+        mKey4 = String8(KEY4);
+   }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(BackupDataTest, WriteAndReadSingle) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+
+  EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))
+          << "WriteEntityHeader returned an error";
+  EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1)))
+          << "WriteEntityData returned an error";
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+  EXPECT_EQ(NO_ERROR, reader->Status())
+          << "Reader ctor failed";
+
+  bool done;
+  int type;
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader";
+
+  String8 key;
+  size_t dataSize;
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader";
+  EXPECT_EQ(sizeof(DATA1), dataSize)
+          << "wrong size from ReadEntityHeader";
+
+  char* dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error";
+  for (unsigned int i = 0; i < sizeof(DATA1); i++) {
+    EXPECT_EQ(DATA1[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, WriteAndReadMultiple) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
+  writer->WriteEntityData(DATA2, sizeof(DATA2));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify second entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(sizeof(DATA2), dataSize)
+          << "wrong size from ReadEntityHeader on second entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on second entity";
+  for (unsigned int i = 0; i < sizeof(DATA2); i++) {
+    EXPECT_EQ(DATA2[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, SkipEntity) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
+  writer->WriteEntityData(DATA2, sizeof(DATA2));
+  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
+  writer->WriteEntityData(DATA3, sizeof(DATA3));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // skip second entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  reader->SkipEntityData();
+
+  // read and verify third entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader after skip";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(sizeof(DATA3), dataSize)
+          << "wrong size from ReadEntityHeader on third entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on third entity";
+  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
+    EXPECT_EQ(DATA3[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, DeleteEntity) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader on deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, EneityAfterDelete) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, -1);
+  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
+  writer->WriteEntityData(DATA3, sizeof(DATA3));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader on deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int)dataSize)
+          << "not recognizing deletion on second entity";
+
+  // read and verify third entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader after deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(sizeof(DATA3), dataSize)
+          << "wrong size from ReadEntityHeader on third entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on third entity";
+  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
+    EXPECT_EQ(DATA3[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, OnlyDeleteEntities) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, -1);
+  writer->WriteEntityHeader(mKey2, -1);
+  writer->WriteEntityHeader(mKey3, -1);
+  writer->WriteEntityHeader(mKey4, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  // read and verify first deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader first deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on first entity";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader on first entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on first entity";
+
+  // read and verify second deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader second deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  // read and verify third deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader third deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on third entity";
+
+  // read and verify fourth deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader fourth deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on fourth entity";
+  EXPECT_EQ(mKey4, key)
+          << "wrong key from ReadEntityHeader on fourth entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on fourth entity";
+
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, ReadDeletedEntityData) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, -1);
+  writer->WriteEntityHeader(mKey2, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  // read and verify first deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader first deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on first entity";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader on first entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on first entity";
+
+  // erroneously try to read first entity data
+  char* dataBytes = new char[10];
+  dataBytes[0] = 'A';
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize));
+  // expect dataBytes to be unmodofied
+  EXPECT_EQ('A', dataBytes[0]);
+
+  // read and verify second deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader second deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  delete writer;
+  delete reader;
+}
+
+}
diff --git a/libs/androidfw/tests/ObbFile_test.cpp b/libs/androidfw/tests/ObbFile_test.cpp
new file mode 100644
index 0000000..2c9f650
--- /dev/null
+++ b/libs/androidfw/tests/ObbFile_test.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ObbFile_test"
+#include <androidfw/ObbFile.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+namespace android {
+
+#define TEST_FILENAME "/test.obb"
+
+class ObbFileTest : public testing::Test {
+protected:
+    sp<ObbFile> mObbFile;
+    char* mExternalStorage;
+    char* mFileName;
+
+    virtual void SetUp() {
+        mObbFile = new ObbFile();
+        mExternalStorage = getenv("EXTERNAL_STORAGE");
+
+        const int totalLen = strlen(mExternalStorage) + strlen(TEST_FILENAME) + 1;
+        mFileName = new char[totalLen];
+        snprintf(mFileName, totalLen, "%s%s", mExternalStorage, TEST_FILENAME);
+
+        int fd = ::open(mFileName, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+        if (fd < 0) {
+            FAIL() << "Couldn't create " << mFileName << " for tests";
+        }
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(ObbFileTest, ReadFailure) {
+    EXPECT_FALSE(mObbFile->readFrom(-1))
+            << "No failure on invalid file descriptor";
+}
+
+TEST_F(ObbFileTest, WriteThenRead) {
+    const char* packageName = "com.example.obbfile";
+    const int32_t versionNum = 1;
+
+    mObbFile->setPackageName(String8(packageName));
+    mObbFile->setVersion(versionNum);
+#define SALT_SIZE 8
+    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
+    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
+            << "Salt should be successfully set";
+
+    EXPECT_TRUE(mObbFile->writeTo(mFileName))
+            << "couldn't write to fake .obb file";
+
+    mObbFile = new ObbFile();
+
+    EXPECT_TRUE(mObbFile->readFrom(mFileName))
+            << "couldn't read from fake .obb file";
+
+    EXPECT_EQ(versionNum, mObbFile->getVersion())
+            << "version didn't come out the same as it went in";
+    const char* currentPackageName = mObbFile->getPackageName().string();
+    EXPECT_STREQ(packageName, currentPackageName)
+            << "package name didn't come out the same as it went in";
+
+    size_t saltLen;
+    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
+
+    EXPECT_EQ(sizeof(salt), saltLen)
+            << "salt sizes were not the same";
+
+    for (int i = 0; i < sizeof(salt); i++) {
+        EXPECT_EQ(salt[i], newSalt[i])
+                << "salt character " << i << " should be equal";
+    }
+    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
+            << "salts should be the same";
+}
+
+}
diff --git a/libs/androidfw/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp
new file mode 100644
index 0000000..cb9c721
--- /dev/null
+++ b/libs/androidfw/tests/ZipFileRO_test.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ZipFileRO_test"
+#include <utils/Log.h>
+#include <androidfw/ZipFileRO.h>
+
+#include <gtest/gtest.h>
+
+#include <fcntl.h>
+#include <string.h>
+
+namespace android {
+
+class ZipFileROTest : public testing::Test {
+protected:
+    virtual void SetUp() {
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(ZipFileROTest, ZipTimeConvertSuccess) {
+    struct tm t;
+
+    // 2011-06-29 14:40:40
+    long when = 0x3EDD7514;
+
+    ZipFileRO::zipTimeToTimespec(when, &t);
+
+    EXPECT_EQ(2011, t.tm_year + 1900)
+            << "Year was improperly converted.";
+
+    EXPECT_EQ(6, t.tm_mon)
+            << "Month was improperly converted.";
+
+    EXPECT_EQ(29, t.tm_mday)
+            << "Day was improperly converted.";
+
+    EXPECT_EQ(14, t.tm_hour)
+            << "Hour was improperly converted.";
+
+    EXPECT_EQ(40, t.tm_min)
+            << "Minute was improperly converted.";
+
+    EXPECT_EQ(40, t.tm_sec)
+            << "Second was improperly converted.";
+}
+
+}
