diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
new file mode 100644
index 0000000..4a68dc1
--- /dev/null
+++ b/libs/utils/Android.mk
@@ -0,0 +1,148 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# libutils is a little unique: It's built twice, once for the host
+# and once for the device.
+
+commonSources:= \
+	Asset.cpp \
+	AssetDir.cpp \
+	AssetManager.cpp \
+	BufferedTextOutput.cpp \
+	CallStack.cpp \
+	Debug.cpp \
+	FileMap.cpp \
+	RefBase.cpp \
+	ResourceTypes.cpp \
+	SharedBuffer.cpp \
+	Static.cpp \
+	StopWatch.cpp \
+	String8.cpp \
+	String16.cpp \
+	SystemClock.cpp \
+	TextOutput.cpp \
+	Threads.cpp \
+	TimerProbe.cpp \
+	Timers.cpp \
+	VectorImpl.cpp \
+    ZipFileCRO.cpp \
+	ZipFileRO.cpp \
+	ZipUtils.cpp \
+	misc.cpp \
+	ported.cpp \
+	LogSocket.cpp
+
+#
+# The cpp files listed here do not belong in the device
+# build.  Consult with the swetland before even thinking about
+# putting them in commonSources.
+#
+# They're used by the simulator runtime and by host-side tools like
+# aapt and the simulator front-end.
+#
+hostSources:= \
+	InetAddress.cpp \
+	Pipe.cpp \
+	Socket.cpp \
+	ZipEntry.cpp \
+	ZipFile.cpp
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
+
+ifeq ($(HOST_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+	LOCAL_SRC_FILES += \
+		futex_synchro.c \
+		executablepath_linux.cpp
+endif
+ifeq ($(HOST_OS),darwin)
+	LOCAL_SRC_FILES += \
+		executablepath_darwin.cpp
+endif
+
+LOCAL_MODULE:= libutils
+
+LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+LOCAL_C_INCLUDES += external/zlib
+
+ifeq ($(HOST_OS),windows)
+ifeq ($(strip $(USE_CYGWIN),),)
+# Under MinGW, ctype.h doesn't need multi-byte support
+LOCAL_CFLAGS += -DMB_CUR_MAX=1
+endif
+endif
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+
+# we have the common sources, plus some device-specific stuff
+LOCAL_SRC_FILES:= \
+	$(commonSources) \
+	Binder.cpp \
+	BpBinder.cpp \
+	IInterface.cpp \
+	IMemory.cpp \
+	IPCThreadState.cpp \
+	MemoryDealer.cpp \
+    MemoryBase.cpp \
+    MemoryHeapBase.cpp \
+    MemoryHeapPmem.cpp \
+	Parcel.cpp \
+	ProcessState.cpp \
+	IPermissionController.cpp \
+	IServiceManager.cpp \
+	Unicode.cpp
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_SRC_FILES += $(hostSources)
+endif
+
+ifeq ($(TARGET_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+LOCAL_SRC_FILES += futex_synchro.c
+LOCAL_LDLIBS += -lrt -ldl
+endif
+
+LOCAL_C_INCLUDES += \
+		external/zlib \
+		external/icu4c/common
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_SHARED_LIBRARIES := \
+	libz \
+	liblog \
+	libcutils
+
+LOCAL_MODULE:= libutils
+
+#LOCAL_CFLAGS+=
+#LOCAL_LDFLAGS:=
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
new file mode 100644
index 0000000..91203dd
--- /dev/null
+++ b/libs/utils/Asset.cpp
@@ -0,0 +1,813 @@
+/*
+ * 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 <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/FileMap.h>
+#include <utils/ZipUtils.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+
+#include <string.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static volatile int32_t gCount = 0;
+
+int32_t Asset::getGlobalCount()
+{
+    return gCount;
+}
+
+Asset::Asset(void)
+    : mAccessMode(ACCESS_UNKNOWN)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //LOGI("Creating Asset %p #%d\n", this, count);
+}
+
+Asset::~Asset(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("Destroying Asset in %p #%d\n", this, count);
+}
+
+/*
+ * 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;
+    off_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.
+     */
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    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;
+    off_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) {
+        LOGD("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, off_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, off_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.
+ */
+off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
+{
+    off_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:
+        LOGW("unexpected whence %d\n", whence);
+        // this was happening due to an off_t size mismatch
+        assert(false);
+        return (off_t) -1;
+    }
+
+    if (newOffset < 0 || newOffset > maxPosn) {
+        LOGW("seek out of range: want %ld, end=%ld\n",
+            (long) newOffset, (long) maxPosn);
+        return (off_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, off_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.
+     */
+    off_t fileLength;
+    fileLength = lseek(fd, 0, SEEK_END);
+    if (fileLength == (off_t) -1) {
+        // probably a bad file descriptor
+        LOGD("failed lseek (errno=%d)\n", errno);
+        return UNKNOWN_ERROR;
+    }
+
+    if ((off_t) (offset + length) > fileLength) {
+        LOGD("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) {
+            LOGE("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.
+ */
+off_t _FileAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+    long actualOffset;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mLength);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    actualOffset = (long) (mStart + newPosn);
+
+    if (mFp != NULL) {
+        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
+            return (off_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) {
+            LOGE("alloc of %ld bytes failed\n", (long) allocLen);
+            return NULL;
+        }
+
+        LOGV("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) {
+                LOGE("failed reading %ld bytes\n", (long) mLength);
+                delete[] buf;
+                return NULL;
+            }
+            fseek(mFp, oldPosn, SEEK_SET);
+        }
+
+        LOGV(" 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;
+        }
+
+        LOGV(" getBuffer: mapped\n");
+
+        mMap = map;
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+}
+
+int _FileAsset::openFileDescriptor(off_t* outStart, off_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.
+        return data;
+    }
+    // If not aligned on a word boundary, then we need to copy it into
+    // our own buffer.
+    LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength);
+    unsigned char* buf = new unsigned char[mLength];
+    if (buf == NULL) {
+        LOGE("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), 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, off_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);
+
+    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);
+
+    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);
+
+    // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly
+
+    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.
+ */
+off_t _CompressedAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    mOffset = newPosn;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _CompressedAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = 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;
+
+    if (mUncompressedLen > UNCOMPRESS_DATA_MAX) {
+        LOGD("Data exceeds UNCOMPRESS_DATA_MAX (%ld vs %d)\n",
+            (long) mUncompressedLen, UNCOMPRESS_DATA_MAX);
+        goto bail;
+    }
+
+    /*
+     * Allocate a buffer and read the file into it.
+     */
+    buf = new unsigned char[mUncompressedLen];
+    if (buf == NULL) {
+        LOGW("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! */
+    mBuf = buf;
+    buf = NULL;
+
+bail:
+    delete[] buf;
+    return mBuf;
+}
+
diff --git a/libs/utils/AssetDir.cpp b/libs/utils/AssetDir.cpp
new file mode 100644
index 0000000..c5f664e
--- /dev/null
+++ b/libs/utils/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 <utils/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/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
new file mode 100644
index 0000000..447b801
--- /dev/null
+++ b/libs/utils/AssetManager.cpp
@@ -0,0 +1,1637 @@
+/*
+ * 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 LOG_NDEBUG 0
+
+#include <utils/AssetManager.h>
+#include <utils/AssetDir.h>
+#include <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/String8.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String8.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils/threads.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <assert.h>
+
+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* kExcludeExtension = ".EXCLUDE";
+
+static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
+
+static volatile int32_t gCount = 0;
+
+
+/*
+ * ===========================================================================
+ *      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;
+    //LOGI("Creating AssetManager %p #%d\n", this, count);
+    memset(mConfig, 0, sizeof(ResTable_config));
+}
+
+AssetManager::~AssetManager(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("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) {
+            LOGW("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;
+        }
+    }
+    
+    LOGV("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();
+    }
+
+    return true;
+}
+
+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();
+    }
+}
+
+/*
+ * 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--;
+        LOGV("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--;
+        LOGV("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()) {
+        LOGV("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;
+        bool shared = true;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        LOGV("Looking for resource asset in '%s'\n", ap.path.string());
+        if (ap.type != kFileTypeDirectory) {
+            ass = const_cast<AssetManager*>(this)->
+                mZipSet.getZipResourceTable(ap.path);
+            if (ass == NULL) {
+                LOGV("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.setZipResourceTable(ap.path, ass);
+                }
+            }
+        } else {
+            LOGV("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 && ass != kExcludedAsset) {
+            if (rt == NULL) {
+                mResources = rt = new ResTable();
+                updateResourceParamsLocked();
+            }
+            LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+            rt->add(ass, (void*)(i+1), !shared);
+
+            if (!shared) {
+                delete ass;
+            }
+        }
+    }
+
+    if (required && !rt) LOGW("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);
+}
+
+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)
+                    LOGD("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)
+{
+    LOGV("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;
+    long 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))
+    {
+        LOGW("getEntryInfo failed\n");
+        return NULL;
+    }
+
+    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
+    if (dataMap == NULL) {
+        LOGW("create map from entry failed\n");
+        return NULL;
+    }
+
+    if (method == ZipFileRO::kCompressStored) {
+        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
+        LOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    } else {
+        pAsset = Asset::createFromCompressedMap(dataMap, method,
+            uncompressedLen, mode);
+        LOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    }
+    if (pAsset == NULL) {
+        /* unexpected */
+        LOGW("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) {
+            LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        } else {
+            LOGV("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;
+}
+
+/*
+ * 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) {
+                LOGV("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);
+            }
+
+            LOGD("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;
+
+    LOGV("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) {
+        LOGW("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
+            LOGE("ARGH: name too long?\n");
+            continue;
+        }
+        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", (const char*) info.mFileName);
+            } 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", (const char*) subdirName);
+            }
+        }
+    }
+
+    /*
+     * 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();
+    LOGD("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)
+{
+    //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+    mZipFile = new ZipFileRO;
+    LOGV("+++ opening zip '%s'\n", mPath.string());
+    if (mZipFile->open(mPath.string()) != NO_ERROR) {
+        LOGD("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()
+{
+    LOGV("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;
+}
+
+bool AssetManager::SharedZip::isUpToDate()
+{
+    time_t modWhen = getFileModDate(mPath.string());
+    return mModWhen == modWhen;
+}
+
+AssetManager::SharedZip::~SharedZip()
+{
+    //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+    if (mResourceTableAsset != NULL) {
+        delete mResourceTableAsset;
+    }
+    if (mZipFile != NULL) {
+        delete mZipFile;
+        LOGV("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::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->getResourceTableAsset();
+}
+
+Asset* AssetManager::ZipSet::setZipResourceTable(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);
+}
+
+/*
+ * 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/utils/Binder.cpp b/libs/utils/Binder.cpp
new file mode 100644
index 0000000..37e4685
--- /dev/null
+++ b/libs/utils/Binder.cpp
@@ -0,0 +1,242 @@
+/*
+ * 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 <utils/Binder.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+
+#include <stdio.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
+{
+    return NULL;
+}
+
+BBinder* IBinder::localBinder()
+{
+    return NULL;
+}
+
+BpBinder* IBinder::remoteBinder()
+{
+    return NULL;
+}
+
+bool IBinder::checkSubclass(const void* /*subclassID*/) const
+{
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+class BBinder::Extras
+{
+public:
+    Mutex mLock;
+    BpBinder::ObjectManager mObjects;
+};
+
+// ---------------------------------------------------------------------------
+
+BBinder::BBinder()
+    : mExtras(NULL)
+{
+}
+
+bool BBinder::isBinderAlive() const
+{
+    return true;
+}
+
+status_t BBinder::pingBinder()
+{
+    return NO_ERROR;
+}
+
+String16 BBinder::getInterfaceDescriptor() const
+{
+    LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
+    return String16();
+}
+
+status_t BBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    data.setDataPosition(0);
+
+    status_t err = NO_ERROR;
+    switch (code) {
+        case PING_TRANSACTION:
+            reply->writeInt32(pingBinder());
+            break;
+        default:
+            err = onTransact(code, data, reply, flags);
+            break;
+    }
+
+    if (reply != NULL) {
+        reply->setDataPosition(0);
+    }
+
+    return err;
+}
+
+status_t BBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+void BBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    Extras* e = mExtras;
+
+    if (!e) {
+        e = new Extras;
+        if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
+                reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
+            delete e;
+            e = mExtras;
+        }
+        if (e == 0) return; // out of memory
+    }
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BBinder::findObject(const void* objectID) const
+{
+    Extras* e = mExtras;
+    if (!e) return NULL;
+
+    AutoMutex _l(e->mLock);
+    return e->mObjects.find(objectID);
+}
+
+void BBinder::detachObject(const void* objectID)
+{
+    Extras* e = mExtras;
+    if (!e) return;
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.detach(objectID);
+}
+
+BBinder* BBinder::localBinder()
+{
+    return this;
+}
+
+BBinder::~BBinder()
+{
+    if (mExtras) delete mExtras;
+}
+
+
+status_t BBinder::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case INTERFACE_TRANSACTION:
+            reply->writeString16(getInterfaceDescriptor());
+            return NO_ERROR;
+
+        case DUMP_TRANSACTION: {
+            int fd = data.readFileDescriptor();
+            int argc = data.readInt32();
+            Vector<String16> args;
+            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+               args.add(data.readString16());
+            }
+            return dump(fd, args);
+        }
+        default:
+            return UNKNOWN_TRANSACTION;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+enum {
+    // This is used to transfer ownership of the remote binder from
+    // the BpRefBase object holding it (when it is constructed), to the
+    // owner of the BpRefBase object when it first acquires that BpRefBase.
+    kRemoteAcquired = 0x00000001
+};
+
+BpRefBase::BpRefBase(const sp<IBinder>& o)
+    : mRemote(o.get()), mRefs(NULL), mState(0)
+{
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+
+    if (mRemote) {
+        mRemote->incStrong(this);           // Removed on first IncStrong().
+        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
+    }
+}
+
+BpRefBase::~BpRefBase()
+{
+    if (mRemote) {
+        if (!(mState&kRemoteAcquired)) {
+            mRemote->decStrong(this);
+        }
+        mRefs->decWeak(this);
+    }
+}
+
+void BpRefBase::onFirstRef()
+{
+    android_atomic_or(kRemoteAcquired, &mState);
+}
+
+void BpRefBase::onLastStrongRef(const void* id)
+{
+    if (mRemote) {
+        mRemote->decStrong(this);
+    }
+}
+
+bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return mRemote ? mRefs->attemptIncStrong(this) : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BpBinder.cpp b/libs/utils/BpBinder.cpp
new file mode 100644
index 0000000..69ab195
--- /dev/null
+++ b/libs/utils/BpBinder.cpp
@@ -0,0 +1,348 @@
+/*
+ * 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 "BpBinder"
+//#define LOG_NDEBUG 0
+
+#include <utils/BpBinder.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+
+//#undef LOGV
+//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BpBinder::ObjectManager::ObjectManager()
+{
+}
+
+BpBinder::ObjectManager::~ObjectManager()
+{
+    kill();
+}
+
+void BpBinder::ObjectManager::attach(
+    const void* objectID, void* object, void* cleanupCookie,
+    IBinder::object_cleanup_func func)
+{
+    entry_t e;
+    e.object = object;
+    e.cleanupCookie = cleanupCookie;
+    e.func = func;
+
+    if (mObjects.indexOfKey(objectID) >= 0) {
+        LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
+                objectID, this,  object);
+        return;
+    }
+
+    mObjects.add(objectID, e);
+}
+
+void* BpBinder::ObjectManager::find(const void* objectID) const
+{
+    const ssize_t i = mObjects.indexOfKey(objectID);
+    if (i < 0) return NULL;
+    return mObjects.valueAt(i).object;
+}
+
+void BpBinder::ObjectManager::detach(const void* objectID)
+{
+    mObjects.removeItem(objectID);
+}
+
+void BpBinder::ObjectManager::kill()
+{
+    const size_t N = mObjects.size();
+    LOGV("Killing %d objects in manager %p", N, this);
+    for (size_t i=0; i<N; i++) {
+        const entry_t& e = mObjects.valueAt(i);
+        if (e.func != NULL) {
+            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
+        }
+    }
+
+    mObjects.clear();
+}
+
+// ---------------------------------------------------------------------------
+
+BpBinder::BpBinder(int32_t handle)
+    : mHandle(handle)
+    , mAlive(1)
+    , mObitsSent(0)
+    , mObituaries(NULL)
+{
+    LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
+
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+    IPCThreadState::self()->incWeakHandle(handle);
+}
+
+String16 BpBinder::getInterfaceDescriptor() const
+{
+    String16 res;
+    Parcel send, reply;
+    status_t err = const_cast<BpBinder*>(this)->transact(
+            INTERFACE_TRANSACTION, send, &reply);
+    if (err == NO_ERROR) {
+        res = reply.readString16();
+    }
+    return res;
+}
+
+bool BpBinder::isBinderAlive() const
+{
+    return mAlive != 0;
+}
+
+status_t BpBinder::pingBinder()
+{
+    Parcel send;
+    Parcel reply;
+    status_t err = transact(PING_TRANSACTION, send, &reply);
+    if (err != NO_ERROR) return err;
+    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
+    return (status_t)reply.readInt32();
+}
+
+status_t BpBinder::dump(int fd, const Vector<String16>& args)
+{
+    Parcel send;
+    Parcel reply;
+    send.writeFileDescriptor(fd);
+    const size_t numArgs = args.size();
+    send.writeInt32(numArgs);
+    for (size_t i = 0; i < numArgs; i++) {
+        send.writeString16(args[i]);
+    }
+    status_t err = transact(DUMP_TRANSACTION, send, &reply);
+    return err;
+}
+
+status_t BpBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // Once a binder has died, it will never come back to life.
+    if (mAlive) {
+        status_t status = IPCThreadState::self()->transact(
+            mHandle, code, data, reply, flags);
+        if (status == DEAD_OBJECT) mAlive = 0;
+        return status;
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    Obituary ob;
+    ob.recipient = recipient;
+    ob.cookie = cookie;
+    ob.flags = flags;
+
+    LOG_ALWAYS_FATAL_IF(recipient == NULL,
+                        "linkToDeath(): recipient must be non-NULL");
+
+    {
+        AutoMutex _l(mLock);
+
+        if (!mObitsSent) {
+            if (!mObituaries) {
+                mObituaries = new Vector<Obituary>;
+                if (!mObituaries) {
+                    return NO_MEMORY;
+                }
+                LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
+                getWeakRefs()->incWeak(this);
+                IPCThreadState* self = IPCThreadState::self();
+                self->requestDeathNotification(mHandle, this);
+                self->flushCommands();
+            }
+            ssize_t res = mObituaries->add(ob);
+            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
+        }
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    AutoMutex _l(mLock);
+
+    if (mObitsSent) {
+        return DEAD_OBJECT;
+    }
+
+    const size_t N = mObituaries ? mObituaries->size() : 0;
+    for (size_t i=0; i<N; i++) {
+        const Obituary& obit = mObituaries->itemAt(i);
+        if ((obit.recipient == recipient
+                    || (recipient == NULL && obit.cookie == cookie))
+                && obit.flags == flags) {
+            const uint32_t allFlags = obit.flags|flags;
+            if (outRecipient != NULL) {
+                *outRecipient = mObituaries->itemAt(i).recipient;
+            }
+            mObituaries->removeAt(i);
+            if (mObituaries->size() == 0) {
+                LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
+                IPCThreadState* self = IPCThreadState::self();
+                self->clearDeathNotification(mHandle, this);
+                self->flushCommands();
+                delete mObituaries;
+                mObituaries = NULL;
+            }
+            return NO_ERROR;
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+void BpBinder::sendObituary()
+{
+    LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
+        this, mHandle, mObitsSent ? "true" : "false");
+
+    mAlive = 0;
+    if (mObitsSent) return;
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
+        IPCThreadState* self = IPCThreadState::self();
+        self->clearDeathNotification(mHandle, this);
+        self->flushCommands();
+        mObituaries = NULL;
+    }
+    mObitsSent = 1;
+    mLock.unlock();
+
+    LOGV("Reporting death of proxy %p for %d recipients\n",
+        this, obits ? obits->size() : 0);
+
+    if (obits != NULL) {
+        const size_t N = obits->size();
+        for (size_t i=0; i<N; i++) {
+            reportOneDeath(obits->itemAt(i));
+        }
+
+        delete obits;
+    }
+}
+
+void BpBinder::reportOneDeath(const Obituary& obit)
+{
+    sp<DeathRecipient> recipient = obit.recipient.promote();
+    LOGV("Reporting death to recipient: %p\n", recipient.get());
+    if (recipient == NULL) return;
+
+    recipient->binderDied(this);
+}
+
+
+void BpBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    AutoMutex _l(mLock);
+    LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
+    mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BpBinder::findObject(const void* objectID) const
+{
+    AutoMutex _l(mLock);
+    return mObjects.find(objectID);
+}
+
+void BpBinder::detachObject(const void* objectID)
+{
+    AutoMutex _l(mLock);
+    mObjects.detach(objectID);
+}
+
+BpBinder* BpBinder::remoteBinder()
+{
+    return this;
+}
+
+BpBinder::~BpBinder()
+{
+    LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
+
+    IPCThreadState* ipc = IPCThreadState::self();
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        if (ipc) ipc->clearDeathNotification(mHandle, this);
+        mObituaries = NULL;
+    }
+    mLock.unlock();
+
+    if (obits != NULL) {
+        // XXX Should we tell any remaining DeathRecipient
+        // objects that the last strong ref has gone away, so they
+        // are no longer linked?
+        delete obits;
+    }
+
+    if (ipc) {
+        ipc->expungeHandle(mHandle, this);
+        ipc->decWeakHandle(mHandle);
+    }
+}
+
+void BpBinder::onFirstRef()
+{
+    LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->incStrongHandle(mHandle);
+}
+
+void BpBinder::onLastStrongRef(const void* id)
+{
+    LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
+    IF_LOGV() {
+        printRefs();
+    }
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->decStrongHandle(mHandle);
+}
+
+bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
new file mode 100644
index 0000000..989662e
--- /dev/null
+++ b/libs/utils/BufferedTextOutput.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+#include <utils/BufferedTextOutput.h>
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <cutils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+struct BufferedTextOutput::BufferState : public RefBase
+{
+    BufferState(int32_t _seq)
+        : seq(_seq)
+        , buffer(NULL)
+        , bufferPos(0)
+        , bufferSize(0)
+        , atFront(true)
+        , indent(0)
+        , bundle(0) {
+    }
+    ~BufferState() {
+        free(buffer);
+    }
+    
+    status_t append(const char* txt, size_t len) {
+        if ((len+bufferPos) > bufferSize) {
+            void* b = realloc(buffer, ((len+bufferPos)*3)/2);
+            if (!b) return NO_MEMORY;
+            buffer = (char*)b;
+        }
+        memcpy(buffer+bufferPos, txt, len);
+        bufferPos += len;
+        return NO_ERROR;
+    }
+    
+    void restart() {
+        bufferPos = 0;
+        atFront = true;
+        if (bufferSize > 256) {
+            void* b = realloc(buffer, 256);
+            if (b) {
+                buffer = (char*)b;
+                bufferSize = 256;
+            }
+        }
+    }
+    
+    const int32_t seq;
+    char* buffer;
+    size_t bufferPos;
+    size_t bufferSize;
+    bool atFront;
+    int32_t indent;
+    int32_t bundle;
+};
+
+struct BufferedTextOutput::ThreadState
+{
+    Vector<sp<BufferedTextOutput::BufferState> > states;
+};
+
+static mutex_t          gMutex;
+
+static thread_store_t   tls;
+
+BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
+{
+    ThreadState*  ts = (ThreadState*) thread_store_get( &tls );
+    if (ts) return ts;
+    ts = new ThreadState;
+    thread_store_set( &tls, ts, threadDestructor );
+    return ts;
+}
+
+void BufferedTextOutput::threadDestructor(void *st)
+{
+    delete ((ThreadState*)st);
+}
+
+static volatile int32_t gSequence = 0;
+
+static volatile int32_t gFreeBufferIndex = -1;
+
+static int32_t allocBufferIndex()
+{
+    int32_t res = -1;
+    
+    mutex_lock(&gMutex);
+    
+    if (gFreeBufferIndex >= 0) {
+        res = gFreeBufferIndex;
+        gFreeBufferIndex = gTextBuffers[res];
+        gTextBuffers.editItemAt(res) = -1;
+
+    } else {
+        res = gTextBuffers.size();
+        gTextBuffers.add(-1);
+    }
+
+    mutex_unlock(&gMutex);
+    
+    return res;
+}
+
+static void freeBufferIndex(int32_t idx)
+{
+    mutex_lock(&gMutex);
+    gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
+    gFreeBufferIndex = idx;
+    mutex_unlock(&gMutex);
+}
+
+// ---------------------------------------------------------------------------
+
+BufferedTextOutput::BufferedTextOutput(uint32_t flags)
+    : mFlags(flags)
+    , mSeq(android_atomic_inc(&gSequence))
+    , mIndex(allocBufferIndex())
+{
+    mGlobalState = new BufferState(mSeq);
+    if (mGlobalState) mGlobalState->incStrong(this);
+}
+    
+BufferedTextOutput::~BufferedTextOutput()
+{
+    if (mGlobalState) mGlobalState->decStrong(this);
+    freeBufferIndex(mIndex);
+}
+
+status_t BufferedTextOutput::print(const char* txt, size_t len)
+{
+    //printf("BufferedTextOutput: printing %d\n", len);
+    
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    
+    const char* const end = txt+len;
+    
+    status_t err;
+
+    while (txt < end) {
+        // Find the next line.
+        const char* first = txt;
+        while (txt < end && *txt != '\n') txt++;
+        
+        // Include this and all following empty lines.
+        while (txt < end && *txt == '\n') txt++;
+        
+        // Special cases for first data on a line.
+        if (b->atFront) {
+            if (b->indent > 0) {
+                // If this is the start of a line, add the indent.
+                const char* prefix = stringForIndent(b->indent);
+                err = b->append(prefix, strlen(prefix));
+                if (err != NO_ERROR) return err;
+                
+            } else if (*(txt-1) == '\n' && !b->bundle) {
+                // Fast path: if we are not indenting or bundling, and
+                // have been given one or more complete lines, just write
+                // them out without going through the buffer.
+                
+                // Slurp up all of the lines.
+                const char* lastLine = txt+1;
+                while (txt < end) {
+                    if (*txt++ == '\n') lastLine = txt;
+                }
+                struct iovec vec;
+                vec.iov_base = (void*)first;
+                vec.iov_len = lastLine-first;
+                //printf("Writing %d bytes of data!\n", vec.iov_len);
+                writeLines(vec, 1);
+                txt = lastLine;
+                continue;
+            }
+        }
+        
+        // Append the new text to the buffer.
+        err = b->append(first, txt-first);
+        if (err != NO_ERROR) return err;
+        b->atFront = *(txt-1) == '\n';
+        
+        // If we have finished a line and are not bundling, write
+        // it out.
+        //printf("Buffer is now %d bytes\n", b->bufferPos);
+        if (b->atFront && !b->bundle) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            //printf("Writing %d bytes of data!\n", vec.iov_len);
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+void BufferedTextOutput::moveIndent(int delta)
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->indent += delta;
+    if (b->indent < 0) b->indent = 0;
+}
+
+void BufferedTextOutput::pushBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle++;
+}
+
+void BufferedTextOutput::popBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle--;
+    LOG_FATAL_IF(b->bundle < 0,
+        "TextOutput::popBundle() called more times than pushBundle()");
+    if (b->bundle < 0) b->bundle = 0;
+    
+    if (b->bundle == 0) {
+        // Last bundle, write out data if it is complete.  If it is not
+        // complete, don't write until the last line is done... this may
+        // or may not be the write thing to do, but it's the easiest.
+        if (b->bufferPos > 0 && b->atFront) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+}
+
+BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
+{
+    if ((mFlags&MULTITHREADED) != 0) {
+        ThreadState* ts = getThreadState();
+        if (ts) {
+            while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
+            BufferState* bs = ts->states[mIndex].get();
+            if (bs != NULL && bs->seq == mSeq) return bs;
+            
+            ts->states.editItemAt(mIndex) = new BufferState(mIndex);
+            bs = ts->states[mIndex].get();
+            if (bs != NULL) return bs;
+        }
+    }
+    
+    return mGlobalState;
+}
+
+}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
new file mode 100644
index 0000000..4968666
--- /dev/null
+++ b/libs/utils/CallStack.cpp
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CallStack"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if HAVE_DLADDR
+#include <dlfcn.h>
+#endif
+
+#if HAVE_CXXABI
+#include <cxxabi.h>
+#endif
+
+#include <unwind.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/CallStack.h>
+#include <utils/threads.h>
+
+
+/*****************************************************************************/
+namespace android {
+
+
+typedef struct {
+    size_t count;
+    size_t ignore;
+    const void** addrs;
+} stack_crawl_state_t;
+
+static
+_Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
+{
+    stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
+    if (state->count) {
+        void* ip = (void*)_Unwind_GetIP(context);
+        if (ip) {
+            if (state->ignore) {
+                state->ignore--;
+            } else {
+                state->addrs[0] = ip; 
+                state->addrs++;
+                state->count--;
+            }
+        }
+    }
+    return _URC_NO_REASON;
+}
+
+static
+int backtrace(const void** addrs, size_t ignore, size_t size)
+{
+    stack_crawl_state_t state;
+    state.count = size;
+    state.ignore = ignore;
+    state.addrs = addrs;
+    _Unwind_Backtrace(trace_function, (void*)&state);
+    return size - state.count;
+}
+
+/*****************************************************************************/
+
+static 
+const char *lookup_symbol(const void* addr, uint32_t *offset, char* name, size_t bufSize)
+{
+#if HAVE_DLADDR
+	Dl_info info;
+	if (dladdr(addr, &info)) {
+		*offset = (uint32_t)info.dli_saddr;
+		return info.dli_sname;
+	}
+#endif
+	return NULL;
+}
+
+static 
+int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
+{
+	size_t out_len = 0;
+#if HAVE_CXXABI
+	int status = 0;
+	char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
+	if (status == 0) {
+		// OK
+		if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
+		else out_len = 0;
+		free(demangled);
+	} else {
+		out_len = 0;
+	}
+#endif
+	return out_len;
+}
+
+/*****************************************************************************/
+
+class MapInfo {
+    struct mapinfo {
+        struct mapinfo *next;
+        unsigned start;
+        unsigned end;
+        char name[];
+    };
+
+    const char *map_to_name(unsigned pc, const char* def) {
+        mapinfo* mi = getMapInfoList();
+        while(mi) {
+            if ((pc >= mi->start) && (pc < mi->end))
+                return mi->name;
+            mi = mi->next;
+        }
+        return def;
+    }
+
+    mapinfo *parse_maps_line(char *line) {
+        mapinfo *mi;
+        int len = strlen(line);
+        if (len < 1) return 0;
+        line[--len] = 0;
+        if (len < 50) return 0;
+        if (line[20] != 'x') return 0;
+        mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
+        if (mi == 0) return 0;
+        mi->start = strtoul(line, 0, 16);
+        mi->end = strtoul(line + 9, 0, 16);
+        mi->next = 0;
+        strcpy(mi->name, line + 49);
+        return mi;
+    }
+
+    mapinfo* getMapInfoList() {
+        Mutex::Autolock _l(mLock);
+        if (milist == 0) {
+            char data[1024];
+            FILE *fp;
+            sprintf(data, "/proc/%d/maps", getpid());
+            fp = fopen(data, "r");
+            if (fp) {
+                while(fgets(data, 1024, fp)) {
+                    mapinfo *mi = parse_maps_line(data);
+                    if(mi) {
+                        mi->next = milist;
+                        milist = mi;
+                    }
+                }
+                fclose(fp);
+            }
+        }
+        return milist;
+    }
+    mapinfo*    milist;
+    Mutex       mLock;
+    static MapInfo sMapInfo;
+
+public:
+    MapInfo()
+     : milist(0) {
+    }
+
+    ~MapInfo() {
+        while (milist) {
+            mapinfo *next = milist->next;
+            free(milist);
+            milist = next;
+        }
+    }
+    
+    static const char *mapAddressToName(const void* pc, const char* def) {
+        return sMapInfo.map_to_name((unsigned)pc, def);
+    }
+
+};
+
+/*****************************************************************************/
+
+MapInfo MapInfo::sMapInfo;
+
+/*****************************************************************************/
+
+CallStack::CallStack()
+    : mCount(0)
+{
+}
+
+CallStack::CallStack(const CallStack& rhs)
+    : mCount(rhs.mCount)
+{
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+}
+
+CallStack::~CallStack()
+{
+}
+
+CallStack& CallStack::operator = (const CallStack& rhs)
+{
+    mCount = rhs.mCount;
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+    return *this;
+}
+
+bool CallStack::operator == (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return false;
+    return !mCount || (memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) == 0);
+}
+
+bool CallStack::operator != (const CallStack& rhs) const {
+    return !operator == (rhs);
+}
+
+bool CallStack::operator < (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount < rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) < 0;
+}
+
+bool CallStack::operator >= (const CallStack& rhs) const {
+    return !operator < (rhs);
+}
+
+bool CallStack::operator > (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount > rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) > 0;
+}
+
+bool CallStack::operator <= (const CallStack& rhs) const {
+    return !operator > (rhs);
+}
+
+const void* CallStack::operator [] (int index) const {
+    if (index >= int(mCount))
+        return 0;
+    return mStack[index];
+}
+
+
+void CallStack::clear()
+{
+    mCount = 0;
+}
+
+void CallStack::update(int32_t ignoreDepth, int32_t maxDepth)
+{
+    if (maxDepth > MAX_DEPTH)
+        maxDepth = MAX_DEPTH;
+    mCount = backtrace(mStack, ignoreDepth, maxDepth);
+}
+
+// Return the stack frame name on the designated level
+String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
+{
+    String8 res;
+    char namebuf[1024];
+    char tmp[256];
+    char tmp1[32];
+    char tmp2[32];
+    uint32_t offs;
+
+    const void* ip = mStack[level];
+    if (!ip) return res;
+
+    if (prefix) res.append(prefix);
+    snprintf(tmp1, 32, "#%02d  ", level);
+    res.append(tmp1);
+
+    const char* name = lookup_symbol(ip, &offs, namebuf, sizeof(namebuf));
+    if (name) {
+        if (linux_gcc_demangler(name, tmp, 256) != 0)
+            name = tmp;
+        snprintf(tmp1, 32, "0x%08x: <", (size_t)ip);
+        snprintf(tmp2, 32, ">+0x%08x", offs);
+        res.append(tmp1);
+        res.append(name);
+        res.append(tmp2);
+    } else { 
+        name = MapInfo::mapAddressToName(ip, "<unknown>");
+        snprintf(tmp, 256, "pc %08x  %s", (size_t)ip, name);
+        res.append(tmp);
+    }
+    res.append("\n");
+
+    return res;
+}
+
+// Dump a stack trace to the log
+void CallStack::dump(const char* prefix) const
+{
+    /* 
+     * Sending a single long log may be truncated since the stack levels can
+     * get very deep. So we request function names of each frame individually.
+     */
+    for (int i=0; i<int(mCount); i++) {
+        LOGD("%s", toStringSingleLevel(prefix, i).string());
+    }
+}
+
+// Return a string (possibly very long) containing the complete stack trace
+String8 CallStack::toString(const char* prefix) const
+{
+    String8 res;
+
+    for (int i=0; i<int(mCount); i++) {
+        res.append(toStringSingleLevel(prefix, i).string());
+    }
+
+    return res;
+}
+
+/*****************************************************************************/
+
+}; // namespace android
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
new file mode 100644
index 0000000..f7988ec
--- /dev/null
+++ b/libs/utils/Debug.cpp
@@ -0,0 +1,318 @@
+/*
+ * 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 <utils/Debug.h>
+
+#include <utils/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------
+
+static const char indentStr[] =
+"                                                                            "
+"                                                                            ";
+
+const char* stringForIndent(int32_t indentLevel)
+{
+    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
+    return indentStr + (off < 0 ? 0 : off);
+}
+
+// ---------------------------------------------------------------------
+
+static void defaultPrintFunc(void* cookie, const char* txt)
+{
+    printf("%s", txt);
+}
+
+// ---------------------------------------------------------------------
+
+static inline int isident(int c)
+{
+    return isalnum(c) || c == '_';
+}
+
+static inline bool isasciitype(char c)
+{
+    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
+    return false;
+}
+
+static inline char makehexdigit(uint32_t val)
+{
+    return "0123456789abcdef"[val&0xF];
+}
+
+static char* appendhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makehexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static inline char makeupperhexdigit(uint32_t val)
+{
+    return "0123456789ABCDEF"[val&0xF];
+}
+
+static char* appendupperhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makeupperhexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static char* appendcharornum(char c, char* out, bool skipzero = true)
+{
+    if (skipzero && c == 0) return out;
+
+    if (isasciitype(c)) {
+        *out++ = c;
+        return out;
+    }
+
+    *out++ = '\\';
+    *out++ = 'x';
+    *out++ = makehexdigit(c>>4);
+    *out++ = makehexdigit(c);
+    return out;
+}
+
+static char* typetostring(uint32_t type, char* out,
+                          bool fullContext = true,
+                          bool strict = false)
+{
+    char* pos = out;
+    char c[4];
+    c[0] = (char)((type>>24)&0xFF);
+    c[1] = (char)((type>>16)&0xFF);
+    c[2] = (char)((type>>8)&0xFF);
+    c[3] = (char)(type&0xFF);
+    bool valid;
+    if( !strict ) {
+        // now even less strict!
+        // valid = isasciitype(c[3]);
+        valid = true;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                //if (!isasciitype(c[i])) valid = false;
+            }
+            i++;
+        }
+        // if all zeros, not a valid type code.
+        if (zero) valid = false;
+    } else {
+        valid = isident(c[3]) ? true : false;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                if (!isident(c[i])) valid = false;
+            }
+            i++;
+        }
+    }
+    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
+        if( fullContext ) *pos++ = '\'';
+        pos = appendcharornum(c[0], pos);
+        pos = appendcharornum(c[1], pos);
+        pos = appendcharornum(c[2], pos);
+        pos = appendcharornum(c[3], pos);
+        if( fullContext ) *pos++ = '\'';
+        *pos = 0;
+        return pos;
+    }
+    
+    if( fullContext ) {
+        *pos++ = '0';
+        *pos++ = 'x';
+    }
+    return appendhexnum(type, pos);
+}
+
+void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
+{
+    char buffer[32];
+    char* end = typetostring(typeCode, buffer);
+    *end = 0;
+    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
+}
+
+void printHexData(int32_t indent, const void *buf, size_t length,
+    size_t bytesPerLine, int32_t singleLineBytesCutoff,
+    size_t alignment, bool cStyle,
+    debugPrintFunc func, void* cookie)
+{
+    if (alignment == 0) {
+        if (bytesPerLine >= 16) alignment = 4;
+        else if (bytesPerLine >= 8) alignment = 2;
+        else alignment = 1;
+    }
+    if (func == NULL) func = defaultPrintFunc;
+
+    size_t offset;
+    
+    unsigned char *pos = (unsigned char *)buf;
+    
+    if (pos == NULL) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(NULL)");
+        return;
+    }
+    
+    if (length == 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(empty)");
+        return;
+    }
+    
+    if ((int32_t)length < 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        char buf[64];
+        sprintf(buf, "(bad length: %d)", length);
+        func(cookie, buf);
+        return;
+    }
+    
+    char buffer[256];
+    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
+    
+    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
+    
+    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
+    bool newLine = false;
+    if (cStyle) {
+        indent++;
+        func(cookie, "{\n");
+        newLine = true;
+    } else if (!oneLine) {
+        func(cookie, "\n");
+        newLine = true;
+    }
+    
+    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
+        long remain = length;
+
+        char* c = buffer;
+        if (!oneLine && !cStyle) {
+            sprintf(c, "0x%08x: ", (int)offset);
+            c += 12;
+        }
+
+        size_t index;
+        size_t word;
+        
+        for (word = 0; word < bytesPerLine; ) {
+
+#ifdef HAVE_LITTLE_ENDIAN
+            const size_t startIndex = word+(alignment-(alignment?1:0));
+            const ssize_t dir = -1;
+#else
+            const size_t startIndex = word;
+            const ssize_t dir = 1;
+#endif
+
+            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
+            
+                if (!cStyle) {
+                    if (index == 0 && word > 0 && alignment > 0) {
+                        *c++ = ' ';
+                    }
+                
+                    if (remain-- > 0) {
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                    } else if (!oneLine) {
+                        *c++ = ' ';
+                        *c++ = ' ';
+                    }
+                } else {
+                    if (remain > 0) {
+                        if (index == 0 && word > 0) {
+                            *c++ = ',';
+                            *c++ = ' ';
+                        }
+                        if (index == 0) {
+                            *c++ = '0';
+                            *c++ = 'x';
+                        }
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                        remain--;
+                    }
+                }
+            }
+            
+            word += index;
+        }
+
+        if (!cStyle) {
+            remain = length;
+            *c++ = ' ';
+            *c++ = '\'';
+            for (index = 0; index < bytesPerLine; index++) {
+
+                if (remain-- > 0) {
+                    const unsigned char val = pos[index];
+                    *c++ = (val >= ' ' && val < 127) ? val : '.';
+                } else if (!oneLine) {
+                    *c++ = ' ';
+                }
+            }
+            
+            *c++ = '\'';
+            if (length > bytesPerLine) *c++ = '\n';
+        } else {
+            if (remain > 0) *c++ = ',';
+            *c++ = '\n';
+        }
+
+        if (newLine && indent) func(cookie, stringForIndent(indent));
+        *c = 0;
+        func(cookie, buffer);
+        newLine = true;
+        
+        if (length <= bytesPerLine) break;
+        length -= bytesPerLine;
+    }
+
+    if (cStyle) {
+        if (indent > 0) func(cookie, stringForIndent(indent-1));
+        func(cookie, "};");
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
new file mode 100644
index 0000000..e1ba9b2
--- /dev/null
+++ b/libs/utils/FileMap.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+//
+// Shared file mapping class.
+//
+
+#define LOG_TAG "filemap"
+
+#include <utils/FileMap.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_POSIX_FILEMAP
+#include <sys/mman.h>
+#endif
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*static*/ long FileMap::mPageSize = -1;
+
+
+/*
+ * Constructor.  Create an empty object.
+ */
+FileMap::FileMap(void)
+    : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0),
+      mDataPtr(NULL), mDataLength(0)
+{
+}
+
+/*
+ * Destructor.
+ */
+FileMap::~FileMap(void)
+{
+    assert(mRefCount == 0);
+
+    //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength);
+
+    mRefCount = -100;       // help catch double-free
+    if (mFileName != NULL) {
+        free(mFileName);
+    }
+#ifdef HAVE_POSIX_FILEMAP    
+    if (munmap(mBasePtr, mBaseLength) != 0) {
+        LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
+    }
+#endif
+#ifdef HAVE_WIN32_FILEMAP
+    if ( UnmapViewOfFile(mBasePtr) == 0) {
+        LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, 
+              GetLastError() );
+    }
+    CloseHandle(mFileMapping);
+    CloseHandle(mFileHandle);
+#endif
+}
+
+
+/*
+ * Create a new mapping on an open file.
+ *
+ * Closing the file descriptor does not unmap the pages, so we don't
+ * claim ownership of the fd.
+ *
+ * Returns "false" on failure.
+ */
+bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
+{
+#ifdef HAVE_WIN32_FILEMAP
+    int     adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    if (mPageSize == -1) {
+        SYSTEM_INFO  si;
+        
+        GetSystemInfo( &si );
+        mPageSize = si.dwAllocationGranularity;
+    }
+
+    DWORD  protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;
+    
+    mFileHandle  = (HANDLE) _get_osfhandle(fd);
+    mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);
+    if (mFileMapping == NULL) {
+        LOGE("CreateFileMapping(%p, %lx) failed with error %ld\n",
+              mFileHandle, protect, GetLastError() );
+        return false;
+    }
+    
+    adjust    = offset % mPageSize;
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+    
+    mBasePtr = MapViewOfFile( mFileMapping, 
+                              readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
+                              0,
+                              (DWORD)(adjOffset),
+                              adjLength );
+    if (mBasePtr == NULL) {
+        LOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n",
+              adjOffset, adjLength, GetLastError() );
+        CloseHandle(mFileMapping);
+        mFileMapping = INVALID_HANDLE_VALUE;
+        return false;
+    }
+#endif
+#ifdef HAVE_POSIX_FILEMAP
+    int     prot, flags, adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    void* ptr;
+
+    assert(mRefCount == 1);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(length > 0);
+
+    /* init on first use */
+    if (mPageSize == -1) {
+#if NOT_USING_KLIBC
+        mPageSize = sysconf(_SC_PAGESIZE);
+        if (mPageSize == -1) {
+            LOGE("could not get _SC_PAGESIZE\n");
+            return false;
+        }
+#else
+        /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */
+        mPageSize = 4096;
+#endif
+    }
+
+    adjust   = offset % mPageSize;
+try_again:
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+
+    flags = MAP_SHARED;
+    prot = PROT_READ;
+    if (!readOnly)
+        prot |= PROT_WRITE;
+
+    ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
+    if (ptr == MAP_FAILED) {
+    	// Cygwin does not seem to like file mapping files from an offset.
+    	// So if we fail, try again with offset zero
+    	if (adjOffset > 0) {
+    		adjust = offset;
+    		goto try_again;
+    	}
+    
+        LOGE("mmap(%ld,%ld) failed: %s\n",
+            (long) adjOffset, (long) adjLength, strerror(errno));
+        return false;
+    }
+    mBasePtr = ptr;
+#endif /* HAVE_POSIX_FILEMAP */
+
+    mFileName = origFileName != NULL ? strdup(origFileName) : NULL;
+    mBaseLength = adjLength;
+    mDataOffset = offset;
+    mDataPtr = (char*) mBasePtr + adjust;
+    mDataLength = length;
+
+    assert(mBasePtr != NULL);
+
+    LOGV("MAP: base %p/%d data %p/%d\n",
+        mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
+
+    return true;
+}
+
+/*
+ * Provide guidance to the system.
+ */
+int FileMap::advise(MapAdvice advice)
+{
+#if HAVE_MADVISE
+    int cc, sysAdvice;
+
+    switch (advice) {
+        case NORMAL:        sysAdvice = MADV_NORMAL;        break;
+        case RANDOM:        sysAdvice = MADV_RANDOM;        break;
+        case SEQUENTIAL:    sysAdvice = MADV_SEQUENTIAL;    break;
+        case WILLNEED:      sysAdvice = MADV_WILLNEED;      break;
+        case DONTNEED:      sysAdvice = MADV_DONTNEED;      break;
+        default:
+                            assert(false);
+                            return -1;
+    }
+
+    cc = madvise(mBasePtr, mBaseLength, sysAdvice);
+    if (cc != 0)
+        LOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno));
+    return cc;
+#else
+	return -1;
+#endif // HAVE_MADVISE
+}
diff --git a/libs/utils/IDataConnection.cpp b/libs/utils/IDataConnection.cpp
new file mode 100644
index 0000000..c6d49aa
--- /dev/null
+++ b/libs/utils/IDataConnection.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+
+#include <utils/IDataConnection.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+enum
+{
+    CONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+    DISCONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1
+};
+
+class BpDataConnection : public BpInterface<IDataConnection>
+{
+public:
+    BpDataConnection::BpDataConnection(const sp<IBinder>& impl)
+        : BpInterface<IDataConnection>(impl)
+    {
+    }
+
+	virtual void connect()
+	{
+		Parcel data, reply;
+        data.writeInterfaceToken(IDataConnection::descriptor());
+		remote()->transact(CONNECT_TRANSACTION, data, &reply);
+	}
+	
+	virtual void disconnect()
+	{
+		Parcel data, reply;
+		remote()->transact(DISCONNECT_TRANSACTION, data, &reply);
+	}
+};
+
+IMPLEMENT_META_INTERFACE(DataConnection, "android.utils.IDataConnection");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnDataConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code)
+    {
+		case CONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			connect();
+			return NO_ERROR;
+		}    
+		
+		case DISCONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			disconnect();
+			return NO_ERROR;
+		}
+       
+		default:
+			return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IInterface.cpp b/libs/utils/IInterface.cpp
new file mode 100644
index 0000000..6ea8178
--- /dev/null
+++ b/libs/utils/IInterface.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 <utils/IInterface.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IBinder> IInterface::asBinder()
+{
+    return this ? onAsBinder() : NULL;
+}
+
+sp<const IBinder> IInterface::asBinder() const
+{
+    return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IMemory.cpp b/libs/utils/IMemory.cpp
new file mode 100644
index 0000000..429bc2b
--- /dev/null
+++ b/libs/utils/IMemory.cpp
@@ -0,0 +1,486 @@
+/*
+ * 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 "IMemory"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <utils/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Parcel.h>
+#include <utils/CallStack.h>
+
+#define VERBOSE   0
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class HeapCache : public IBinder::DeathRecipient
+{
+public:
+    HeapCache();
+    virtual ~HeapCache();
+    
+    virtual void binderDied(const wp<IBinder>& who);
+
+    sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 
+    void pin_heap(const sp<IBinder>& binder); 
+    void free_heap(const sp<IBinder>& binder); 
+    sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
+    void dump_heaps();
+
+private:
+    // For IMemory.cpp
+    struct heap_info_t {
+        sp<IMemoryHeap> heap;
+        int32_t         count;
+    };
+
+    void free_heap(const wp<IBinder>& binder); 
+
+    Mutex mHeapCacheLock;
+    KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
+};
+
+static sp<HeapCache> gHeapCache = new HeapCache();
+
+/******************************************************************************/
+
+enum {
+    HEAP_ID = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemoryHeap : public BpInterface<IMemoryHeap>
+{
+public:
+    BpMemoryHeap(const sp<IBinder>& impl);
+    virtual ~BpMemoryHeap();
+
+    virtual int getHeapID() const;
+    virtual void* getBase() const;
+    virtual size_t getSize() const;
+    virtual uint32_t getFlags() const;
+
+private:
+    friend class IMemory;
+    friend class HeapCache;
+    
+    // for debugging in this module
+    static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
+        return gHeapCache->find_heap(binder);
+    }
+    static inline void free_heap(const sp<IBinder>& binder) {
+        gHeapCache->free_heap(binder);
+    }
+    static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) {
+        return gHeapCache->get_heap(binder);
+    }
+    static inline void dump_heaps() {
+        gHeapCache->dump_heaps();       
+    }
+    void inline pin_heap() const {
+        gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
+    }
+
+    void assertMapped() const;
+    void assertReallyMapped() const;
+    void pinHeap() const;
+
+    mutable volatile int32_t mHeapId;
+    mutable void*       mBase;
+    mutable size_t      mSize;
+    mutable uint32_t    mFlags;
+    mutable bool        mRealHeap;
+    mutable Mutex       mLock;
+};
+
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemory : public BpInterface<IMemory>
+{
+public:
+    BpMemory(const sp<IBinder>& impl);
+    virtual ~BpMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
+    
+private:
+    mutable sp<IMemoryHeap> mHeap;
+    mutable ssize_t mOffset;
+    mutable size_t mSize;
+};
+
+/******************************************************************************/
+
+void* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const
+{
+    sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
+    void* const base = realHeap->base();
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+void* IMemory::pointer() const {
+    ssize_t offset;
+    sp<IMemoryHeap> heap = getMemory(&offset);
+    void* const base = heap!=0 ? heap->base() : MAP_FAILED;
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+size_t IMemory::size() const {
+    size_t size;
+    getMemory(NULL, &size);
+    return size;
+}
+
+ssize_t IMemory::offset() const {
+    ssize_t offset;
+    getMemory(&offset);
+    return offset;
+}
+
+/******************************************************************************/
+
+BpMemory::BpMemory(const sp<IBinder>& impl)
+    : BpInterface<IMemory>(impl), mOffset(0), mSize(0)
+{
+}
+
+BpMemory::~BpMemory()
+{
+}
+
+sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (mHeap == 0) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
+        if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
+            sp<IBinder> heap = reply.readStrongBinder();
+            ssize_t o = reply.readInt32();
+            size_t s = reply.readInt32();
+            if (heap != 0) {
+                mHeap = interface_cast<IMemoryHeap>(heap);
+                if (mHeap != 0) {
+                    mOffset = o;
+                    mSize = s;
+                }
+            }
+        }
+    }
+    if (offset) *offset = mOffset;
+    if (size) *size = mSize;
+    return mHeap;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnMemory::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_MEMORY: {
+            CHECK_INTERFACE(IMemory, data, reply);
+            ssize_t offset;
+            size_t size;
+            reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
+            reply->writeInt32(offset);
+            reply->writeInt32(size);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+
+/******************************************************************************/
+
+BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
+    : BpInterface<IMemoryHeap>(impl),
+        mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false)
+{
+}
+
+BpMemoryHeap::~BpMemoryHeap() {
+    if (mHeapId != -1) {
+        close(mHeapId);
+        if (mRealHeap) {
+            // by construction we're the last one
+            if (mBase != MAP_FAILED) {
+                sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+
+                if (VERBOSE) {
+                    LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 
+                            binder.get(), this, mSize, mHeapId);
+                    CallStack stack;
+                    stack.update();
+                    stack.dump("callstack");
+                }
+
+                munmap(mBase, mSize);
+            }
+        } else {
+            // remove from list only if it was mapped before
+            sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertMapped() const
+{
+    if (mHeapId == -1) {
+        sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
+        sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
+        heap->assertReallyMapped();
+        if (heap->mBase != MAP_FAILED) {
+            Mutex::Autolock _l(mLock);
+            if (mHeapId == -1) {
+                mBase   = heap->mBase;
+                mSize   = heap->mSize;
+                android_atomic_write( dup( heap->mHeapId ), &mHeapId );
+            }
+        } else {
+            // something went wrong
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertReallyMapped() const
+{
+    if (mHeapId == -1) {
+
+        // remote call without mLock held, worse case scenario, we end up
+        // calling transact() from multiple threads, but that's not a problem,
+        // only mmap below must be in the critical section.
+        
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
+        status_t err = remote()->transact(HEAP_ID, data, &reply);
+        int parcel_fd = reply.readFileDescriptor();
+        ssize_t size = reply.readInt32();
+        uint32_t flags = reply.readInt32();
+
+        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
+                asBinder().get(), parcel_fd, size, err, strerror(-err));
+
+        int fd = dup( parcel_fd );
+        LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
+                parcel_fd, size, err, strerror(errno));
+
+        int access = PROT_READ;
+        if (!(flags & READ_ONLY)) {
+            access |= PROT_WRITE;
+        }
+
+        Mutex::Autolock _l(mLock);
+        if (mHeapId == -1) {
+            mRealHeap = true;
+            mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
+            if (mBase == MAP_FAILED) {
+                LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
+                        asBinder().get(), size, fd, strerror(errno));
+                close(fd);
+            } else {
+                if (flags & MAP_ONCE) {
+                    //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
+                    //        asBinder().get(), size, fd);
+                    pin_heap();
+                }
+                mSize = size;
+                mFlags = flags;
+                android_atomic_write(fd, &mHeapId);
+            }
+        }
+    }
+}
+
+int BpMemoryHeap::getHeapID() const {
+    assertMapped();
+    return mHeapId;
+}
+
+void* BpMemoryHeap::getBase() const {
+    assertMapped();
+    return mBase;
+}
+
+size_t BpMemoryHeap::getSize() const {
+    assertMapped();
+    return mSize;
+}
+
+uint32_t BpMemoryHeap::getFlags() const {
+    assertMapped();
+    return mFlags;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
+
+status_t BnMemoryHeap::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+       case HEAP_ID: {
+            CHECK_INTERFACE(IMemoryHeap, data, reply);
+            reply->writeFileDescriptor(getHeapID());
+            reply->writeInt32(getSize());
+            reply->writeInt32(getFlags());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+/*****************************************************************************/
+
+HeapCache::HeapCache()
+    : DeathRecipient()
+{
+}
+
+HeapCache::~HeapCache()
+{
+}
+
+void HeapCache::binderDied(const wp<IBinder>& binder)
+{
+    //LOGD("binderDied binder=%p", binder.unsafe_get());
+    free_heap(binder); 
+}
+
+sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info = mHeapCache.editValueAt(i);
+        LOGD_IF(VERBOSE,
+                "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                binder.get(), info.heap.get(),
+                static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                info.count);
+        android_atomic_inc(&info.count);
+        return info.heap;
+    } else {
+        heap_info_t info;
+        info.heap = interface_cast<IMemoryHeap>(binder);
+        info.count = 1;
+        //LOGD("adding binder=%p, heap=%p, count=%d",
+        //      binder.get(), info.heap.get(), info.count);
+        mHeapCache.add(binder, info);
+        return info.heap;
+    }
+}
+
+void HeapCache::pin_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info(mHeapCache.editValueAt(i));
+        android_atomic_inc(&info.count);
+        binder->linkToDeath(this);
+    } else {
+        LOGE("pin_heap binder=%p not found!!!", binder.get());
+    }    
+}
+
+void HeapCache::free_heap(const sp<IBinder>& binder)  {
+    free_heap( wp<IBinder>(binder) );
+}
+
+void HeapCache::free_heap(const wp<IBinder>& binder) 
+{
+    sp<IMemoryHeap> rel;
+    {
+        Mutex::Autolock _l(mHeapCacheLock);
+        ssize_t i = mHeapCache.indexOfKey(binder);
+        if (i>=0) {
+            heap_info_t& info(mHeapCache.editValueAt(i));
+            int32_t c = android_atomic_dec(&info.count);
+            if (c == 1) {
+                LOGD_IF(VERBOSE,
+                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                        binder.unsafe_get(), info.heap.get(),
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                        info.count);
+                rel = mHeapCache.valueAt(i).heap;
+                mHeapCache.removeItemsAt(i);
+            }
+        } else {
+            LOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
+        }
+    }
+}
+
+sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
+{
+    sp<IMemoryHeap> realHeap;
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0)   realHeap = mHeapCache.valueAt(i).heap;
+    else        realHeap = interface_cast<IMemoryHeap>(binder);
+    return realHeap;
+}
+
+void HeapCache::dump_heaps() 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    int c = mHeapCache.size();
+    for (int i=0 ; i<c ; i++) {
+        const heap_info_t& info = mHeapCache.valueAt(i);
+        BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
+        LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
+                mHeapCache.keyAt(i).unsafe_get(),
+                info.heap.get(), info.count, 
+                h->mHeapId, h->mBase, h->mSize);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp
new file mode 100644
index 0000000..ca49d9a
--- /dev/null
+++ b/libs/utils/IPCThreadState.cpp
@@ -0,0 +1,1007 @@
+/*
+ * 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 <utils/IPCThreadState.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+
+#if LOG_NDEBUG
+
+#define IF_LOG_TRANSACTIONS() if (false)
+#define IF_LOG_COMMANDS() if (false)
+#define LOG_REMOTEREFS(...) 
+#define IF_LOG_REMOTEREFS() if (false)
+#define LOG_THREADPOOL(...) 
+#define LOG_ONEWAY(...) 
+
+#else
+
+#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
+#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
+#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
+#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
+#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
+#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
+
+#endif
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static const char* getReturnString(size_t idx);
+static const char* getCommandString(size_t idx);
+static const void* printReturnCommand(TextOutput& out, const void* _cmd);
+static const void* printCommand(TextOutput& out, const void* _cmd);
+
+// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
+// conditionals don't get stripped...  but that is probably what we want.
+#if !LOG_NDEBUG
+static const char *kReturnStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BR_OK",
+    "BR_TIMEOUT",
+    "BR_WAKEUP",
+    "BR_TRANSACTION",
+    "BR_REPLY",
+    "BR_ACQUIRE_RESULT",
+    "BR_DEAD_REPLY",
+    "BR_TRANSACTION_COMPLETE",
+    "BR_INCREFS",
+    "BR_ACQUIRE",
+    "BR_RELEASE",
+    "BR_DECREFS",
+    "BR_ATTEMPT_ACQUIRE",
+    "BR_EVENT_OCCURRED",
+    "BR_NOOP",
+    "BR_SPAWN_LOOPER",
+    "BR_FINISHED",
+    "BR_DEAD_BINDER",
+    "BR_CLEAR_DEATH_NOTIFICATION_DONE"
+#endif
+};
+
+static const char *kCommandStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BC_NOOP",
+    "BC_TRANSACTION",
+    "BC_REPLY",
+    "BC_ACQUIRE_RESULT",
+    "BC_FREE_BUFFER",
+    "BC_TRANSACTION_COMPLETE",
+    "BC_INCREFS",
+    "BC_ACQUIRE",
+    "BC_RELEASE",
+    "BC_DECREFS",
+    "BC_INCREFS_DONE",
+    "BC_ACQUIRE_DONE",
+    "BC_ATTEMPT_ACQUIRE",
+    "BC_RETRIEVE_ROOT_OBJECT",
+    "BC_SET_THREAD_ENTRY",
+    "BC_REGISTER_LOOPER",
+    "BC_ENTER_LOOPER",
+    "BC_EXIT_LOOPER",
+    "BC_SYNC",
+    "BC_STOP_PROCESS",
+    "BC_STOP_SELF",
+    "BC_REQUEST_DEATH_NOTIFICATION",
+    "BC_CLEAR_DEATH_NOTIFICATION",
+    "BC_DEAD_BINDER_DONE"
+#endif
+};
+
+static const char* getReturnString(size_t idx)
+{
+    if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
+        return kReturnStrings[idx];
+    else
+        return "unknown";
+}
+
+static const char* getCommandString(size_t idx)
+{
+    if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
+        return kCommandStrings[idx];
+    else
+        return "unknown";
+}
+
+static const void* printBinderTransactionData(TextOutput& out, const void* data)
+{
+    const binder_transaction_data* btd =
+        (const binder_transaction_data*)data;
+    out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
+        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
+        << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
+        << " bytes)" << endl
+        << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
+        << " bytes)" << endl;
+    return btd+1;
+}
+
+static const void* printReturnCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code == BR_ERROR) {
+        out << "BR_ERROR: " << (void*)(*cmd++) << endl;
+        return cmd;
+    } else if (code < 0 || code >= N) {
+        out << "Unknown reply: " << code << endl;
+        return cmd;
+    }
+    
+    out << kReturnStrings[code];
+    switch (code) {
+        case BR_TRANSACTION:
+        case BR_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BR_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BR_INCREFS:
+        case BR_ACQUIRE:
+        case BR_RELEASE:
+        case BR_DECREFS: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+    
+        case BR_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c
+                << "), pri=" << p;
+        } break;
+
+        case BR_DEAD_BINDER:
+        case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+
+static const void* printCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code < 0 || code >= N) {
+        out << "Unknown command: " << code << endl;
+        return cmd;
+    }
+    
+    out << kCommandStrings[code];
+    switch (code) {
+        case BC_TRANSACTION:
+        case BC_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BC_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BC_FREE_BUFFER: {
+            const int32_t buf = *cmd++;
+            out << ": buffer=" << (void*)buf;
+        } break;
+        
+        case BC_INCREFS:
+        case BC_ACQUIRE:
+        case BC_RELEASE:
+        case BC_DECREFS: {
+            const int32_t d = *cmd++;
+            out << ": descriptor=" << (void*)d;
+        } break;
+    
+        case BC_INCREFS_DONE:
+        case BC_ACQUIRE_DONE: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+        
+        case BC_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t d = *cmd++;
+            out << ": decriptor=" << (void*)d << ", pri=" << p;
+        } break;
+        
+        case BC_REQUEST_DEATH_NOTIFICATION:
+        case BC_CLEAR_DEATH_NOTIFICATION: {
+            const int32_t h = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": handle=" << h << " (death cookie " << (void*)c << ")";
+        } break;
+
+        case BC_DEAD_BINDER_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+#endif
+
+static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool gHaveTLS = false;
+static pthread_key_t gTLS = 0;
+static bool gShutdown = false;
+
+IPCThreadState* IPCThreadState::self()
+{
+    if (gHaveTLS) {
+restart:
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        if (st) return st;
+        return new IPCThreadState;
+    }
+    
+    if (gShutdown) return NULL;
+    
+    pthread_mutex_lock(&gTLSMutex);
+    if (!gHaveTLS) {
+        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
+            pthread_mutex_unlock(&gTLSMutex);
+            return NULL;
+        }
+        gHaveTLS = true;
+    }
+    pthread_mutex_unlock(&gTLSMutex);
+    goto restart;
+}
+
+void IPCThreadState::shutdown()
+{
+    gShutdown = true;
+    
+    if (gHaveTLS) {
+        // XXX Need to wait for all thread pool threads to exit!
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
+        if (st) {
+            delete st;
+            pthread_setspecific(gTLS, NULL);
+        }
+        gHaveTLS = false;
+    }
+}
+
+sp<ProcessState> IPCThreadState::process()
+{
+    return mProcess;
+}
+
+status_t IPCThreadState::clearLastError()
+{
+    const status_t err = mLastError;
+    mLastError = NO_ERROR;
+    return err;
+}
+
+int IPCThreadState::getCallingPid()
+{
+    return mCallingPid;
+}
+
+int IPCThreadState::getCallingUid()
+{
+    return mCallingUid;
+}
+
+int64_t IPCThreadState::clearCallingIdentity()
+{
+    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+    clearCaller();
+    return token;
+}
+
+void IPCThreadState::restoreCallingIdentity(int64_t token)
+{
+    mCallingUid = (int)(token>>32);
+    mCallingPid = (int)token;
+}
+
+void IPCThreadState::clearCaller()
+{
+    if (mProcess->supportsProcesses()) {
+        mCallingPid = getpid();
+        mCallingUid = getuid();
+    } else {
+        mCallingPid = -1;
+        mCallingUid = -1;
+    }
+}
+
+void IPCThreadState::flushCommands()
+{
+    if (mProcess->mDriverFD <= 0)
+        return;
+    talkWithDriver(false);
+}
+
+void IPCThreadState::joinThreadPool(bool isMain)
+{
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
+
+    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+    
+    status_t result;
+    do {
+        int32_t cmd;
+        result = talkWithDriver();
+        if (result >= NO_ERROR) {
+            size_t IN = mIn.dataAvail();
+            if (IN < sizeof(int32_t)) continue;
+            cmd = mIn.readInt32();
+            IF_LOG_COMMANDS() {
+                alog << "Processing top-level Command: "
+                    << getReturnString(cmd) << endl;
+            }
+            result = executeCommand(cmd);
+        }
+        
+        // Let this thread exit the thread pool if it is no longer
+        // needed and it is not the main process thread.
+        if(result == TIMED_OUT && !isMain) {
+            break;
+        }
+    } while (result != -ECONNREFUSED && result != -EBADF);
+
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
+        (void*)pthread_self(), getpid(), (void*)result);
+    
+    mOut.writeInt32(BC_EXIT_LOOPER);
+    talkWithDriver(false);
+}
+
+void IPCThreadState::stopProcess(bool immediate)
+{
+    //LOGI("**** STOPPING PROCESS");
+    flushCommands();
+    int fd = mProcess->mDriverFD;
+    mProcess->mDriverFD = -1;
+    close(fd);
+    //kill(getpid(), SIGKILL);
+}
+
+status_t IPCThreadState::transact(int32_t handle,
+                                  uint32_t code, const Parcel& data,
+                                  Parcel* reply, uint32_t flags)
+{
+    status_t err = data.errorCheck();
+
+    flags |= TF_ACCEPT_FDS;
+
+    IF_LOG_TRANSACTIONS() {
+        TextOutput::Bundle _b(alog);
+        alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
+            << handle << " / code " << TypeCode(code) << ": "
+            << indent << data << dedent << endl;
+    }
+    
+    if (err == NO_ERROR) {
+        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
+            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
+        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
+    }
+    
+    if (err != NO_ERROR) {
+        if (reply) reply->setError(err);
+        return (mLastError = err);
+    }
+    
+    if ((flags & TF_ONE_WAY) == 0) {
+        if (reply) {
+            err = waitForResponse(reply);
+        } else {
+            Parcel fakeReply;
+            err = waitForResponse(&fakeReply);
+        }
+        
+        IF_LOG_TRANSACTIONS() {
+            TextOutput::Bundle _b(alog);
+            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
+                << handle << ": ";
+            if (reply) alog << indent << *reply << dedent << endl;
+            else alog << "(none requested)" << endl;
+        }
+    } else {
+        err = waitForResponse(NULL, NULL);
+    }
+    
+    return err;
+}
+
+void IPCThreadState::incStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_ACQUIRE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_RELEASE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::incWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_INCREFS);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_DECREFS);
+    mOut.writeInt32(handle);
+}
+
+status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
+{
+    mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
+    mOut.writeInt32(0); // xxx was thread priority
+    mOut.writeInt32(handle);
+    status_t result = UNKNOWN_ERROR;
+    
+    waitForResponse(NULL, &result);
+    
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
+        handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
+#endif
+    
+    return result;
+}
+
+void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
+{
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::expungeHandle(%ld)\n", handle);
+#endif
+    self()->mProcess->expungeHandle(handle, binder);
+}
+
+status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+IPCThreadState::IPCThreadState()
+    : mProcess(ProcessState::self())
+{
+    pthread_setspecific(gTLS, this);
+        clearCaller();
+    mIn.setDataCapacity(256);
+    mOut.setDataCapacity(256);
+}
+
+IPCThreadState::~IPCThreadState()
+{
+}
+
+status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
+{
+    status_t err;
+    status_t statusBuffer;
+    err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
+    if (err < NO_ERROR) return err;
+    
+    return waitForResponse(NULL, NULL);
+}
+
+status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
+{
+    int32_t cmd;
+    int32_t err;
+
+    while (1) {
+        if ((err=talkWithDriver()) < NO_ERROR) break;
+        err = mIn.errorCheck();
+        if (err < NO_ERROR) break;
+        if (mIn.dataAvail() == 0) continue;
+        
+        cmd = mIn.readInt32();
+        
+        IF_LOG_COMMANDS() {
+            alog << "Processing waitForResponse Command: "
+                << getReturnString(cmd) << endl;
+        }
+
+        switch (cmd) {
+        case BR_TRANSACTION_COMPLETE:
+            if (!reply && !acquireResult) goto finish;
+            break;
+        
+        case BR_DEAD_REPLY:
+            err = DEAD_OBJECT;
+            goto finish;
+
+        case BR_FAILED_REPLY:
+            err = FAILED_TRANSACTION;
+            goto finish;
+        
+        case BR_ACQUIRE_RESULT:
+            {
+                LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
+                const int32_t result = mIn.readInt32();
+                if (!acquireResult) continue;
+                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
+            }
+            goto finish;
+        
+        case BR_REPLY:
+            {
+                binder_transaction_data tr;
+                err = mIn.read(&tr, sizeof(tr));
+                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
+                if (err != NO_ERROR) goto finish;
+
+                if (reply) {
+                    if ((tr.flags & TF_STATUS_CODE) == 0) {
+                        reply->ipcSetDataReference(
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t),
+                            freeBuffer, this);
+                    } else {
+                        err = *static_cast<const status_t*>(tr.data.ptr.buffer);
+                        freeBuffer(NULL,
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t), this);
+                    }
+                } else {
+                    freeBuffer(NULL,
+                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                        tr.data_size,
+                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                        tr.offsets_size/sizeof(size_t), this);
+                    continue;
+                }
+            }
+            goto finish;
+
+        default:
+            err = executeCommand(cmd);
+            if (err != NO_ERROR) goto finish;
+            break;
+        }
+    }
+
+finish:
+    if (err != NO_ERROR) {
+        if (acquireResult) *acquireResult = err;
+        if (reply) reply->setError(err);
+        mLastError = err;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::talkWithDriver(bool doReceive)
+{
+    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
+    
+    binder_write_read bwr;
+    
+    // Is the read buffer empty?
+    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
+    
+    // We don't want to write anything if we are still reading
+    // from data left in the input buffer and the caller
+    // has requested to read the next data.
+    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
+    
+    bwr.write_size = outAvail;
+    bwr.write_buffer = (long unsigned int)mOut.data();
+
+    // This is what we'll read.
+    if (doReceive && needRead) {
+        bwr.read_size = mIn.dataCapacity();
+        bwr.read_buffer = (long unsigned int)mIn.data();
+    } else {
+        bwr.read_size = 0;
+    }
+    
+    IF_LOG_COMMANDS() {
+        TextOutput::Bundle _b(alog);
+        if (outAvail != 0) {
+            alog << "Sending commands to driver: " << indent;
+            const void* cmds = (const void*)bwr.write_buffer;
+            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
+            alog << HexDump(cmds, bwr.write_size) << endl;
+            while (cmds < end) cmds = printCommand(alog, cmds);
+            alog << dedent;
+        }
+        alog << "Size of receive buffer: " << bwr.read_size
+            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
+    }
+    
+    // Return immediately if there is nothing to do.
+    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
+    
+    bwr.write_consumed = 0;
+    bwr.read_consumed = 0;
+    status_t err;
+    do {
+        IF_LOG_COMMANDS() {
+            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
+        }
+#if defined(HAVE_ANDROID_OS)
+        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
+            err = NO_ERROR;
+        else
+            err = -errno;
+#else
+        err = INVALID_OPERATION;
+#endif
+        IF_LOG_COMMANDS() {
+            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
+        }
+    } while (err == -EINTR);
+    
+    IF_LOG_COMMANDS() {
+        alog << "Our err: " << (void*)err << ", write consumed: "
+            << bwr.write_consumed << " (of " << mOut.dataSize()
+			<< "), read consumed: " << bwr.read_consumed << endl;
+    }
+
+    if (err >= NO_ERROR) {
+        if (bwr.write_consumed > 0) {
+            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
+                mOut.remove(0, bwr.write_consumed);
+            else
+                mOut.setDataSize(0);
+        }
+        if (bwr.read_consumed > 0) {
+            mIn.setDataSize(bwr.read_consumed);
+            mIn.setDataPosition(0);
+        }
+        IF_LOG_COMMANDS() {
+            TextOutput::Bundle _b(alog);
+            alog << "Remaining data size: " << mOut.dataSize() << endl;
+            alog << "Received commands from driver: " << indent;
+            const void* cmds = mIn.data();
+            const void* end = mIn.data() + mIn.dataSize();
+            alog << HexDump(cmds, mIn.dataSize()) << endl;
+            while (cmds < end) cmds = printReturnCommand(alog, cmds);
+            alog << dedent;
+        }
+        return NO_ERROR;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
+    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
+{
+    binder_transaction_data tr;
+
+    tr.target.handle = handle;
+    tr.code = code;
+    tr.flags = binderFlags;
+    
+    const status_t err = data.errorCheck();
+    if (err == NO_ERROR) {
+        tr.data_size = data.ipcDataSize();
+        tr.data.ptr.buffer = data.ipcData();
+        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
+        tr.data.ptr.offsets = data.ipcObjects();
+    } else if (statusBuffer) {
+        tr.flags |= TF_STATUS_CODE;
+        *statusBuffer = err;
+        tr.data_size = sizeof(status_t);
+        tr.data.ptr.buffer = statusBuffer;
+        tr.offsets_size = 0;
+        tr.data.ptr.offsets = NULL;
+    } else {
+        return (mLastError = err);
+    }
+    
+    mOut.writeInt32(cmd);
+    mOut.write(&tr, sizeof(tr));
+    
+    return NO_ERROR;
+}
+
+sp<BBinder> the_context_object;
+
+void setTheContextObject(sp<BBinder> obj)
+{
+    the_context_object = obj;
+}
+
+status_t IPCThreadState::executeCommand(int32_t cmd)
+{
+    BBinder* obj;
+    RefBase::weakref_type* refs;
+    status_t result = NO_ERROR;
+    
+    switch (cmd) {
+    case BR_ERROR:
+        result = mIn.readInt32();
+        break;
+        
+    case BR_OK:
+        break;
+        
+    case BR_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        obj->incStrong(mProcess.get());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mOut.writeInt32(BC_ACQUIRE_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_RELEASE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_RELEASE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
+            obj->printRefs();
+        }
+        obj->decStrong(mProcess.get());
+        break;
+        
+    case BR_INCREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        refs->incWeak(mProcess.get());
+        mOut.writeInt32(BC_INCREFS_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_DECREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        // NOTE: This assertion is not valid, because the object may no
+        // longer exist (thus the (BBinder*)cast above resulting in a different
+        // memory address).
+        //LOG_ASSERT(refs->refBase() == obj,
+        //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
+        //           refs, obj, refs->refBase());
+        refs->decWeak(mProcess.get());
+        break;
+        
+    case BR_ATTEMPT_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+         
+        {
+            const bool success = refs->attemptIncStrong(mProcess.get());
+            LOG_ASSERT(success && refs->refBase() == obj,
+                       "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                       refs, obj, refs->refBase());
+            
+            mOut.writeInt32(BC_ACQUIRE_RESULT);
+            mOut.writeInt32((int32_t)success);
+        }
+        break;
+    
+    case BR_TRANSACTION:
+        {
+            binder_transaction_data tr;
+            result = mIn.read(&tr, sizeof(tr));
+            LOG_ASSERT(result == NO_ERROR,
+                "Not enough command data for brTRANSACTION");
+            if (result != NO_ERROR) break;
+            
+            Parcel buffer;
+            buffer.ipcSetDataReference(
+                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                tr.data_size,
+                reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                tr.offsets_size/sizeof(size_t), freeBuffer, this);
+            
+            const pid_t origPid = mCallingPid;
+            const uid_t origUid = mCallingUid;
+            
+            mCallingPid = tr.sender_pid;
+            mCallingUid = tr.sender_euid;
+            
+            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
+            
+            Parcel reply;
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BR_TRANSACTION thr " << (void*)pthread_self()
+                    << " / obj " << tr.target.ptr << " / code "
+                    << TypeCode(tr.code) << ": " << indent << buffer
+                    << dedent << endl
+                    << "Data addr = "
+                    << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
+                    << ", offsets addr="
+                    << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
+            }
+            if (tr.target.ptr) {
+                sp<BBinder> b((BBinder*)tr.cookie);
+                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+                
+            } else {
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+            }
+            
+            //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
+            //     mCallingPid, origPid, origUid);
+            
+            if ((tr.flags & TF_ONE_WAY) == 0) {
+                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
+                sendReply(reply, 0);
+            } else {
+                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
+            }
+            
+            mCallingPid = origPid;
+            mCallingUid = origUid;
+            
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
+                    << tr.target.ptr << ": " << indent << reply << dedent << endl;
+            }
+            
+        }
+        break;
+    
+    case BR_DEAD_BINDER:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->sendObituary();
+            mOut.writeInt32(BC_DEAD_BINDER_DONE);
+            mOut.writeInt32((int32_t)proxy);
+        } break;
+        
+    case BR_CLEAR_DEATH_NOTIFICATION_DONE:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->getWeakRefs()->decWeak(proxy);
+        } break;
+        
+    case BR_FINISHED:
+        result = TIMED_OUT;
+        break;
+        
+    case BR_NOOP:
+        break;
+        
+    case BR_SPAWN_LOOPER:
+        mProcess->spawnPooledThread(false);
+        break;
+        
+    default:
+        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
+        result = UNKNOWN_ERROR;
+        break;
+    }
+
+    if (result != NO_ERROR) {
+        mLastError = result;
+    }
+    
+    return result;
+}
+
+void IPCThreadState::threadDestructor(void *st)
+{
+	IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+	if (self) {
+		self->flushCommands();
+#if defined(HAVE_ANDROID_OS)
+        ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
+#endif
+		delete self;
+	}
+}
+
+
+void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
+                                const size_t* objects, size_t objectsSize,
+                                void* cookie)
+{
+    //LOGI("Freeing parcel %p", &parcel);
+    IF_LOG_COMMANDS() {
+        alog << "Writing BC_FREE_BUFFER for " << data << endl;
+    }
+    LOG_ASSERT(data != NULL, "Called with NULL data");
+    if (parcel != NULL) parcel->closeFileDescriptors();
+    IPCThreadState* state = self();
+    state->mOut.writeInt32(BC_FREE_BUFFER);
+    state->mOut.writeInt32((int32_t)data);
+}
+
+}; // namespace android
diff --git a/libs/utils/IPermissionController.cpp b/libs/utils/IPermissionController.cpp
new file mode 100644
index 0000000..f01d38f
--- /dev/null
+++ b/libs/utils/IPermissionController.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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 "PermissionController"
+
+#include <utils/IPermissionController.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/utils/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpPermissionController : public BpInterface<IPermissionController>
+{
+public:
+    BpPermissionController(const sp<IBinder>& impl)
+        : BpInterface<IPermissionController>(impl)
+    {
+    }
+        
+    virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
+        data.writeString16(permission);
+        data.writeInt32(pid);
+        data.writeInt32(uid);
+        remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readInt32() != 0) return 0;
+        return reply.readInt32() != 0;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnPermissionController::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("PermissionController received: "); data.print();
+    switch(code) {
+        case CHECK_PERMISSION_TRANSACTION: {
+            CHECK_INTERFACE(IPermissionController, data, reply);
+            String16 permission = data.readString16();
+            int32_t pid = data.readInt32();
+            int32_t uid = data.readInt32();
+            bool res = checkPermission(permission, pid, uid);
+            // write exception
+            reply->writeInt32(0);
+            reply->writeInt32(res ? 1 : 0);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/IServiceManager.cpp b/libs/utils/IServiceManager.cpp
new file mode 100644
index 0000000..9beeadd
--- /dev/null
+++ b/libs/utils/IServiceManager.cpp
@@ -0,0 +1,230 @@
+/*
+ * 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 "ServiceManager"
+
+#include <utils/IServiceManager.h>
+
+#include <utils/Debug.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+#include <utils/SystemClock.h>
+
+#include <private/utils/Static.h>
+
+#include <unistd.h>
+
+namespace android {
+
+sp<IServiceManager> defaultServiceManager()
+{
+    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
+    
+    {
+        AutoMutex _l(gDefaultServiceManagerLock);
+        if (gDefaultServiceManager == NULL) {
+            gDefaultServiceManager = interface_cast<IServiceManager>(
+                ProcessState::self()->getContextObject(NULL));
+        }
+    }
+    
+    return gDefaultServiceManager;
+}
+
+bool checkCallingPermission(const String16& permission)
+{
+    return checkCallingPermission(permission, NULL, NULL);
+}
+
+static String16 _permission("permission");
+
+bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
+{
+    IPCThreadState* ipcState = IPCThreadState::self();
+    int32_t pid = ipcState->getCallingPid();
+    int32_t uid = ipcState->getCallingUid();
+    if (outPid) *outPid = pid;
+    if (outUid) *outUid= uid;
+    
+    sp<IPermissionController> pc;
+    gDefaultServiceManagerLock.lock();
+    pc = gPermissionController;
+    gDefaultServiceManagerLock.unlock();
+    
+    int64_t startTime = 0;
+
+    while (true) {
+        if (pc != NULL) {
+            bool res = pc->checkPermission(permission, pid, uid);
+            if (res) {
+                if (startTime != 0) {
+                    LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
+                            (int)((uptimeMillis()-startTime)/1000),
+                            String8(permission).string(), uid, pid);
+                }
+                return res;
+            }
+            
+            // Is this a permission failure, or did the controller go away?
+            if (pc->asBinder()->isBinderAlive()) {
+                LOGW("Permission failure: %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+                return false;
+            }
+            
+            // Object is dead!
+            gDefaultServiceManagerLock.lock();
+            if (gPermissionController == pc) {
+                gPermissionController = NULL;
+            }
+            gDefaultServiceManagerLock.unlock();
+        }
+    
+        // Need to retrieve the permission controller.
+        sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
+        if (binder == NULL) {
+            // Wait for the permission controller to come back...
+            if (startTime == 0) {
+                startTime = uptimeMillis();
+                LOGI("Waiting to check permission %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+            }
+            sleep(1);
+        } else {
+            pc = interface_cast<IPermissionController>(binder);
+            // Install the new permission controller, and try again.        
+            gDefaultServiceManagerLock.lock();
+            gPermissionController = pc;
+            gDefaultServiceManagerLock.unlock();
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+
+class BpServiceManager : public BpInterface<IServiceManager>
+{
+public:
+    BpServiceManager(const sp<IBinder>& impl)
+        : BpInterface<IServiceManager>(impl)
+    {
+    }
+        
+    virtual sp<IBinder> getService(const String16& name) const
+    {
+        unsigned n;
+        for (n = 0; n < 5; n++){
+            sp<IBinder> svc = checkService(name);
+            if (svc != NULL) return svc;
+            LOGI("Waiting for sevice %s...\n", String8(name).string());
+            sleep(1);
+        }
+        return NULL;
+    }
+    
+    virtual sp<IBinder> checkService( const String16& name) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
+        return reply.readStrongBinder();
+    }
+
+    virtual status_t addService(const String16& name, const sp<IBinder>& service)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeStrongBinder(service);
+        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
+        return err == NO_ERROR ? reply.readInt32() : err;
+    }
+
+    virtual Vector<String16> listServices()
+    {
+        Vector<String16> res;
+        int n = 0;
+
+        for (;;) {
+            Parcel data, reply;
+            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+            data.writeInt32(n++);
+            status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
+            if (err != NO_ERROR)
+                break;
+            res.add(reply.readString16());
+        }
+        return res;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnServiceManager::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("ServiceManager received: "); data.print();
+    switch(code) {
+        case GET_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case CHECK_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case ADD_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = data.readStrongBinder();
+            status_t err = addService(which, b);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        case LIST_SERVICES_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            Vector<String16> list = listServices();
+            const size_t N = list.size();
+            reply->writeInt32(N);
+            for (size_t i=0; i<N; i++) {
+                reply->writeString16(list[i]);
+            }
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
new file mode 100644
index 0000000..39a0a68
--- /dev/null
+++ b/libs/utils/InetAddress.cpp
@@ -0,0 +1,236 @@
+/*
+ * 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.
+ */
+
+//
+// Internet address class.
+//
+#ifdef HAVE_WINSOCK
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+//# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include <utils/inet_address.h>
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      InetAddress
+ * ===========================================================================
+ */
+
+// lock for the next couple of functions; could tuck into InetAddress
+static Mutex*   gGHBNLock;
+
+/*
+ * Lock/unlock access to the hostent struct returned by gethostbyname().
+ */
+static inline void lock_gethostbyname(void)
+{
+    if (gGHBNLock == NULL)
+        gGHBNLock = new Mutex;
+    gGHBNLock->lock();
+}
+static inline void unlock_gethostbyname(void)
+{
+    assert(gGHBNLock != NULL);
+    gGHBNLock->unlock();
+}
+
+
+/*
+ * Constructor -- just init members.  This is private so that callers
+ * are required to use getByName().
+ */
+InetAddress::InetAddress(void)
+    : mAddress(NULL), mLength(-1), mName(NULL)
+{
+}
+
+/*
+ * Destructor -- free address storage.
+ */
+InetAddress::~InetAddress(void)
+{
+    delete[] (char*) mAddress;
+    delete[] mName;
+}
+
+/*
+ * Copy constructor.
+ */
+InetAddress::InetAddress(const InetAddress& orig)
+{
+    *this = orig;   // use assignment code
+}
+
+/*
+ * Assignment operator.
+ */
+InetAddress& InetAddress::operator=(const InetAddress& addr)
+{
+    // handle self-assignment
+    if (this == &addr)
+        return *this;
+    // copy mLength and mAddress
+    mLength = addr.mLength;
+    if (mLength > 0) {
+        mAddress = new char[mLength];
+        memcpy(mAddress, addr.mAddress, mLength);
+        LOG(LOG_DEBUG, "socket",
+            "HEY: copied %d bytes in assignment operator\n", mLength);
+    } else {
+        mAddress = NULL;
+    }
+    // copy mName
+    mName = new char[strlen(addr.mName)+1];
+    strcpy(mName, addr.mName);
+
+    return *this;
+}
+
+/*
+ * Create a new object from a name or a dotted-number IP notation.
+ *
+ * Returns NULL on failure.
+ */
+InetAddress*
+InetAddress::getByName(const char* host)
+{
+    InetAddress* newAddr = NULL;
+    struct sockaddr_in addr;
+    struct hostent* he;
+    DurationTimer hostTimer, lockTimer;
+
+    // gethostbyname() isn't reentrant, so we need to lock things until
+    // we can copy the data out.
+    lockTimer.start();
+    lock_gethostbyname();
+    hostTimer.start();
+
+    he = gethostbyname(host);
+    if (he == NULL) {
+        LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
+        unlock_gethostbyname();
+        return NULL;
+    }
+
+    memcpy(&addr.sin_addr, he->h_addr, he->h_length);
+    addr.sin_family = he->h_addrtype;
+    addr.sin_port = 0;
+
+    // got it, unlock us
+    hostTimer.stop();
+    he = NULL;
+    unlock_gethostbyname();
+
+    lockTimer.stop();
+    if ((long) lockTimer.durationUsecs() > 100000) {
+        long lockTime = (long) lockTimer.durationUsecs();
+        long hostTime = (long) hostTimer.durationUsecs();
+        LOG(LOG_DEBUG, "socket",
+            "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
+            host, lockTime / 1000000.0, hostTime / 1000000.0,
+            (lockTime - hostTime) / 1000000.0);
+    }
+
+    // Alloc storage and copy it over.
+    newAddr = new InetAddress();
+    if (newAddr == NULL)
+        return NULL;
+
+    newAddr->mLength = sizeof(struct sockaddr_in);
+    newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
+    if (newAddr->mAddress == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    memcpy(newAddr->mAddress, &addr, newAddr->mLength);
+
+    // Keep this for debug messages.
+    newAddr->mName = new char[strlen(host)+1];
+    if (newAddr->mName == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    strcpy(newAddr->mName, host);
+
+    return newAddr;
+}
+
+
+/*
+ * ===========================================================================
+ *      InetSocketAddress
+ * ===========================================================================
+ */
+
+/*
+ * Create an address with the host wildcard (INADDR_ANY).
+ */
+bool InetSocketAddress::create(int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName("0.0.0.0");
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const InetAddress* addr, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = new InetAddress(*addr);  // make a copy
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const char* host, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName(host);
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
new file mode 100644
index 0000000..e64f794
--- /dev/null
+++ b/libs/utils/LogSocket.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+
+#ifndef HAVE_WINSOCK
+#define SOCKETLOG
+#endif
+
+#ifdef SOCKETLOG
+
+#define LOG_TAG "SOCKETLOG"
+
+#include <string.h>
+#include <cutils/log.h>
+#include "utils/LogSocket.h"
+#include "utils/logger.h"
+#include "cutils/hashmap.h"
+
+// defined in //device/data/etc/event-log-tags
+#define SOCKET_CLOSE_LOG 51000
+
+static Hashmap* statsMap = NULL;
+
+#define LOG_LIST_NUMBER 5
+
+typedef struct SocketStats {
+    int fd;
+    unsigned int send;
+    unsigned int recv;
+    unsigned int ip;
+    unsigned short port;
+    short reason;
+}SocketStats;
+
+SocketStats *get_socket_stats(int fd) {
+    if (statsMap == NULL) {
+        statsMap = hashmapCreate(8, &hashmapIntHash, &hashmapIntEquals);
+    }
+
+    SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+    if (s == NULL) {
+        // LOGD("create SocketStats for fd %d", fd);
+        s = (SocketStats*) malloc(sizeof(SocketStats));
+        memset(s, 0, sizeof(SocketStats));
+        s->fd = fd;
+        hashmapPut(statsMap, &s->fd, s);
+    }
+    return s;
+}
+
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {
+    // LOGD("log_socket_connect for fd %d ip %d port%d", fd, ip, port);
+    SocketStats *s = get_socket_stats(fd);
+    s->ip = ip;
+    s->port = port;
+}
+
+void add_send_stats(int fd, int send) {
+    if (send <=0) {
+        LOGE("add_send_stats send %d", send);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->send += send;
+    // LOGD("add_send_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+void add_recv_stats(int fd, int recv) {
+    if (recv <=0) {
+        LOGE("add_recv_stats recv %d", recv);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->recv += recv;
+    // LOGD("add_recv_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+char* put_int(char* buf, int value) {
+    *buf = EVENT_TYPE_INT;
+    buf++;
+    memcpy(buf, &value, sizeof(int));
+    return buf + sizeof(int);
+}
+
+void log_socket_close(int fd, short reason) {
+    if (statsMap) {
+        SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+        if (s != NULL) {
+            if (s->send != 0 || s->recv != 0) {
+                s->reason = reason;
+                // 5 int + list type need 2 bytes
+                char buf[LOG_LIST_NUMBER * 5 + 2];
+                buf[0] = EVENT_TYPE_LIST;
+                buf[1] = LOG_LIST_NUMBER;
+                char* writePos = buf + 2;
+                writePos = put_int(writePos, s->send);
+                writePos = put_int(writePos, s->recv);
+                writePos = put_int(writePos, s->ip);
+                writePos = put_int(writePos, s->port);
+                writePos = put_int(writePos, s->reason);
+                
+                android_bWriteLog(SOCKET_CLOSE_LOG, buf, sizeof(buf));
+                // LOGD("send %d recv %d reason %d", s->send, s->recv, s->reason);
+            }
+            hashmapRemove(statsMap, &s->fd);
+            free(s);
+        }
+    }
+}
+
+#else
+void add_send_stats(int fd, int send) {} 
+void add_recv_stats(int fd, int recv) {}
+void log_socket_close(int fd, short reason) {}
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {}
+#endif
diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/utils/MODULE_LICENSE_APACHE2
diff --git a/libs/utils/MemoryBase.cpp b/libs/utils/MemoryBase.cpp
new file mode 100644
index 0000000..f25e11c
--- /dev/null
+++ b/libs/utils/MemoryBase.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/MemoryBase.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : mSize(size), mOffset(offset), mHeap(heap)
+{
+}
+
+sp<IMemoryHeap> MemoryBase::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return mHeap;
+}
+
+MemoryBase::~MemoryBase()
+{
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp
new file mode 100644
index 0000000..e6d1d18
--- /dev/null
+++ b/libs/utils/MemoryDealer.cpp
@@ -0,0 +1,407 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MemoryDealer"
+
+#include <utils/MemoryDealer.h>
+
+#include <utils/Log.h>
+#include <utils/IPCThreadState.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <utils/MemoryBase.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/file.h>
+
+namespace android {
+
+
+// ----------------------------------------------------------------------------
+
+class SimpleMemory : public MemoryBase {
+public:
+    SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+    virtual ~SimpleMemory();
+};
+
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::Allocation::Allocation(
+        const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
+        const sp<IMemory>& memory)
+    : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory) 
+{
+}
+
+MemoryDealer::Allocation::~Allocation()
+{
+    if (mSize) {
+        /* NOTE: it's VERY important to not free allocations of size 0 because
+         * they're special as they don't have any record in the allocator
+         * and could alias some real allocation (their offset is zero). */
+        mDealer->deallocate(mOffset);
+    }
+}
+
+sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
+    ssize_t* offset, size_t* size) const
+{
+    return mMemory->getMemory(offset, size);
+}
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
+    : mHeap(new SharedHeap(size, flags, name)),
+    mAllocator(new SimpleBestFitAllocator(size))
+{    
+}
+
+MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
+    : mHeap(heap),
+    mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
+{
+}
+
+MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
+        const sp<AllocatorInterface>& allocator)
+    : mHeap(heap), mAllocator(allocator)
+{
+}
+
+MemoryDealer::~MemoryDealer()
+{
+}
+
+sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
+{
+    sp<IMemory> memory;
+    const ssize_t offset = allocator()->allocate(size, flags);
+    if (offset >= 0) {
+        sp<IMemory> new_memory = heap()->mapMemory(offset, size);
+        if (new_memory != 0) {
+            memory = new Allocation(this, offset, size, new_memory);
+        } else {
+            LOGE("couldn't map [%8x, %d]", offset, size);
+            if (size) {
+                /* NOTE: it's VERY important to not free allocations of size 0
+                 * because they're special as they don't have any record in the 
+                 * allocator and could alias some real allocation 
+                 * (their offset is zero). */
+                allocator()->deallocate(offset);
+            }
+        }        
+    }
+    return memory;
+}
+
+void MemoryDealer::deallocate(size_t offset)
+{
+    allocator()->deallocate(offset);
+}
+
+void MemoryDealer::dump(const char* what, uint32_t flags) const
+{
+    allocator()->dump(what, flags);
+}
+
+const sp<HeapInterface>& MemoryDealer::heap() const {
+    return mHeap;
+}
+
+const sp<AllocatorInterface>& MemoryDealer::allocator() const {
+    return mAllocator;
+}
+
+// ----------------------------------------------------------------------------
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+{
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.insertHead(node);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator()
+{
+    while(!mList.isEmpty()) {
+        delete mList.remove(mList.head());
+    }
+}
+
+size_t SimpleBestFitAllocator::size() const
+{
+    return mHeapSize;
+}
+
+size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+{
+    Mutex::Autolock _l(mLock);
+    ssize_t offset = alloc(size, flags);
+    return offset;
+}
+
+status_t SimpleBestFitAllocator::deallocate(size_t offset)
+{
+    Mutex::Autolock _l(mLock);
+    chunk_t const * const freed = dealloc(offset);
+    if (freed) {
+        return NO_ERROR;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
+{
+    if (size == 0) {
+        return 0;
+    }
+    size = (size + kMemoryAlign-1) / kMemoryAlign;
+    chunk_t* free_chunk = 0;
+    chunk_t* cur = mList.head();
+
+    size_t pagesize = getpagesize();
+    while (cur) {
+        int extra = 0;
+        if (flags & PAGE_ALIGNED)
+            extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
+
+        // best fit
+        if (cur->free && (cur->size >= (size+extra))) {
+            if ((!free_chunk) || (cur->size < free_chunk->size)) {
+                free_chunk = cur;
+            }
+            if (cur->size == size) {
+                break;
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (free_chunk) {
+        const size_t free_size = free_chunk->size;
+        free_chunk->free = 0;
+        free_chunk->size = size;
+        if (free_size > size) {
+            int extra = 0;
+            if (flags & PAGE_ALIGNED)
+                extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
+            if (extra) {
+                chunk_t* split = new chunk_t(free_chunk->start, extra);
+                free_chunk->start += extra;
+                mList.insertBefore(free_chunk, split);
+            }
+
+            LOGE_IF((flags&PAGE_ALIGNED) && 
+                    ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+                    "PAGE_ALIGNED requested, but page is not aligned!!!");
+
+            const ssize_t tail_free = free_size - (size+extra);
+            if (tail_free > 0) {
+                chunk_t* split = new chunk_t(
+                        free_chunk->start + free_chunk->size, tail_free);
+                mList.insertAfter(free_chunk, split);
+            }
+        }
+        return (free_chunk->start)*kMemoryAlign;
+    }
+    return NO_MEMORY;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
+{
+    start = start / kMemoryAlign;
+    chunk_t* cur = mList.head();
+    while (cur) {
+        if (cur->start == start) {
+            LOG_FATAL_IF(cur->free,
+                "block at offset 0x%08lX of size 0x%08lX already freed",
+                cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+
+            // merge freed blocks together
+            chunk_t* freed = cur;
+            cur->free = 1;
+            do {
+                chunk_t* const p = cur->prev;
+                chunk_t* const n = cur->next;
+                if (p && (p->free || !cur->size)) {
+                    freed = p;
+                    p->size += cur->size;
+                    mList.remove(cur);
+                    delete cur;
+                }
+                cur = n;
+            } while (cur && cur->free);
+
+            #ifndef NDEBUG
+                if (!freed->free) {
+                    dump_l("dealloc (!freed->free)");
+                }
+            #endif
+            LOG_FATAL_IF(!freed->free,
+                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+            return freed;
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
+
+void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
+{
+    String8 result;
+    dump_l(result, what, flags);
+    LOGD("%s", result.string());
+}
+
+void SimpleBestFitAllocator::dump(String8& result,
+        const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(result, what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(String8& result,
+        const char* what, uint32_t flags) const
+{
+    size_t size = 0;
+    int32_t i = 0;
+    chunk_t const* cur = mList.head();
+    
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "  %s (%p, size=%u)\n",
+            what, this, (unsigned int)mHeapSize);
+    
+    result.append(buffer);
+            
+    while (cur) {
+        const char* errs[] = {"", "| link bogus NP",
+                            "| link bogus PN", "| link bogus NP+PN" };
+        int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
+        int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
+
+        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
+            i, int(cur), int(cur->start*kMemoryAlign),
+            int(cur->size*kMemoryAlign),
+                    int(cur->free) ? "F" : "A",
+                    errs[np|pn]);
+        
+        result.append(buffer);
+
+        if (!cur->free)
+            size += cur->size*kMemoryAlign;
+
+        i++;
+        cur = cur->next;
+    }
+    snprintf(buffer, SIZE, "  size allocated: %u (%u KB)\n", int(size), int(size/1024));
+    result.append(buffer);
+}
+        
+// ----------------------------------------------------------------------------
+
+
+SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
+    : MemoryHeapBase(size, flags, name)
+{
+}
+
+SharedHeap::~SharedHeap()
+{
+}
+
+sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
+{
+    return new SimpleMemory(this, offset, size);
+}
+ 
+
+SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : MemoryBase(heap, offset, size)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+}
+
+SimpleMemory::~SimpleMemory()
+{
+    size_t freedOffset = getOffset();
+    size_t freedSize   = getSize();
+
+    // keep the size to unmap in excess
+    size_t pagesize = getpagesize();
+    size_t start = freedOffset;
+    size_t end = start + freedSize;
+    start &= ~(pagesize-1);
+    end = (end + pagesize-1) & ~(pagesize-1);
+
+    // give back to the kernel the pages we don't need
+    size_t free_start = freedOffset;
+    size_t free_end = free_start + freedSize;
+    if (start < free_start)
+        start = free_start;
+    if (end > free_end)
+        end = free_end;
+    start = (start + pagesize-1) & ~(pagesize-1);
+    end &= ~(pagesize-1);    
+
+    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
+    size_t size = end-start;
+
+#ifndef NDEBUG
+    memset(start_ptr, 0xdf, size);
+#endif
+  
+// MADV_REMOVE is not defined on Dapper based Goobuntu 
+#ifdef MADV_REMOVE 
+    if (size) {
+        int err = madvise(start_ptr, size, MADV_REMOVE);
+        LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+                start_ptr, size, err<0 ? strerror(errno) : "Ok");
+    }
+#endif
+}
+
+}; // namespace android
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/utils/MemoryHeapBase.cpp
new file mode 100644
index 0000000..59963c9
--- /dev/null
+++ b/libs/utils/MemoryHeapBase.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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 "MemoryHeapBase"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/ashmem.h>
+#include <cutils/atomic.h>
+
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapBase::MemoryHeapBase() 
+    : mFD(-1), mSize(0), mBase(MAP_FAILED),
+      mDevice(NULL), mNeedUnmap(false) 
+{
+}
+
+MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
+    LOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
+    if (fd >= 0) {
+        if (mapfd(fd, size) == NO_ERROR) {
+            if (flags & READ_ONLY) {
+                ashmem_set_prot_region(fd, PROT_READ);
+            }
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    int fd = open(device, O_RDWR);
+    LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
+    if (fd >= 0) {
+        const size_t pagesize = getpagesize();
+        size = ((size + pagesize-1) & ~(pagesize-1));
+        if (mapfd(fd, size) == NO_ERROR) {
+            mDevice = device;
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    mapfd(dup(fd), size);
+}
+
+status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
+{
+    if (mFD != -1) {
+        return INVALID_OPERATION;
+    }
+    mFD = fd;
+    mBase = base;
+    mSize = size;
+    mFlags = flags;
+    mDevice = device;
+    return NO_ERROR;
+}
+
+status_t MemoryHeapBase::mapfd(int fd, size_t size)
+{
+    if (size == 0) {
+        // try to figure out the size automatically
+#if HAVE_ANDROID_OS
+        // first try the PMEM ioctl
+        pmem_region reg;
+        int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
+        if (err == 0)
+            size = reg.len;
+#endif
+        if (size == 0) { // try fstat
+            struct stat sb;
+            if (fstat(fd, &sb) == 0)
+                size = sb.st_size;
+        }
+        // if it didn't work, let mmap() fail.
+    }
+
+    void* base = (uint8_t*)mmap(0, size,
+            PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (base == MAP_FAILED) {
+        LOGE("mmap(fd=%d, size=%u) failed (%s)",
+                fd, uint32_t(size), strerror(errno));
+        close(fd);
+        return -errno;
+    }
+    //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
+    mFD = fd;
+    mBase = base;
+    mSize = size;
+    mNeedUnmap = true;
+    return NO_ERROR;
+}
+
+MemoryHeapBase::~MemoryHeapBase()
+{
+    dispose();
+}
+
+void MemoryHeapBase::dispose()
+{
+    int fd = android_atomic_or(-1, &mFD);
+    if (fd >= 0) {
+        if (mNeedUnmap) {
+            //LOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
+            munmap(mBase, mSize);
+        }
+        mBase = 0;
+        mSize = 0;
+        close(fd);
+    }
+}
+
+int MemoryHeapBase::getHeapID() const {
+    return mFD;
+}
+
+void* MemoryHeapBase::getBase() const {
+    return mBase;
+}
+
+size_t MemoryHeapBase::getSize() const {
+    return mSize;
+}
+
+uint32_t MemoryHeapBase::getFlags() const {
+    return mFlags;
+}
+
+const char* MemoryHeapBase::getDevice() const {
+    return mDevice;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp
new file mode 100644
index 0000000..1e5a1cc
--- /dev/null
+++ b/libs/utils/MemoryHeapPmem.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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 "MemoryHeapPmem"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapPmem;
+
+class SubRegionMemory : public BnMemory {
+public:
+    SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
+    virtual ~SubRegionMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+private:
+    friend class MemoryHeapPmem;
+    void revoke();
+    size_t              mSize;
+    ssize_t             mOffset;
+    sp<MemoryHeapPmem>  mClientHeap;
+};
+
+SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
+        ssize_t offset, size_t size)
+    : mSize(size), mOffset(offset), mClientHeap(heap)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(mClientHeap->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+
+#if HAVE_ANDROID_OS
+    if (size > 0) {
+        const size_t pagesize = getpagesize();
+        size = (size + pagesize-1) & ~(pagesize-1);
+        int our_fd = heap->heapID();
+        struct pmem_region sub = { offset, size };
+        int err = ioctl(our_fd, PMEM_MAP, &sub);
+        LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+}
+#endif
+}
+
+sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return mClientHeap;
+}
+
+SubRegionMemory::~SubRegionMemory()
+{
+    revoke();
+}
+
+
+void SubRegionMemory::revoke()
+{
+    // NOTE: revoke() doesn't need to be protected by a lock because it
+    // can only be called from MemoryHeapPmem::revoke(), which means
+    // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
+    // which means MemoryHeapPmem::revoke() wouldn't have been able to 
+    // promote() it.
+    
+#if HAVE_ANDROID_OS
+    if (mClientHeap != NULL) {
+        int our_fd = mClientHeap->heapID();
+        struct pmem_region sub;
+        sub.offset = mOffset;
+        sub.len = mSize;
+        int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+        LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+        mClientHeap.clear();
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+        uint32_t flags)
+    : HeapInterface(), MemoryHeapBase()
+{
+    char const * const device = pmemHeap->getDevice();
+#if HAVE_ANDROID_OS
+    if (device) {
+        int fd = open(device, O_RDWR);
+        LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
+        if (fd >= 0) {
+            int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
+            if (err < 0) {
+                LOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
+                        strerror(errno), fd, pmemHeap->heapID());
+                close(fd);
+            } else {
+                // everything went well...
+                mParentHeap = pmemHeap;
+                MemoryHeapBase::init(fd, 
+                        pmemHeap->getBase(),
+                        pmemHeap->getSize(),
+                        pmemHeap->getFlags() | flags,
+                        device);
+            }
+        }
+    }
+#else
+    mParentHeap = pmemHeap;
+    MemoryHeapBase::init( 
+            dup(pmemHeap->heapID()),
+            pmemHeap->getBase(),
+            pmemHeap->getSize(),
+            pmemHeap->getFlags() | flags,
+            device);
+#endif
+}
+
+MemoryHeapPmem::~MemoryHeapPmem()
+{
+}
+
+sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
+{
+    sp<SubRegionMemory> memory;
+    if (heapID() > 0) 
+        memory = new SubRegionMemory(this, offset, size);
+
+    if (memory != 0) {
+        Mutex::Autolock _l(mLock);
+        mAllocations.add(memory);
+    }
+    return memory;
+}
+
+status_t MemoryHeapPmem::slap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_MAP, &sub);
+    LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+status_t MemoryHeapPmem::unslap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+    LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+void MemoryHeapPmem::revoke()
+{
+    Vector< wp<SubRegionMemory> > allocations;
+
+    { // scope for lock
+        Mutex::Autolock _l(mLock);
+        allocations = mAllocations;
+        mAllocations.clear();
+    }
+    
+    ssize_t count = allocations.size();
+    for (ssize_t i=0 ; i<count ; i++) {
+        sp<SubRegionMemory> memory(allocations[i].promote());
+        if (memory != 0)
+            memory->revoke();
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/utils/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/utils/Parcel.cpp b/libs/utils/Parcel.cpp
new file mode 100644
index 0000000..3eca4b0
--- /dev/null
+++ b/libs/utils/Parcel.cpp
@@ -0,0 +1,1311 @@
+/*
+ * 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 "Parcel"
+//#define LOG_NDEBUG 0
+
+#include <utils/Parcel.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/misc.h>
+
+#include <private/utils/binder_module.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define LOG_REFS(...)
+//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+
+// ---------------------------------------------------------------------------
+
+#define PAD_SIZE(s) (((s)+3)&~3)
+
+// XXX This can be made public if we want to provide
+// support for typed data.
+struct small_flat_data
+{
+    uint32_t type;
+    uint32_t data;
+};
+
+namespace android {
+
+void acquire_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->incStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
+                b->incStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->incWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            // intentionally blank -- nothing to do to acquire this, but we do
+            // recognize it as a legitimate object type.
+            return;
+        }
+    }
+
+    LOGD("Invalid object type 0x%08lx", obj.type);
+}
+
+void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->decStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
+                b->decStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->decWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            if (obj.cookie != (void*)0) close(obj.handle);
+            return;
+        }
+    }
+
+    LOGE("Invalid object type 0x%08lx", obj.type);
+}
+
+inline static status_t finish_flatten_binder(
+    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
+{
+    return out->writeObject(flat, false);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const sp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        IBinder *local = binder->localBinder();
+        if (!local) {
+            BpBinder *proxy = binder->remoteBinder();
+            if (proxy == NULL) {
+                LOGE("null proxy");
+            }
+            const int32_t handle = proxy ? proxy->handle() : 0;
+            obj.type = BINDER_TYPE_HANDLE;
+            obj.handle = handle;
+            obj.cookie = NULL;
+        } else {
+            obj.type = BINDER_TYPE_BINDER;
+            obj.binder = local->getWeakRefs();
+            obj.cookie = local;
+        }
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+    }
+    
+    return finish_flatten_binder(binder, obj, out);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const wp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        sp<IBinder> real = binder.promote();
+        if (real != NULL) {
+            IBinder *local = real->localBinder();
+            if (!local) {
+                BpBinder *proxy = real->remoteBinder();
+                if (proxy == NULL) {
+                    LOGE("null proxy");
+                }
+                const int32_t handle = proxy ? proxy->handle() : 0;
+                obj.type = BINDER_TYPE_WEAK_HANDLE;
+                obj.handle = handle;
+                obj.cookie = NULL;
+            } else {
+                obj.type = BINDER_TYPE_WEAK_BINDER;
+                obj.binder = binder.get_refs();
+                obj.cookie = binder.unsafe_get();
+            }
+            return finish_flatten_binder(real, obj, out);
+        }
+        
+        // XXX How to deal?  In order to flatten the given binder,
+        // we need to probe it for information, which requires a primary
+        // reference...  but we don't have one.
+        //
+        // The OpenBinder implementation uses a dynamic_cast<> here,
+        // but we can't do that with the different reference counting
+        // implementation we are using.
+        LOGE("Unable to unflatten Binder weak reference!");
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    }
+}
+
+inline static status_t finish_unflatten_binder(
+    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
+{
+    return NO_ERROR;
+}
+    
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, sp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+                *out = proc->getStrongProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->get()), *flat, in);
+        }        
+    }
+    return BAD_TYPE;
+}
+
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, wp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_WEAK_BINDER:
+                if (flat->binder != NULL) {
+                    out->set_object_and_refs(
+                        static_cast<IBinder*>(flat->cookie),
+                        static_cast<RefBase::weakref_type*>(flat->binder));
+                } else {
+                    *out = NULL;
+                }
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+            case BINDER_TYPE_WEAK_HANDLE:
+                *out = proc->getWeakProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
+        }
+    }
+    return BAD_TYPE;
+}
+
+// ---------------------------------------------------------------------------
+
+Parcel::Parcel()
+{
+    initState();
+}
+
+Parcel::~Parcel()
+{
+    freeDataNoInit();
+}
+
+const uint8_t* Parcel::data() const
+{
+    return mData;
+}
+
+size_t Parcel::dataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+size_t Parcel::dataAvail() const
+{
+    // TODO: decide what to do about the possibility that this can
+    // report an available-data size that exceeds a Java int's max
+    // positive value, causing havoc.  Fortunately this will only
+    // happen if someone constructs a Parcel containing more than two
+    // gigabytes of data, which on typical phone hardware is simply
+    // not possible.
+    return dataSize() - dataPosition();
+}
+
+size_t Parcel::dataPosition() const
+{
+    return mDataPos;
+}
+
+size_t Parcel::dataCapacity() const
+{
+    return mDataCapacity;
+}
+
+status_t Parcel::setDataSize(size_t size)
+{
+    status_t err;
+    err = continueWrite(size);
+    if (err == NO_ERROR) {
+        mDataSize = size;
+        LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+    }
+    return err;
+}
+
+void Parcel::setDataPosition(size_t pos) const
+{
+    mDataPos = pos;
+    mNextObjectHint = 0;
+}
+
+status_t Parcel::setDataCapacity(size_t size)
+{
+    if (size > mDataSize) return continueWrite(size);
+    return NO_ERROR;
+}
+
+status_t Parcel::setData(const uint8_t* buffer, size_t len)
+{
+    status_t err = restartWrite(len);
+    if (err == NO_ERROR) {
+        memcpy(const_cast<uint8_t*>(data()), buffer, len);
+        mDataSize = len;
+        mFdsKnown = false;
+    }
+    return err;
+}
+
+status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    status_t err;
+    uint8_t *data = parcel->mData;
+    size_t *objects = parcel->mObjects;
+    size_t size = parcel->mObjectsSize;
+    int startPos = mDataPos;
+    int firstIndex = -1, lastIndex = -2;
+
+    if (len == 0) {
+        return NO_ERROR;
+    }
+
+    // range checks against the source parcel size
+    if ((offset > parcel->mDataSize)
+            || (len > parcel->mDataSize)
+            || (offset + len > parcel->mDataSize)) {
+        return BAD_VALUE;
+    }
+
+    // Count objects in range
+    for (int i = 0; i < (int) size; i++) {
+        size_t off = objects[i];
+        if ((off >= offset) && (off < offset + len)) {
+            if (firstIndex == -1) {
+                firstIndex = i;
+            }
+            lastIndex = i;
+        }
+    }
+    int numObjects = lastIndex - firstIndex + 1;
+
+    // grow data
+    err = growData(len);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // append data
+    memcpy(mData + mDataPos, data + offset, len);
+    mDataPos += len;
+    mDataSize += len;
+
+    if (numObjects > 0) {
+        // grow objects
+        if (mObjectsCapacity < mObjectsSize + numObjects) {
+            int newSize = ((mObjectsSize + numObjects)*3)/2;
+            size_t *objects =
+                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+            if (objects == (size_t*)0) {
+                return NO_MEMORY;
+            }
+            mObjects = objects;
+            mObjectsCapacity = newSize;
+        }
+        
+        // append and acquire objects
+        int idx = mObjectsSize;
+        for (int i = firstIndex; i <= lastIndex; i++) {
+            size_t off = objects[i] - offset + startPos;
+            mObjects[idx++] = off;
+            mObjectsSize++;
+
+            const flat_binder_object* flat
+                = reinterpret_cast<flat_binder_object*>(mData + off);
+            acquire_object(proc, *flat, this);
+
+            // take note if the object is a file descriptor
+            if (flat->type == BINDER_TYPE_FD) {
+                mHasFds = mFdsKnown = true;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+bool Parcel::hasFileDescriptors() const
+{
+    if (!mFdsKnown) {
+        scanForFds();
+    }
+    return mHasFds;
+}
+
+status_t Parcel::writeInterfaceToken(const String16& interface)
+{
+    // currently the interface identification token is just its name as a string
+    return writeString16(interface);
+}
+
+bool Parcel::enforceInterface(const String16& interface) const
+{
+    String16 str = readString16();
+    if (str == interface) {
+        return true;
+    } else {
+        LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
+                String8(interface).string(), String8(str).string());
+        return false;
+    }
+} 
+
+const size_t* Parcel::objects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::objectsCount() const
+{
+    return mObjectsSize;
+}
+
+status_t Parcel::errorCheck() const
+{
+    return mError;
+}
+
+void Parcel::setError(status_t err)
+{
+    mError = err;
+}
+
+status_t Parcel::finishWrite(size_t len)
+{
+    //printf("Finish write of %d\n", len);
+    mDataPos += len;
+    LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+    if (mDataPos > mDataSize) {
+        mDataSize = mDataPos;
+        LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+    }
+    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
+    return NO_ERROR;
+}
+
+status_t Parcel::writeUnpadded(const void* data, size_t len)
+{
+    size_t end = mDataPos + len;
+    if (end < mDataPos) {
+        // integer overflow
+        return BAD_VALUE;
+    }
+
+    if (end <= mDataCapacity) {
+restart_write:
+        memcpy(mData+mDataPos, data, len);
+        return finishWrite(len);
+    }
+
+    status_t err = growData(len);
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::write(const void* data, size_t len)
+{
+    void* const d = writeInplace(len);
+    if (d) {
+        memcpy(d, data, len);
+        return NO_ERROR;
+    }
+    return mError;
+}
+
+void* Parcel::writeInplace(size_t len)
+{
+    const size_t padded = PAD_SIZE(len);
+
+    // sanity check for integer overflow
+    if (mDataPos+padded < mDataPos) {
+        return NULL;
+    }
+
+    if ((mDataPos+padded) <= mDataCapacity) {
+restart_write:
+        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
+        uint8_t* const data = mData+mDataPos;
+
+        // Need to pad at end?
+        if (padded != len) {
+#if BYTE_ORDER == BIG_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
+            };
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
+            };
+#endif
+            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
+            //    *reinterpret_cast<void**>(data+padded-4));
+            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
+        }
+
+        finishWrite(padded);
+        return data;
+    }
+
+    status_t err = growData(padded);
+    if (err == NO_ERROR) goto restart_write;
+    return NULL;
+}
+
+status_t Parcel::writeInt32(int32_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeInt64(int64_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeFloat(float val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<float*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeDouble(double val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<double*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeCString(const char* str)
+{
+    return write(str, strlen(str)+1);
+}
+
+status_t Parcel::writeString8(const String8& str)
+{
+    status_t err = writeInt32(str.bytes());
+    if (err == NO_ERROR) {
+        err = write(str.string(), str.bytes()+1);
+    }
+    return err;
+}
+
+status_t Parcel::writeString16(const String16& str)
+{
+    return writeString16(str.string(), str.size());
+}
+
+status_t Parcel::writeString16(const char16_t* str, size_t len)
+{
+    if (str == NULL) return writeInt32(-1);
+    
+    status_t err = writeInt32(len);
+    if (err == NO_ERROR) {
+        len *= sizeof(char16_t);
+        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
+        if (data) {
+            memcpy(data, str, len);
+            *reinterpret_cast<char16_t*>(data+len) = 0;
+            return NO_ERROR;
+        }
+        err = mError;
+    }
+    return err;
+}
+
+status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = fd;
+    obj.cookie = (void*)0;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeDupFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = dup(fd);
+    obj.cookie = (void*)1;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
+{
+    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
+    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
+    if (enoughData && enoughObjects) {
+restart_write:
+        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
+        
+        // Need to write meta-data?
+        if (nullMetaData || val.binder != NULL) {
+            mObjects[mObjectsSize] = mDataPos;
+            acquire_object(ProcessState::self(), val, this);
+            mObjectsSize++;
+        }
+        
+        // remember if it's a file descriptor
+        if (val.type == BINDER_TYPE_FD) {
+            mHasFds = mFdsKnown = true;
+        }
+
+        return finishWrite(sizeof(flat_binder_object));
+    }
+
+    if (!enoughData) {
+        const status_t err = growData(sizeof(val));
+        if (err != NO_ERROR) return err;
+    }
+    if (!enoughObjects) {
+        size_t newSize = ((mObjectsSize+2)*3)/2;
+        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+        if (objects == NULL) return NO_MEMORY;
+        mObjects = objects;
+        mObjectsCapacity = newSize;
+    }
+    
+    goto restart_write;
+}
+
+
+void Parcel::remove(size_t start, size_t amt)
+{
+    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
+}
+
+status_t Parcel::read(void* outData, size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        memcpy(outData, mData+mDataPos, len);
+        mDataPos += PAD_SIZE(len);
+        LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    }
+    return NOT_ENOUGH_DATA;
+}
+
+const void* Parcel::readInplace(size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += PAD_SIZE(len);
+        LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+        return data;
+    }
+    return NULL;
+}
+
+status_t Parcel::readInt32(int32_t *pArg) const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+int32_t Parcel::readInt32() const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int32_t*>(data);
+    }
+    return 0;
+}
+
+
+status_t Parcel::readInt64(int64_t *pArg) const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        *pArg = *reinterpret_cast<const int64_t*>(data);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+int64_t Parcel::readInt64() const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int64_t*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readFloat(float *pArg) const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const float*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+float Parcel::readFloat() const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const float*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readDouble(double *pArg) const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const double*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+double Parcel::readDouble() const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const double*>(data);
+    }
+    return 0;
+}
+
+
+const char* Parcel::readCString() const
+{
+    const size_t avail = mDataSize-mDataPos;
+    if (avail > 0) {
+        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
+        // is the string's trailing NUL within the parcel's valid bounds?
+        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
+        if (eos) {
+            const size_t len = eos - str;
+            mDataPos += PAD_SIZE(len+1);
+            LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+            return str;
+        }
+    }
+    return NULL;
+}
+
+String8 Parcel::readString8() const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow adding 1 for trailing NUL
+    if (size > 0 && size < INT32_MAX) {
+        const char* str = (const char*)readInplace(size+1);
+        if (str) return String8(str, size);
+    }
+    return String8();
+}
+
+String16 Parcel::readString16() const
+{
+    size_t len;
+    const char16_t* str = readString16Inplace(&len);
+    if (str) return String16(str, len);
+    LOGE("Reading a NULL string not supported here.");
+    return String16();
+}
+
+const char16_t* Parcel::readString16Inplace(size_t* outLen) const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow from size+1
+    if (size >= 0 && size < INT32_MAX) {
+        *outLen = size;
+        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
+        if (str != NULL) {
+            return str;
+        }
+    }
+    *outLen = 0;
+    return NULL;
+}
+
+sp<IBinder> Parcel::readStrongBinder() const
+{
+    sp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+wp<IBinder> Parcel::readWeakBinder() const
+{
+    wp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+int Parcel::readFileDescriptor() const
+{
+    const flat_binder_object* flat = readObject(true);
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_FD:
+                //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
+                return flat->handle;
+        }        
+    }
+    return BAD_TYPE;
+}
+
+const flat_binder_object* Parcel::readObject(bool nullMetaData) const
+{
+    const size_t DPOS = mDataPos;
+    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
+        const flat_binder_object* obj
+                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
+        mDataPos = DPOS + sizeof(flat_binder_object);
+        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
+            // When transfering a NULL object, we don't write it into
+            // the object list, so we don't want to check for it when
+            // reading.
+            LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+            return obj;
+        }
+        
+        // Ensure that this object is valid...
+        size_t* const OBJS = mObjects;
+        const size_t N = mObjectsSize;
+        size_t opos = mNextObjectHint;
+        
+        if (N > 0) {
+            LOGV("Parcel %p looking for obj at %d, hint=%d\n",
+                 this, DPOS, opos);
+            
+            // Start at the current hint position, looking for an object at
+            // the current data position.
+            if (opos < N) {
+                while (opos < (N-1) && OBJS[opos] < DPOS) {
+                    opos++;
+                }
+            } else {
+                opos = N-1;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with forward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        
+            // Look backwards for it...
+            while (opos > 0 && OBJS[opos] > DPOS) {
+                opos--;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with backward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        }
+        LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
+             this, DPOS);
+    }
+    return NULL;
+}
+
+void Parcel::closeFileDescriptors()
+{
+    size_t i = mObjectsSize;
+    if (i > 0) {
+        //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
+    }
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            //LOGI("Closing fd: %ld\n", flat->handle);
+            close(flat->handle);
+        }
+    }
+}
+
+const uint8_t* Parcel::ipcData() const
+{
+    return mData;
+}
+
+size_t Parcel::ipcDataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+const size_t* Parcel::ipcObjects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::ipcObjectsCount() const
+{
+    return mObjectsSize;
+}
+
+void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
+    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+{
+    freeDataNoInit();
+    mError = NO_ERROR;
+    mData = const_cast<uint8_t*>(data);
+    mDataSize = mDataCapacity = dataSize;
+    //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
+    mDataPos = 0;
+    LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = const_cast<size_t*>(objects);
+    mObjectsSize = mObjectsCapacity = objectsCount;
+    mNextObjectHint = 0;
+    mOwner = relFunc;
+    mOwnerCookie = relCookie;
+    scanForFds();
+}
+
+void Parcel::print(TextOutput& to, uint32_t flags) const
+{
+    to << "Parcel(";
+    
+    if (errorCheck() != NO_ERROR) {
+        const status_t err = errorCheck();
+        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
+    } else if (dataSize() > 0) {
+        const uint8_t* DATA = data();
+        to << indent << HexDump(DATA, dataSize()) << dedent;
+        const size_t* OBJS = objects();
+        const size_t N = objectsCount();
+        for (size_t i=0; i<N; i++) {
+            const flat_binder_object* flat
+                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
+            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
+                << TypeCode(flat->type & 0x7f7f7f00)
+                << " = " << flat->binder;
+        }
+    } else {
+        to << "NULL";
+    }
+    
+    to << ")";
+}
+
+void Parcel::releaseObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        release_object(proc, *flat, this);
+    }
+}
+
+void Parcel::acquireObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        acquire_object(proc, *flat, this);
+    }
+}
+
+void Parcel::freeData()
+{
+    freeDataNoInit();
+    initState();
+}
+
+void Parcel::freeDataNoInit()
+{
+    if (mOwner) {
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+    } else {
+        releaseObjects();
+        if (mData) free(mData);
+        if (mObjects) free(mObjects);
+    }
+}
+
+status_t Parcel::growData(size_t len)
+{
+    size_t newSize = ((mDataSize+len)*3)/2;
+    return (newSize <= mDataSize)
+            ? (status_t) NO_MEMORY
+            : continueWrite(newSize);
+}
+
+status_t Parcel::restartWrite(size_t desired)
+{
+    if (mOwner) {
+        freeData();
+        return continueWrite(desired);
+    }
+    
+    uint8_t* data = (uint8_t*)realloc(mData, desired);
+    if (!data && desired > mDataCapacity) {
+        mError = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    
+    releaseObjects();
+    
+    if (data) {
+        mData = data;
+        mDataCapacity = desired;
+    }
+    
+    mDataSize = mDataPos = 0;
+    LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
+        
+    free(mObjects);
+    mObjects = NULL;
+    mObjectsSize = mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    
+    return NO_ERROR;
+}
+
+status_t Parcel::continueWrite(size_t desired)
+{
+    // If shrinking, first adjust for any objects that appear
+    // after the new data size.
+    size_t objectsSize = mObjectsSize;
+    if (desired < mDataSize) {
+        if (desired == 0) {
+            objectsSize = 0;
+        } else {
+            while (objectsSize > 0) {
+                if (mObjects[objectsSize-1] < desired)
+                    break;
+                objectsSize--;
+            }
+        }
+    }
+    
+    if (mOwner) {
+        // If the size is going to zero, just release the owner's data.
+        if (desired == 0) {
+            freeData();
+            return NO_ERROR;
+        }
+
+        // If there is a different owner, we need to take
+        // posession.
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        size_t* objects = NULL;
+        
+        if (objectsSize) {
+            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
+            if (!objects) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+
+            // Little hack to only acquire references on objects
+            // we will be keeping.
+            size_t oldObjectsSize = mObjectsSize;
+            mObjectsSize = objectsSize;
+            acquireObjects();
+            mObjectsSize = oldObjectsSize;
+        }
+        
+        if (mData) {
+            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
+        }
+        if (objects && mObjects) {
+            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
+        }
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner = NULL;
+
+        mData = data;
+        mObjects = objects;
+        mDataSize = (mDataSize < desired) ? mDataSize : desired;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        mDataCapacity = desired;
+        mObjectsSize = mObjectsCapacity = objectsSize;
+        mNextObjectHint = 0;
+
+    } else if (mData) {
+        if (objectsSize < mObjectsSize) {
+            // Need to release refs on any objects we are dropping.
+            const sp<ProcessState> proc(ProcessState::self());
+            for (size_t i=objectsSize; i<mObjectsSize; i++) {
+                const flat_binder_object* flat
+                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+                if (flat->type == BINDER_TYPE_FD) {
+                    // will need to rescan because we may have lopped off the only FDs
+                    mFdsKnown = false;
+                }
+                release_object(proc, *flat, this);
+            }
+            size_t* objects =
+                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
+            if (objects) {
+                mObjects = objects;
+            }
+            mObjectsSize = objectsSize;
+            mNextObjectHint = 0;
+        }
+
+        // We own the data, so we can just do a realloc().
+        if (desired > mDataCapacity) {
+            uint8_t* data = (uint8_t*)realloc(mData, desired);
+            if (data) {
+                mData = data;
+                mDataCapacity = desired;
+            } else if (desired > mDataCapacity) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+        } else {
+            mDataSize = desired;
+            LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+            if (mDataPos > desired) {
+                mDataPos = desired;
+                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+            }
+        }
+        
+    } else {
+        // This is the first data.  Easy!
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        
+        if(!(mDataCapacity == 0 && mObjects == NULL
+             && mObjectsCapacity == 0)) {
+            LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
+        }
+        
+        mData = data;
+        mDataSize = mDataPos = 0;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+        mDataCapacity = desired;
+    }
+
+    return NO_ERROR;
+}
+
+void Parcel::initState()
+{
+    mError = NO_ERROR;
+    mData = 0;
+    mDataSize = 0;
+    mDataCapacity = 0;
+    mDataPos = 0;
+    LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = NULL;
+    mObjectsSize = 0;
+    mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    mOwner = NULL;
+}
+
+void Parcel::scanForFds() const
+{
+    bool hasFds = false;
+    for (size_t i=0; i<mObjectsSize; i++) {
+        const flat_binder_object* flat
+            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            hasFds = true;
+            break;
+        }
+    }
+    mHasFds = hasFds;
+    mFdsKnown = true;
+}
+
+}; // namespace android
diff --git a/libs/utils/Pipe.cpp b/libs/utils/Pipe.cpp
new file mode 100644
index 0000000..613906b
--- /dev/null
+++ b/libs/utils/Pipe.cpp
@@ -0,0 +1,465 @@
+/*
+ * 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.
+ */
+
+//
+// Unidirectional pipe.
+//
+
+#include <utils/Pipe.h>
+#include <utils/Log.h>
+
+#if defined(HAVE_WIN32_IPC)
+# include <windows.h>
+#else
+# include <fcntl.h>
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+using namespace android;
+
+const unsigned long kInvalidHandle = (unsigned long) -1;
+
+
+/*
+ * Constructor.  Do little.
+ */
+Pipe::Pipe(void)
+    : mReadNonBlocking(false), mReadHandle(kInvalidHandle),
+      mWriteHandle(kInvalidHandle)
+{
+}
+
+/*
+ * Destructor.  Use the system-appropriate close call.
+ */
+Pipe::~Pipe(void)
+{
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle))
+            LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
+                mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        FlushFileBuffers((HANDLE)mWriteHandle);
+        if (!CloseHandle((HANDLE)mWriteHandle))
+            LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
+                mWriteHandle);
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
+                (int) mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
+                (int) mWriteHandle);
+    }
+#endif
+}
+
+/*
+ * Create the pipe.
+ *
+ * Use the POSIX stuff for everything but Windows.
+ */
+bool Pipe::create(void)
+{
+    assert(mReadHandle == kInvalidHandle);
+    assert(mWriteHandle == kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    /* we use this across processes, so they need to be inheritable */
+    HANDLE handles[2];
+    SECURITY_ATTRIBUTES saAttr;
+
+    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    saAttr.bInheritHandle = TRUE;
+    saAttr.lpSecurityDescriptor = NULL;
+
+    if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = (unsigned long) handles[0];
+    mWriteHandle = (unsigned long) handles[1];
+    return true;
+#else
+    int fds[2];
+
+    if (pipe(fds) != 0) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = fds[0];
+    mWriteHandle = fds[1];
+    return true;
+#endif
+}
+
+/*
+ * Create a "half pipe".  Please, no Segway riding.
+ */
+bool Pipe::createReader(unsigned long handle)
+{
+    mReadHandle = handle;
+    assert(mWriteHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Create a "half pipe" for writing.
+ */
+bool Pipe::createWriter(unsigned long handle)
+{
+    mWriteHandle = handle;
+    assert(mReadHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Return "true" if create() has been called successfully.
+ */
+bool Pipe::isCreated(void)
+{
+    // one or the other should be open
+    return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
+}
+
+
+/*
+ * Read data from the pipe.
+ *
+ * For Linux and Darwin, just call read().  For Windows, implement
+ * non-blocking reads by calling PeekNamedPipe first.
+ */
+int Pipe::read(void* buf, int count)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail = count;
+    DWORD bytesRead;
+
+    if (mReadNonBlocking) {
+        // use PeekNamedPipe to adjust read count expectations
+        if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+                &totalBytesAvail, NULL))
+        {
+            LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+            return -1;
+        }
+
+        if (totalBytesAvail == 0)
+            return 0;
+    }
+
+    if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
+            NULL))
+    {
+        DWORD err = GetLastError();
+        if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
+            return 0;
+        LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
+        return -1;
+    }
+
+    return (int) bytesRead;
+#else
+    int cc;
+    cc = ::read(mReadHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Write data to the pipe.
+ *
+ * POSIX systems are trivial, Windows uses a different call and doesn't
+ * handle non-blocking writes.
+ *
+ * If we add non-blocking support here, we probably want to make it an
+ * all-or-nothing write.
+ *
+ * DO NOT use LOG() here, we could be writing a log message.
+ */
+int Pipe::write(const void* buf, int count)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD bytesWritten;
+
+    if (mWriteNonBlocking) {
+        // BUG: can't use PeekNamedPipe() to get the amount of space
+        // left.  Looks like we need to use "overlapped I/O" functions.
+        // I just don't care that much.
+    }
+
+    if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
+        // can't LOG, use stderr
+        fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
+        return -1;
+    }
+
+    return (int) bytesWritten;
+#else
+    int cc;
+    cc = ::write(mWriteHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Figure out if there is data available on the read fd.
+ *
+ * We return "true" on error because we want the caller to try to read
+ * from the pipe.  They'll notice the read failure and do something
+ * appropriate.
+ */
+bool Pipe::readReady(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail;
+
+    if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+            &totalBytesAvail, NULL))
+    {
+        LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+        return true;
+    }
+
+    return (totalBytesAvail != 0);
+#else
+    errno = 0;
+    fd_set readfds;
+    struct timeval tv = { 0, 0 };
+    int cc;
+
+    FD_ZERO(&readfds);
+    FD_SET(mReadHandle, &readfds);
+
+    cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
+    if (cc < 0) {
+        LOG(LOG_ERROR, "pipe", "select() failed\n");
+        return true;
+    } else if (cc == 0) {
+        /* timed out, nothing available */
+        return false;
+    } else if (cc == 1) {
+        /* our fd is ready */
+        return true;
+    } else {
+        LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
+        return true;
+    }
+#endif
+}
+
+/*
+ * Enable or disable non-blocking mode for the read descriptor.
+ *
+ * NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
+ * actually be in non-blocking mode.  If this matters -- i.e. you're not
+ * using a select() call -- put a call to readReady() in front of the
+ * ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
+ * Darwin.
+ */
+bool Pipe::setReadNonBlocking(bool val)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
+        return false;
+    }
+#endif
+
+    mReadNonBlocking = val;
+    return true;
+}
+
+/*
+ * Enable or disable non-blocking mode for the write descriptor.
+ *
+ * As with setReadNonBlocking(), this does not work on the Mac.
+ */
+bool Pipe::setWriteNonBlocking(bool val)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't get flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't set flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+#endif
+
+    mWriteNonBlocking = val;
+    return true;
+}
+
+/*
+ * Specify whether a file descriptor can be inherited by a child process.
+ * Under Linux this means setting the close-on-exec flag, under Windows
+ * this is SetHandleInformation(HANDLE_FLAG_INHERIT).
+ */
+bool Pipe::disallowReadInherit(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+bool Pipe::disallowWriteInherit(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+
+/*
+ * Close read descriptor.
+ */
+bool Pipe::closeRead(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing read handle\n");
+            return false;
+        }
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing read fd\n");
+            return false;
+        }
+    }
+#endif
+    mReadHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Close write descriptor.
+ */
+bool Pipe::closeWrite(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mWriteHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mWriteHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing write handle\n");
+            return false;
+        }
+    }
+#else
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing write fd\n");
+            return false;
+        }
+    }
+#endif
+    mWriteHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Get the read handle.
+ */
+unsigned long Pipe::getReadHandle(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+    return mReadHandle;
+}
+
+/*
+ * Get the write handle.
+ */
+unsigned long Pipe::getWriteHandle(void)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+    return mWriteHandle;
+}
+
diff --git a/libs/utils/ProcessState.cpp b/libs/utils/ProcessState.cpp
new file mode 100644
index 0000000..4567df6
--- /dev/null
+++ b/libs/utils/ProcessState.cpp
@@ -0,0 +1,398 @@
+/*
+ * 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 "ProcessState"
+
+#include <cutils/process_name.h>
+
+#include <utils/ProcessState.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/IServiceManager.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#define BINDER_VM_SIZE (1*1024*1024)
+
+static bool gSingleProcess = false;
+
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+ 
+// Global variables
+int                 mArgC;
+const char* const*  mArgV;
+int                 mArgLen;
+
+class PoolThread : public Thread
+{
+public:
+    PoolThread(bool isMain)
+        : mIsMain(isMain)
+    {
+    }
+    
+protected:
+    virtual bool threadLoop()
+    {
+        IPCThreadState::self()->joinThreadPool(mIsMain);
+        return false;
+    }
+    
+    const bool mIsMain;
+};
+
+sp<ProcessState> ProcessState::self()
+{
+    if (gProcess != NULL) return gProcess;
+    
+    AutoMutex _l(gProcessMutex);
+    if (gProcess == NULL) gProcess = new ProcessState;
+    return gProcess;
+}
+
+void ProcessState::setSingleProcess(bool singleProcess)
+{
+    gSingleProcess = singleProcess;
+}
+
+
+void ProcessState::setContextObject(const sp<IBinder>& object)
+{
+    setContextObject(object, String16("default"));
+}
+
+sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
+{
+    if (supportsProcesses()) {
+        return getStrongProxyForHandle(0);
+    } else {
+        return getContextObject(String16("default"), caller);
+    }
+}
+
+void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
+{
+    AutoMutex _l(mLock);
+    mContexts.add(name, object);
+}
+
+sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
+{
+    mLock.lock();
+    sp<IBinder> object(
+        mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
+    mLock.unlock();
+    
+    //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
+    
+    if (object != NULL) return object;
+
+    // Don't attempt to retrieve contexts if we manage them
+    if (mManagesContexts) {
+        LOGE("getContextObject(%s) failed, but we manage the contexts!\n",
+            String8(name).string());
+        return NULL;
+    }
+    
+    IPCThreadState* ipc = IPCThreadState::self();
+    {
+        Parcel data, reply;
+        // no interface token on this magic transaction
+        data.writeString16(name);
+        data.writeStrongBinder(caller);
+        status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
+        if (result == NO_ERROR) {
+            object = reply.readStrongBinder();
+        }
+    }
+    
+    ipc->flushCommands();
+    
+    if (object != NULL) setContextObject(object, name);
+    return object;
+}
+
+bool ProcessState::supportsProcesses() const
+{
+    return mDriverFD >= 0;
+}
+
+void ProcessState::startThreadPool()
+{
+    AutoMutex _l(mLock);
+    if (!mThreadPoolStarted) {
+        mThreadPoolStarted = true;
+        spawnPooledThread(true);
+    }
+}
+
+bool ProcessState::isContextManager(void) const
+{
+    return mManagesContexts;
+}
+
+bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
+{
+    if (!mManagesContexts) {
+        AutoMutex _l(mLock);
+        mBinderContextCheckFunc = checkFunc;
+        mBinderContextUserData = userData;
+        if (mDriverFD >= 0) {
+            int dummy = 0;
+#if defined(HAVE_ANDROID_OS)
+            status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+#else
+            status_t result = INVALID_OPERATION;
+#endif
+            if (result == 0) {
+                mManagesContexts = true;
+            } else if (result == -1) {
+                mBinderContextCheckFunc = NULL;
+                mBinderContextUserData = NULL;
+                LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
+            }
+        } else {
+            // If there is no driver, our only world is the local
+            // process so we can always become the context manager there.
+            mManagesContexts = true;
+        }
+    }
+    return mManagesContexts;
+}
+
+ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
+{
+    const size_t N=mHandleToObject.size();
+    if (N <= (size_t)handle) {
+        handle_entry e;
+        e.binder = NULL;
+        e.refs = NULL;
+        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
+        if (err < NO_ERROR) return NULL;
+    }
+    return &mHandleToObject.editItemAt(handle);
+}
+
+sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
+{
+    sp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  See comment
+        // in getWeakProxyForHandle() for more info about this.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle); 
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+            result = b;
+        } else {
+            // This little bit of nastyness is to allow us to add a primary
+            // reference to the remote proxy when this team doesn't have one
+            // but another team is sending the handle to us.
+            result.force_set(b);
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
+{
+    wp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {        
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  The
+        // attemptIncWeak() is safe because we know the BpBinder destructor will always
+        // call expungeHandle(), which acquires the same lock we are holding now.
+        // We need to do this because there is a race condition between someone
+        // releasing a reference on this BpBinder, and a new reference on its handle
+        // arriving from the driver.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle);
+            result = b;
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+        } else {
+            result = b;
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
+{
+    AutoMutex _l(mLock);
+    
+    handle_entry* e = lookupHandleLocked(handle);
+
+    // This handle may have already been replaced with a new BpBinder
+    // (if someone failed the AttemptIncWeak() above); we don't want
+    // to overwrite it.
+    if (e && e->binder == binder) e->binder = NULL;
+}
+
+void ProcessState::setArgs(int argc, const char* const argv[])
+{
+    mArgC = argc;
+    mArgV = (const char **)argv;
+
+    mArgLen = 0;
+    for (int i=0; i<argc; i++) {
+        mArgLen += strlen(argv[i]) + 1;
+    }
+    mArgLen--;
+}
+
+int ProcessState::getArgC() const
+{
+    return mArgC;
+}
+
+const char* const* ProcessState::getArgV() const
+{
+    return mArgV;
+}
+
+void ProcessState::setArgV0(const char* txt)
+{
+    if (mArgV != NULL) {
+        strncpy((char*)mArgV[0], txt, mArgLen);
+        set_process_name(txt);
+    }
+}
+
+void ProcessState::spawnPooledThread(bool isMain)
+{
+    if (mThreadPoolStarted) {
+        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
+        char buf[32];
+        sprintf(buf, "Binder Thread #%d", s);
+        LOGV("Spawning new pooled thread, name=%s\n", buf);
+        sp<Thread> t = new PoolThread(isMain);
+        t->run(buf);
+    }
+}
+
+static int open_driver()
+{
+    if (gSingleProcess) {
+        return -1;
+    }
+
+    int fd = open("/dev/binder", O_RDWR);
+    if (fd >= 0) {
+        fcntl(fd, F_SETFD, FD_CLOEXEC);
+        int vers;
+#if defined(HAVE_ANDROID_OS)
+        status_t result = ioctl(fd, BINDER_VERSION, &vers);
+#else
+        status_t result = -1;
+        errno = EPERM;
+#endif
+        if (result == -1) {
+            LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
+            close(fd);
+            fd = -1;
+        }
+        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
+            LOGE("Binder driver protocol does not match user space protocol!");
+            close(fd);
+            fd = -1;
+        }
+#if defined(HAVE_ANDROID_OS)
+        size_t maxThreads = 15;
+        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
+        if (result == -1) {
+            LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
+        }
+#endif
+        
+    } else {
+        LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
+    }
+    return fd;
+}
+
+ProcessState::ProcessState()
+    : mDriverFD(open_driver())
+    , mVMStart(MAP_FAILED)
+    , mManagesContexts(false)
+    , mBinderContextCheckFunc(NULL)
+    , mBinderContextUserData(NULL)
+    , mThreadPoolStarted(false)
+    , mThreadPoolSeq(1)
+{
+    if (mDriverFD >= 0) {
+        // XXX Ideally, there should be a specific define for whether we
+        // have mmap (or whether we could possibly have the kernel module
+        // availabla).
+#if !defined(HAVE_WIN32_IPC)
+        // mmap the binder, providing a chunk of virtual address space to receive transactions.
+        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        if (mVMStart == MAP_FAILED) {
+            // *sigh*
+            LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
+            close(mDriverFD);
+            mDriverFD = -1;
+        }
+#else
+        mDriverFD = -1;
+#endif
+    }
+    if (mDriverFD < 0) {
+        // Need to run without the driver, starting our own thread pool.
+    }
+}
+
+ProcessState::~ProcessState()
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/README b/libs/utils/README
new file mode 100644
index 0000000..36a706d
--- /dev/null
+++ b/libs/utils/README
@@ -0,0 +1,14 @@
+Android Utility Function Library
+
+If you need a feature that is native to Linux but not present on other
+platforms, construct a platform-dependent implementation that shares
+the Linux interface.  That way the actual device runs as "light" as
+possible.
+
+If that isn't feasible, create a system-independent interface and hide
+the details.
+
+The ultimate goal is *not* to create a super-duper platform abstraction
+layer.  The goal is to provide an optimized solution for Linux with
+reasonable implementations for other platforms.
+
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
new file mode 100644
index 0000000..0bd1af4
--- /dev/null
+++ b/libs/utils/RefBase.cpp
@@ -0,0 +1,534 @@
+/*
+ * 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 "RefBase"
+
+#include <utils/RefBase.h>
+
+#include <utils/Atomic.h>
+#include <utils/CallStack.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <typeinfo>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+// compile with refcounting debugging enabled
+#define DEBUG_REFS                      0
+#define DEBUG_REFS_ENABLED_BY_DEFAULT   1
+#define DEBUG_REFS_CALLSTACK_ENABLED    1
+
+// log all reference counting operations
+#define PRINT_REFS                      0
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+#define INITIAL_STRONG_VALUE (1<<28)
+
+// ---------------------------------------------------------------------------
+
+class RefBase::weakref_impl : public RefBase::weakref_type
+{
+public:
+    volatile int32_t    mStrong;
+    volatile int32_t    mWeak;
+    RefBase* const      mBase;
+    volatile int32_t    mFlags;
+
+
+#if !DEBUG_REFS
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+    {
+    }
+
+    void addStrongRef(const void* /*id*/) { }
+    void removeStrongRef(const void* /*id*/) { }
+    void addWeakRef(const void* /*id*/) { }
+    void removeWeakRef(const void* /*id*/) { }
+    void printRefs() const { }
+    void trackMe(bool, bool) { }
+
+#else
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+        , mStrongRefs(NULL)
+        , mWeakRefs(NULL)
+        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
+        , mRetain(false)
+    {
+        //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
+    }
+    
+    ~weakref_impl()
+    {
+        LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
+        LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
+    }
+
+    void addStrongRef(const void* id)
+    {
+        addRef(&mStrongRefs, id, mStrong);
+    }
+
+    void removeStrongRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mStrongRefs, id);
+        else
+            addRef(&mStrongRefs, id, -mStrong);
+    }
+
+    void addWeakRef(const void* id)
+    {
+        addRef(&mWeakRefs, id, mWeak);
+    }
+
+    void removeWeakRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mWeakRefs, id);
+        else
+            addRef(&mWeakRefs, id, -mWeak);
+    }
+
+    void trackMe(bool track, bool retain)
+    { 
+        mTrackEnabled = track;
+        mRetain = retain;
+    }
+
+    void printRefs() const
+    {
+        String8 text;
+
+        {
+            AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
+    
+            char buf[128];
+            sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mStrongRefs);
+            sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mWeakRefs);
+        }
+
+        {
+            char name[100];
+            snprintf(name, 100, "/data/%p.stack", this);
+            int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
+            if (rc >= 0) {
+                write(rc, text.string(), text.length());
+                close(rc);
+                LOGD("STACK TRACE for %p saved in %s", this, name);
+            }
+            else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
+                      name, strerror(errno));
+        }
+    }
+
+private:
+    struct ref_entry
+    {
+        ref_entry* next;
+        const void* id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+        CallStack stack;
+#endif
+        int32_t ref;
+    };
+
+    void addRef(ref_entry** refs, const void* id, int32_t mRef)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            ref_entry* ref = new ref_entry;
+            // Reference count at the time of the snapshot, but before the
+            // update.  Positive value means we increment, negative--we
+            // decrement the reference count.
+            ref->ref = mRef;
+            ref->id = id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            ref->stack.update(2);
+#endif
+            
+            ref->next = *refs;
+            *refs = ref;
+        }
+    }
+
+    void removeRef(ref_entry** refs, const void* id)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            
+            ref_entry* ref = *refs;
+            while (ref != NULL) {
+                if (ref->id == id) {
+                    *refs = ref->next;
+                    delete ref;
+                    return;
+                }
+                
+                refs = &ref->next;
+                ref = *refs;
+            }
+            
+            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
+                             id, mBase, this);
+        }
+    }
+
+    void printRefsLocked(String8* out, const ref_entry* refs) const
+    {
+        char buf[128];
+        while (refs) {
+            char inc = refs->ref >= 0 ? '+' : '-';
+            sprintf(buf, "\t%c ID %p (ref %d):\n", 
+                    inc, refs->id, refs->ref);
+            out->append(buf);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            out->append(refs->stack.toString("\t\t"));
+#else
+            out->append("\t\t(call stacks disabled)");
+#endif
+            refs = refs->next;
+        }
+    }
+
+    Mutex mMutex;
+    ref_entry* mStrongRefs;
+    ref_entry* mWeakRefs;
+
+    bool mTrackEnabled;
+    // Collect stack traces on addref and removeref, instead of deleting the stack references
+    // on removeref that match the address ones.
+    bool mRetain;
+
+#if 0
+    void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        if (i >= 0) {
+            ++(refs->editValueAt(i));
+        } else {
+            i = refs->add(id, 1);
+        }
+    }
+
+    void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
+        if (i >= 0) {
+            int32_t val = --(refs->editValueAt(i));
+            if (val == 0) {
+                refs->removeItemsAt(i);
+            }
+        }
+    }
+
+    void printRefs(const KeyedVector<const void*, int32_t>& refs)
+    {
+        const size_t N=refs.size();
+        for (size_t i=0; i<N; i++) {
+            printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
+        }
+    }
+
+    mutable Mutex mMutex;
+    KeyedVector<const void*, int32_t> mStrongRefs;
+    KeyedVector<const void*, int32_t> mWeakRefs;
+#endif
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+void RefBase::incStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
+#if PRINT_REFS
+    LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    if (c != INITIAL_STRONG_VALUE)  {
+        return;
+    }
+
+    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+    const_cast<RefBase*>(this)->onFirstRef();
+}
+
+void RefBase::decStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->removeStrongRef(id);
+    const int32_t c = android_atomic_dec(&refs->mStrong);
+#if PRINT_REFS
+    LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
+    if (c == 1) {
+        const_cast<RefBase*>(this)->onLastStrongRef(id);
+        if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+            delete this;
+        }
+    }
+    refs->removeWeakRef(id);
+    refs->decWeak(id);
+}
+
+void RefBase::forceIncStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
+               refs);
+#if PRINT_REFS
+    LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+
+    switch (c) {
+    case INITIAL_STRONG_VALUE:
+        android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+        // fall through...
+    case 0:
+        const_cast<RefBase*>(this)->onFirstRef();
+    }
+}
+
+int32_t RefBase::getStrongCount() const
+{
+    return mRefs->mStrong;
+}
+
+
+
+RefBase* RefBase::weakref_type::refBase() const
+{
+    return static_cast<const weakref_impl*>(this)->mBase;
+}
+
+void RefBase::weakref_type::incWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->addWeakRef(id);
+    const int32_t c = android_atomic_inc(&impl->mWeak);
+    LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
+}
+
+void RefBase::weakref_type::decWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->removeWeakRef(id);
+    const int32_t c = android_atomic_dec(&impl->mWeak);
+    LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
+    if (c != 1) return;
+    
+    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+        if (impl->mStrong == INITIAL_STRONG_VALUE)
+            delete impl->mBase;
+        else {
+//            LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+            delete impl;
+        }
+    } else {
+        impl->mBase->onLastWeakRef(id);
+        if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
+            delete impl->mBase;
+        }
+    }
+}
+
+bool RefBase::weakref_type::attemptIncStrong(const void* id)
+{
+    incWeak(id);
+    
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mStrong;
+    LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
+               this);
+    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
+            break;
+        }
+        curCount = impl->mStrong;
+    }
+    
+    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
+        bool allow;
+        if (curCount == INITIAL_STRONG_VALUE) {
+            // Attempting to acquire first strong reference...  this is allowed
+            // if the object does NOT have a longer lifetime (meaning the
+            // implementation doesn't need to see this), or if the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
+                  || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        } else {
+            // Attempting to revive the object...  this is allowed
+            // if the object DOES have a longer lifetime (so we can safely
+            // call the object with only a weak ref) and the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
+                  && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        }
+        if (!allow) {
+            decWeak(id);
+            return false;
+        }
+        curCount = android_atomic_inc(&impl->mStrong);
+
+        // If the strong reference count has already been incremented by
+        // someone else, the implementor of onIncStrongAttempted() is holding
+        // an unneeded reference.  So call onLastStrongRef() here to remove it.
+        // (No, this is not pretty.)  Note that we MUST NOT do this if we
+        // are in fact acquiring the first reference.
+        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
+            impl->mBase->onLastStrongRef(id);
+        }
+    }
+    
+    impl->addWeakRef(id);
+    impl->addStrongRef(id);
+
+#if PRINT_REFS
+    LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
+#endif
+
+    if (curCount == INITIAL_STRONG_VALUE) {
+        android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
+        impl->mBase->onFirstRef();
+    }
+    
+    return true;
+}
+
+bool RefBase::weakref_type::attemptIncWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mWeak;
+    LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
+               this);
+    while (curCount > 0) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
+            break;
+        }
+        curCount = impl->mWeak;
+    }
+
+    if (curCount > 0) {
+        impl->addWeakRef(id);
+    }
+
+    return curCount > 0;
+}
+
+int32_t RefBase::weakref_type::getWeakCount() const
+{
+    return static_cast<const weakref_impl*>(this)->mWeak;
+}
+
+void RefBase::weakref_type::printRefs() const
+{
+    static_cast<const weakref_impl*>(this)->printRefs();
+}
+
+void RefBase::weakref_type::trackMe(bool enable, bool retain)
+{
+    static_cast<const weakref_impl*>(this)->trackMe(enable, retain);
+}
+
+RefBase::weakref_type* RefBase::createWeak(const void* id) const
+{
+    mRefs->incWeak(id);
+    return mRefs;
+}
+
+RefBase::weakref_type* RefBase::getWeakRefs() const
+{
+    return mRefs;
+}
+
+RefBase::RefBase()
+    : mRefs(new weakref_impl(this))
+{
+//    LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
+}
+
+RefBase::~RefBase()
+{
+//    LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
+    if (mRefs->mWeak == 0) {
+//        LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
+        delete mRefs;
+    }
+}
+
+void RefBase::extendObjectLifetime(int32_t mode)
+{
+    android_atomic_or(mode, &mRefs->mFlags);
+}
+
+void RefBase::onFirstRef()
+{
+}
+
+void RefBase::onLastStrongRef(const void* /*id*/)
+{
+}
+
+bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return (flags&FIRST_INC_STRONG) ? true : false;
+}
+
+void RefBase::onLastWeakRef(const void* /*id*/)
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
new file mode 100644
index 0000000..a5fe9fb
--- /dev/null
+++ b/libs/utils/ResourceTypes.cpp
@@ -0,0 +1,3969 @@
+/*
+ * 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 <utils/Atomic.h>
+#include <utils/ByteOrder.h>
+#include <utils/Debug.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/Log.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 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
+
+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
+
+static void printToLogFunc(void* cookie, const char* txt)
+{
+    LOGV("%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;
+                }
+                LOGW("%s data size %p extends beyond resource end %p.",
+                     name, (void*)size,
+                     (void*)(dataEnd-((const uint8_t*)chunk)));
+                return BAD_TYPE;
+            }
+            LOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
+                 name, (int)size, (int)headerSize);
+            return BAD_TYPE;
+        }
+        LOGW("%s size %p is smaller than header size %p.",
+             name, (void*)size, (void*)(int)headerSize);
+        return BAD_TYPE;
+    }
+    LOGW("%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()
+{
+    return sizeof(Res_png_9patch)
+            + numXDivs * sizeof(int32_t)
+            + numYDivs * sizeof(int32_t)
+            + numColors * sizeof(uint32_t);
+}
+
+void* Res_png_9patch::serialize()
+{
+    void* newData = malloc(serializedSize());
+    serialize(newData);
+    return newData;
+}
+
+void Res_png_9patch::serialize(void * outData)
+{
+    char* data = (char*) outData;
+    memmove(data, this, sizeof(Res_png_9patch));
+    data +=  sizeof(Res_png_9patch);
+    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));
+}
+
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+    deserialize(inData, (Res_png_9patch*) inData);
+    return (Res_png_9patch*) inData;
+}
+
+void Res_png_9patch::deserialize(const void* inData, Res_png_9patch* outData) {
+    Res_png_9patch* patch = (Res_png_9patch*) inData;
+    if (inData != outData) {
+        memcpy(outData, inData, patch->serializedSize());
+    }
+    outData->wasDeserialized = true;
+    char* data = (char*)outData;
+    data +=  sizeof(Res_png_9patch);
+    outData->xDivs = (int32_t*) data;
+    data +=  patch->numXDivs * sizeof(int32_t);
+    outData->yDivs = (int32_t*) data;
+    data +=  patch->numYDivs * sizeof(int32_t);
+    outData->colors = (uint32_t*) data;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResStringPool::ResStringPool()
+    : mError(NO_INIT), mOwnedData(NULL)
+{
+}
+
+ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
+    : mError(NO_INIT), mOwnedData(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) {
+        LOGW("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) {
+            LOGW("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);
+        }
+        mStrings = (const char16_t*)
+            (((const uint8_t*)data)+mHeader->stringsStart);
+        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
+            LOGW("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)/sizeof(uint16_t);
+        } else {
+            // check invariant: styles follow the strings
+            if (mHeader->stylesStart <= mHeader->stringsStart) {
+                LOGW("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)/sizeof(uint16_t);
+        }
+
+        // check invariant: stringCount > 0 requires a string pool to exist
+        if (mStringPoolSize == 0) {
+            LOGW("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]);
+            }
+            char16_t* s = const_cast<char16_t*>(mStrings);
+            for (i=0; i<mStringPoolSize; i++) {
+                s[i] = dtohs(mStrings[i]);
+            }
+        }
+
+        if (mStrings[mStringPoolSize-1] != 0) {
+            LOGW("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) {
+            LOGW("Bad string block: integer overflow finding styles\n");
+            return (mError=BAD_TYPE);
+        }
+
+        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
+            LOGW("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) {
+            LOGW("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) {
+            LOGW("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 (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
+        if (off < (mStringPoolSize-1)) {
+            const char16_t* str = mStrings+off;
+            *outLen = *str;
+            if ((*str)&0x8000) {
+                str++;
+                *outLen = (((*outLen)&0x7fff)<<16) + *str;
+            }
+            if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
+                return str+1;
+            } else {
+                LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                        (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
+            }
+        } else {
+            LOGW("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 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 {
+            LOGW("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::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;
+            POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                         String8(str).string(),
+                         String8(s).string(),
+                         c, (int)l, (int)mid, (int)h));
+            if (c == 0) {
+                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);
+            POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
+                         String8(str, strLen).string(),
+                         String8(s).string(),
+                         i));
+            if (s && strzcmp16(s, len, str, strLen) == 0) {
+                return i;
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+size_t ResStringPool::size() const
+{
+    return (mError == NO_ERROR) ? mHeader->stringCount : 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;
+}
+
+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;
+}
+
+const 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;
+}
+
+const uint32_t ResXMLParser::getLineNumber() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
+}
+
+const 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;
+}
+
+const 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;
+}
+
+const 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;
+}
+
+const 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;
+}
+
+const 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;
+}
+
+const 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 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 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;
+}
+
+const 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) {
+        const size_t N = getAttributeCount();
+        for (size_t i=0; i<N; i++) {
+            size_t curNsLen, curAttrLen;
+            const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
+            const char16_t* curAttr = getAttributeName(i, &curAttrLen);
+            //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
+            //       i, ns, attr, curNs, curAttr);
+            //printf(" --> attr=%s, curAttr=%s\n",
+            //       String8(attr).string(), String8(curAttr).string());
+            if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
+                if (ns == NULL) {
+                    if (curNs == NULL) return i;
+                } else if (curNs != NULL) {
+                    //printf(" --> ns=%s, curNs=%s\n",
+                    //       String8(ns).string(), String8(curNs).string());
+                    if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) 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));
+        //LOGW("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:
+                LOGW("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) {
+            LOGW("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)
+{
+    //LOGI("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)
+{
+    //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    setTo(data, size, copyData);
+}
+
+ResXMLTree::~ResXMLTree()
+{
+    //LOGI("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 (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) {
+        LOGW("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) {
+        LOGW("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;
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+    restart();
+}
+
+const ResStringPool& ResXMLTree::getStrings() const
+{
+    return mStrings;
+}
+
+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;
+            }
+            LOGW("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 {
+            LOGW("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;
+                }
+                LOGW("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;
+            }
+            LOGW("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;
+        }
+        LOGW("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;
+    }
+    LOGW("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
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+struct ResTable::Header
+{
+    Header() : ownedData(NULL), header(NULL) { }
+
+    void*                           ownedData;
+    const ResTable_header*          header;
+    size_t                          size;
+    const uint8_t*                  dataEnd;
+    size_t                          index;
+    void*                           cookie;
+
+    ResStringPool                   values;
+};
+
+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(const Header* _header, const ResTable_package* _package)
+        : header(_header), package(_package) { }
+    ~Package()
+    {
+        size_t i = types.size();
+        while (i > 0) {
+            i--;
+            delete types[i];
+        }
+    }
+    
+    const Header* const             header;
+    const ResTable_package* const   package;
+    Vector<Type*>                   types;
+
+    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(const String16& _name, uint32_t _id)
+        : name(_name), id(_id), typeCount(0), bags(NULL) { }
+    ~PackageGroup() {
+        clearBagCache();
+        const size_t N = packages.size();
+        for (size_t i=0; i<N; i++) {
+            delete packages[i];
+        }
+    }
+
+    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;
+        }
+    }
+    
+    String16 const                  name;
+    uint32_t const                  id;
+    Vector<Package*>                packages;
+
+    // Taken from the root package.
+    ResStringPool                   typeStrings;
+    ResStringPool                   keyStrings;
+    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(LOGV("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) {
+                LOGE("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) {
+                LOGE("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) {
+            LOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
+            bag++;
+            continue;
+        }
+        theme_entry* curEntry = curEntries + e;
+        TABLE_NOISY(LOGV("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();
+
+    //LOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+status_t ResTable::Theme::setTo(const Theme& other)
+{
+    //LOGI("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;
+            }
+        }
+    }
+
+    //LOGI("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_NOISY(LOGV("Looking up attr 0x%08x in theme %p", resID, this));
+
+        if (p >= 0) {
+            const package_info* const pi = mPackages[p];
+            if (pi != NULL) {
+                if (t < pi->numTypes) {
+                    const type_info& ti = pi->types[t];
+                    if (e < ti.numEntries) {
+                        const theme_entry& te = ti.entries[e];
+                            if (outTypeSpecFlags != NULL) {
+                                *outTypeSpecFlags |= te.typeSpecFlags;
+                            }
+                        const uint8_t type = te.value.dataType;
+                        if (type == Res_value::TYPE_ATTRIBUTE) {
+                            if (cnt > 0) {
+                                cnt--;
+                                resID = te.value.data;
+                                continue;
+                            }
+                            LOGW("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) 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);
+        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);
+}
+
+void ResTable::Theme::dumpToLog() const
+{
+    LOGI("Theme %p:\n", this);
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi == NULL) continue;
+        
+        LOGI("  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;
+            
+            LOGI("    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;
+                LOGI("      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));
+    //LOGI("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");
+    //LOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::~ResTable()
+{
+    //LOGI("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)
+{
+    return add(data, size, cookie, NULL, copyData);
+}
+
+status_t ResTable::add(Asset* asset, void* cookie, bool copyData)
+{
+    const void* data = asset->getBuffer(true);
+    if (data == NULL) {
+        LOGW("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);
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie,
+                       Asset* asset, bool copyData)
+{
+    if (!data) return NO_ERROR;
+    Header* header = new Header;
+    header->index = mHeaders.size();
+    header->cookie = cookie;
+    mHeaders.add(header);
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    LOAD_TABLE_NOISY(
+        LOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d\n",
+             data, size, cookie, asset, copyData));
+    
+    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);
+    //LOGI("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(LOGV("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) {
+        LOGW("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) {
+        LOGW("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(LOGV("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 {
+                LOGW("Multiple string chunks found in resource table.");
+            }
+        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
+            if (curPackage >= dtohl(header->header->packageCount)) {
+                LOGW("More package chunks were found than the %d declared in the header.",
+                     dtohl(header->header->packageCount));
+                return (mError=BAD_TYPE);
+            }
+            if (parsePackage((ResTable_package*)chunk, header) != NO_ERROR) {
+                return mError;
+            }
+            curPackage++;
+        } else {
+            LOGW("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)) {
+        LOGW("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) {
+        LOGW("No string values found in resource table!");
+    }
+    TABLE_NOISY(LOGV("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->ownedData) {
+            free(header->ownedData);
+        }
+        delete header;
+    }
+
+    mPackageGroups.clear();
+    mHeaders.clear();
+}
+
+bool ResTable::getResourceName(uint32_t resID, 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) {
+        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("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();
+        outName->type = grp->typeStrings.stringAt(t, &outName->typeLen);
+        outName->name = grp->keyStrings.stringAt(
+            dtohl(entry->key.index), &outName->nameLen);
+        return true;
+    }
+
+    return false;
+}
+
+ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
+        uint32_t* outSpecFlags) 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) {
+        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("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) {
+        LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
+        return false;
+    }
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        if (offset <= 0) {
+            if (offset < 0) {
+                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
+                        resID, t, e, (int)ip, (int)offset);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
+            if (!mayBeBag) {
+                LOGW("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))) {
+            LOGW("ResTable_item at %d is beyond type chunk data %d",
+                 (int)offset, dtohl(type->header.size));
+            return BAD_TYPE;
+        }
+        
+        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.isBetterThan(thisConfig)) {
+            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);
+        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));
+        return bestPackage->header->index;
+    }
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) 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, &newFlags);
+        //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%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) {
+        LOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("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) {
+        LOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
+        return false;
+    }
+
+    if (t >= (int)grp->typeCount) {
+        LOGW("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) {
+        LOGW("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);
+                    //LOGI("Found existing bag for: %p\n", (void*)resID);
+                    return set->numAttrs;
+                }
+                LOGW("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***)malloc(sizeof(bag_set*)*grp->typeCount);
+        if (!grp->bags) return NO_MEMORY;
+        memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount);
+    }
+
+    bag_set** typeSet = grp->bags[t];
+    if (!typeSet) {
+        typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY);
+        if (!typeSet) return NO_MEMORY;
+        memset(typeSet, 0, sizeof(bag_set*)*NENTRY);
+        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(LOGI("Building bag: %p\n", (void*)resID));
+    
+    // Now collect all bag attributes from all packages.
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        LOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, t, e);
+        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        LOGV("Resulting offset=%d\n", offset);
+        if (offset <= 0) {
+            if (offset < 0) {
+                if (set) free(set);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
+            LOGW("Skipping entry %p in package table %d because it is not complex!\n",
+                 (void*)resID, (int)ip);
+            continue;
+        }
+
+        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(LOGI("Found map: size=%p parent=%p count=%d\n",
+                         entrySize, parent, count));
+
+        if (set == NULL) {
+            // 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(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+                } else {
+                    TABLE_NOISY(LOGI("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(LOGI("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))) {
+                LOGW("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(LOGI("Returning %d attrs\n", set->numAttrs));
+        return set->numAttrs;
+    }
+    return BAD_INDEX;
+}
+
+void ResTable::setParameters(const ResTable_config* params)
+{
+    mLock.lock();
+    TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
+                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                       params->mcc, params->mnc,
+                       params->language[0] ? params->language[0] : '-',
+                       params->language[1] ? params->language[1] : '-',
+                       params->country[0] ? params->country[0] : '-',
+                       params->country[1] ? params->country[1] : '-',
+                       params->orientation,
+                       params->touchscreen,
+                       params->density,
+                       params->keyboard,
+                       params->inputFlags,
+                       params->navigation,
+                       params->screenWidth,
+                       params->screenHeight));
+    mParams = *params;
+    for (size_t i=0; i<mPackageGroups.size(); i++) {
+        TABLE_NOISY(LOGI("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;
+                }
+            }
+            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)) {
+                    LOGW("Array resource index: %d is too large.",
+                         index);
+                    return 0;
+                }
+                return  Res_MAKEARRAY(index);
+            }
+        }
+        return 0;
+    }
+
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+
+    // 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 >= 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->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->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))) {
+                    LOGW("ResTable_entry at %d is beyond type chunk data %d",
+                         offset, dtohl(ty->header.size));
+                    return 0;
+                }
+                if ((offset&0x3) != 0) {
+                    LOGW("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)) {
+                    LOGW("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];
+                    }
+                    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)
+{
+    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 (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);
+    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, &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;
+                end++;
+                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, &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 == '\'')) {
+                    break;
+                }
+            }
+            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;
+    LOGD("calling getConfigurations");
+    getConfigurations(&configs);
+    LOGD("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
+{
+    LOGV("Getting entry from package %p\n", package);
+    const ResTable_package* const pkg = package->package;
+
+    const Type* allTypes = package->getType(typeIndex);
+    LOGV("allTypes=%p\n", allTypes);
+    if (allTypes == NULL) {
+        LOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
+        return 0;
+    }
+
+    if ((size_t)entryIndex >= allTypes->entryCount) {
+        LOGW("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(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
+                            "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
+                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
+                           thisConfig.mcc, thisConfig.mnc,
+                           config ? config->mcc : 0, config ? config->mnc : 0,
+                           thisConfig.language[0] ? thisConfig.language[0] : '-',
+                           thisConfig.language[1] ? thisConfig.language[1] : '-',
+                           config && config->language[0] ? config->language[0] : '-',
+                           config && config->language[1] ? config->language[1] : '-',
+                           thisConfig.country[0] ? thisConfig.country[0] : '-',
+                           thisConfig.country[1] ? thisConfig.country[1] : '-',
+                           config && config->country[0] ? config->country[0] : '-',
+                           config && config->country[1] ? config->country[1] : '-',
+                           thisConfig.orientation,
+                           config ? config->orientation : 0,
+                           thisConfig.touchscreen,
+                           config ? config->touchscreen : 0,
+                           thisConfig.density,
+                           config ? config->density : 0,
+                           thisConfig.keyboard,
+                           config ? config->keyboard : 0,
+                           thisConfig.inputFlags,
+                           config ? config->inputFlags : 0,
+                           thisConfig.navigation,
+                           config ? config->navigation : 0,
+                           thisConfig.screenWidth,
+                           config ? config->screenWidth : 0,
+                           thisConfig.screenHeight,
+                           config ? config->screenHeight : 0));
+        
+        // Check to make sure this one is valid for the current parameters.
+        if (config && !thisConfig.match(*config)) {
+            TABLE_GETENTRY(LOGI("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(LOGI("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(LOGI("This config is worse than last!\n"));
+                continue;
+            }
+        }
+        
+        type = thisType;
+        offset = thisOffset;
+        bestConfig = thisConfig;
+        TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+        if (!config) break;
+    }
+    
+    if (type == NULL) {
+        TABLE_GETENTRY(LOGI("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))) {
+        LOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
+             offset, dtohl(type->header.size));
+        return BAD_TYPE;
+    }
+    if ((offset&0x3) != 0) {
+        LOGW("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)) {
+        LOGW("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)
+{
+    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) {
+        LOGW("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) {
+        LOGW("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) {
+        LOGW("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) {
+        LOGW("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 = dtohl(pkg->id);
+    if (id != 0 && id < 256) {
+        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(String16(tmpName), id);
+            if (group == NULL) {
+                return (mError=NO_MEMORY);
+            }
+
+            err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings),
+                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings),
+                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
+            if (err != NO_ERROR) {
+                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);
+            }
+            mPackageMap[id] = (uint8_t)idx;
+        } else {
+            group = mPackageGroups.itemAt(idx-1);
+            if (group == NULL) {
+                return (mError=UNKNOWN_ERROR);
+            }
+        }
+        package = new Package(header, pkg);
+        if (package == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        err = group->packages.add(package);
+        if (err < NO_ERROR) {
+            return (mError=err);
+        }
+    } else {
+        LOG_ALWAYS_FATAL("Skins not supported!");
+        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(LOGV("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)) {
+                LOGW("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) {
+                LOGW("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) {
+                LOGW("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) {
+                LOGW("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))) {
+                LOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
+                     (void*)dtohl(type->entriesStart), (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (type->id == 0) {
+                LOGW("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) {
+                LOGW("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);
+                LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
+                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                      type->id,
+                      thisConfig.mcc, thisConfig.mnc,
+                      thisConfig.language[0] ? thisConfig.language[0] : '-',
+                      thisConfig.language[1] ? thisConfig.language[1] : '-',
+                      thisConfig.country[0] ? thisConfig.country[0] : '-',
+                      thisConfig.country[1] ? thisConfig.country[1] : '-',
+                      thisConfig.orientation,
+                      thisConfig.touchscreen,
+                      thisConfig.density,
+                      thisConfig.keyboard,
+                      thisConfig.inputFlags,
+                      thisConfig.navigation,
+                      thisConfig.screenWidth,
+                      thisConfig.screenHeight));
+            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;
+}
+
+#ifndef HAVE_ANDROID_OS
+#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))))
+
+void ResTable::print() const
+{
+    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;
+                        this->getResourceName(resID, &resName);
+                        printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
+                            resID,
+                            CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                            CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                            CHAR16_TO_CSTR(resName.name, resName.nameLen),
+                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                    }
+                }
+                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
+                    const ResTable_type* type = typeConfigs->configs[configIndex];
+                    if ((((int)type)&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
+                        continue;
+                    }
+                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
+                           (int)configIndex,
+                           type->config.language[0] ? type->config.language[0] : '-',
+                           type->config.language[1] ? type->config.language[1] : '-',
+                           type->config.country[0] ? type->config.country[0] : '-',
+                           type->config.country[1] ? type->config.country[1] : '-',
+                           type->config.orientation,
+                           type->config.touchscreen,
+                           dtohs(type->config.density),
+                           type->config.keyboard,
+                           type->config.inputFlags,
+                           type->config.navigation,
+                           dtohs(type->config.screenWidth),
+                           dtohs(type->config.screenHeight));
+                    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;
+                        this->getResourceName(resID, &resName);
+                        printf("        resource 0x%08x %s:%s/%s: ", resID,
+                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                                CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                        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;
+                        }
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
+                            printf("<bag>");
+                        } else {
+                            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* value = (const Res_value*)
+                                (((const uint8_t*)ent) + esize);
+                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
+                                   (int)value->dataType, (int)dtohl(value->data),
+                                   (int)dtohs(value->size), (int)value->res0);
+                        }
+                        
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
+                            printf(" (PUBLIC)");
+                        }
+                        printf("\n");
+                    }
+                }
+            }
+        }
+    }
+}
+
+#endif // HAVE_ANDROID_OS
+
+}   // namespace android
diff --git a/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp
new file mode 100644
index 0000000..3555fb7
--- /dev/null
+++ b/libs/utils/SharedBuffer.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <utils/SharedBuffer.h>
+#include <utils/Atomic.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+SharedBuffer* SharedBuffer::alloc(size_t size)
+{
+    SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
+    if (sb) {
+        sb->mRefs = 1;
+        sb->mSize = size;
+    }
+    return sb;
+}
+
+
+ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
+{
+    if (released->mRefs != 0) return -1; // XXX: invalid operation
+    free(const_cast<SharedBuffer*>(released));
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::edit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    SharedBuffer* sb = alloc(mSize);
+    if (sb) {
+        memcpy(sb->data(), data(), size());
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::editResize(size_t newSize) const
+{
+    if (onlyOwner()) {
+        SharedBuffer* buf = const_cast<SharedBuffer*>(this);
+        if (buf->mSize == newSize) return buf;
+        buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
+        if (buf != NULL) {
+            buf->mSize = newSize;
+            return buf;
+        }
+    }
+    SharedBuffer* sb = alloc(newSize);
+    if (sb) {
+        const size_t mySize = mSize;
+        memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::attemptEdit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::reset(size_t new_size) const
+{
+    // cheap-o-reset.
+    SharedBuffer* sb = alloc(new_size);
+    if (sb) {
+        release();
+    }
+    return sb;
+}
+
+void SharedBuffer::acquire() const {
+    android_atomic_inc(&mRefs);
+}
+
+int32_t SharedBuffer::release(uint32_t flags) const
+{
+    int32_t prev = 1;
+    if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
+        mRefs = 0;
+        if ((flags & eKeepStorage) == 0) {
+            free(const_cast<SharedBuffer*>(this));
+        }
+    }
+    return prev;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/Socket.cpp b/libs/utils/Socket.cpp
new file mode 100644
index 0000000..51509a3
--- /dev/null
+++ b/libs/utils/Socket.cpp
@@ -0,0 +1,388 @@
+/*
+ * 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.
+ */
+
+//
+// Internet address class.
+//
+
+#ifdef HAVE_WINSOCK
+// This needs to come first, or Cygwin gets concerned about a potential
+// clash between WinSock and <sys/types.h>.
+# include <winsock2.h>
+#endif
+
+#include <utils/Socket.h>
+#include <utils/inet_address.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#ifndef HAVE_WINSOCK
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      Socket
+ * ===========================================================================
+ */
+
+#ifndef INVALID_SOCKET
+# define INVALID_SOCKET (-1)
+#endif
+#define UNDEF_SOCKET   ((unsigned long) INVALID_SOCKET)
+
+/*static*/ bool Socket::mBootInitialized = false;
+
+/*
+ * Extract system-dependent error code.
+ */
+static inline int getSocketError(void) {
+#ifdef HAVE_WINSOCK
+    return WSAGetLastError();
+#else
+    return errno;
+#endif
+}
+
+/*
+ * One-time initialization for socket code.
+ */
+/*static*/ bool Socket::bootInit(void)
+{
+#ifdef HAVE_WINSOCK
+    WSADATA wsaData;
+    int err;
+
+    err = WSAStartup(MAKEWORD(2, 0), &wsaData);
+    if (err != 0) {
+        LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
+        return false;
+    }
+
+    LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
+        LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
+#endif
+
+    mBootInitialized = true;
+    return true;
+}
+
+/*
+ * One-time shutdown for socket code.
+ */
+/*static*/ void Socket::finalShutdown(void)
+{
+#ifdef HAVE_WINSOCK
+    WSACleanup();
+#endif
+    mBootInitialized = false;
+}
+
+
+/*
+ * Simple constructor.  Allow the application to create us and then make
+ * bind/connect calls.
+ */
+Socket::Socket(void)
+    : mSock(UNDEF_SOCKET)
+{
+    if (!mBootInitialized)
+        LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
+}
+
+/*
+ * Destructor.  Closes the socket and resets our storage.
+ */
+Socket::~Socket(void)
+{
+    close();
+}
+
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const char* host, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(host, port))
+        return -1;
+
+    //return doConnect(sockAddr);
+    int foo;
+    foo = doConnect(sockAddr);
+    return foo;
+}
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const InetAddress* addr, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(addr, port))
+        return -1;
+
+    return doConnect(sockAddr);
+}
+
+/*
+ * Finish creating a socket by connecting to the remote host.
+ *
+ * Returns 0 on success.
+ */
+int Socket::doConnect(const InetSocketAddress& sockAddr)
+{
+#ifdef HAVE_WINSOCK
+    SOCKET sock;
+#else
+    int sock;
+#endif
+    const InetAddress* addr = sockAddr.getAddress();
+    int port = sockAddr.getPort();
+    struct sockaddr_in inaddr;
+    DurationTimer connectTimer;
+
+    assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
+    memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
+    inaddr.sin_port = htons(port);
+
+    //fprintf(stderr, "--- connecting to %s:%d\n",
+    //    sockAddr.getHostName(), port);
+
+    sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sock == INVALID_SOCKET) {
+        int err = getSocketError();
+        LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.start();
+
+    if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
+        int err = getSocketError();
+        LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
+            sockAddr.getHostName(), port, err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.stop();
+    if ((long) connectTimer.durationUsecs() > 100000) {
+        LOG(LOG_INFO, "socket",
+            "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
+            port, ((long) connectTimer.durationUsecs()) / 1000000.0);
+    }
+
+    mSock = (unsigned long) sock;
+    LOG(LOG_VERBOSE, "socket",
+        "--- connected to %s:%d\n", sockAddr.getHostName(), port);
+    return 0;
+}
+
+
+/*
+ * Close the socket if it needs closing.
+ */
+bool Socket::close(void)
+{
+    if (mSock != UNDEF_SOCKET) {
+        //fprintf(stderr, "--- closing socket %lu\n", mSock);
+#ifdef HAVE_WINSOCK
+        if (::closesocket((SOCKET) mSock) != 0)
+            return false;
+#else
+        if (::close((int) mSock) != 0)
+            return false;
+#endif
+    }
+
+    mSock = UNDEF_SOCKET;
+
+    return true;
+}
+
+/*
+ * Read data from socket.
+ *
+ * Standard semantics: read up to "len" bytes into "buf".  Returns the
+ * number of bytes read, or less than zero on error.
+ */
+int Socket::read(void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = recv(sock, (char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+/*
+ * Write data to a socket.
+ *
+ * Standard semantics: write up to "len" bytes into "buf".  Returns the
+ * number of bytes written, or less than zero on error.
+ */
+int Socket::write(const void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = send(sock, (const char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+
+/*
+ * ===========================================================================
+ *      Socket tests
+ * ===========================================================================
+ */
+
+/*
+ * Read all data from the socket.  The data is read into a buffer that
+ * expands as needed.
+ *
+ * On exit, the buffer is returned, and the length of the data is stored
+ * in "*sz".  A null byte is added to the end, but is not included in
+ * the length.
+ */
+static char* socketReadAll(const Socket& s, int *sz)
+{
+    int max, r;
+    char *data, *ptr, *tmp;
+
+    data = (char*) malloc(max = 32768);
+    if (data == NULL)
+        return NULL;
+
+    ptr = data;
+    
+    for (;;) {
+        if ((ptr - data) == max) {
+            tmp = (char*) realloc(data, max *= 2);
+            if(tmp == 0) {
+                free(data);
+                return 0;
+            }
+        }
+        r = s.read(ptr, max - (ptr - data));
+        if (r == 0)
+            break;
+        if (r < 0) {
+            LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
+            break;
+        }
+        ptr += r;
+    }
+
+    if ((ptr - data) == max) {
+        tmp = (char*) realloc(data, max + 1);
+        if (tmp == NULL) {
+            free(data);
+            return NULL;
+        }
+    }
+    *ptr = '\0';
+    *sz = (ptr - data);
+    return data;
+}
+
+/*
+ * Exercise the Socket class.
+ */
+void android::TestSockets(void)
+{
+    printf("----- SOCKET TEST ------\n");
+    Socket::bootInit();
+
+    char* buf = NULL;
+    int len, cc;
+    const char* kTestStr =
+        "GET / HTTP/1.0\n"
+        "Connection: close\n"
+        "\n";
+
+    Socket sock;
+    if (sock.connect("www.google.com", 80) != 0) {
+        fprintf(stderr, "socket connected failed\n");
+        goto bail;
+    }
+
+    cc = sock.write(kTestStr, strlen(kTestStr));
+    if (cc != (int) strlen(kTestStr)) {
+        fprintf(stderr, "write failed, res=%d\n", cc);
+        goto bail;
+    }
+    buf = socketReadAll(sock, &len);
+
+    printf("GOT '%s'\n", buf);
+
+bail:
+    sock.close();
+    free(buf);
+}
+
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
new file mode 100644
index 0000000..93f7e4f
--- /dev/null
+++ b/libs/utils/Static.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <private/utils/Static.h>
+
+#include <utils/BufferedTextOutput.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+namespace android {
+
+class LibUtilsFirstStatics
+{
+public:
+    LibUtilsFirstStatics()
+    {
+        initialize_string8();
+        initialize_string16();
+    }
+    
+    ~LibUtilsFirstStatics()
+    {
+        terminate_string16();
+        terminate_string8();
+    }
+};
+
+static LibUtilsFirstStatics gFirstStatics;
+int gDarwinCantLoadAllObjects = 1;
+
+// ------------ Text output streams
+
+Vector<int32_t> gTextBuffers;
+
+class LogTextOutput : public BufferedTextOutput
+{
+public:
+    LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
+    virtual ~LogTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        android_writevLog(&vec, N);
+        return NO_ERROR;
+    }
+};
+
+class FdTextOutput : public BufferedTextOutput
+{
+public:
+    FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
+    virtual ~FdTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        writev(mFD, &vec, N);
+        return NO_ERROR;
+    }
+
+private:
+    int mFD;
+};
+
+static LogTextOutput gLogTextOutput;
+static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
+static FdTextOutput gStderrTextOutput(STDERR_FILENO);
+
+TextOutput& alog(gLogTextOutput);
+TextOutput& aout(gStdoutTextOutput);
+TextOutput& aerr(gStderrTextOutput);
+
+#ifndef LIBUTILS_NATIVE
+
+// ------------ ProcessState.cpp
+
+Mutex gProcessMutex;
+sp<ProcessState> gProcess;
+
+class LibUtilsIPCtStatics
+{
+public:
+    LibUtilsIPCtStatics()
+    {
+    }
+    
+    ~LibUtilsIPCtStatics()
+    {
+        IPCThreadState::shutdown();
+    }
+};
+
+static LibUtilsIPCtStatics gIPCStatics;
+
+// ------------ ServiceManager.cpp
+
+Mutex gDefaultServiceManagerLock;
+sp<IServiceManager> gDefaultServiceManager;
+sp<IPermissionController> gPermissionController;
+
+#endif
+
+}   // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
new file mode 100644
index 0000000..68a1c52
--- /dev/null
+++ b/libs/utils/StopWatch.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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 "StopWatch"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/StopWatch.h>
+
+/*****************************************************************************/
+
+namespace android {
+
+
+StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
+    :   mName(name), mClock(clock), mFlags(flags),
+        mStartTime(0), mNumLaps(0)
+{
+    mStartTime = systemTime(mClock);
+}
+
+StopWatch::~StopWatch()
+{
+    nsecs_t elapsed = elapsedTime();
+    const int n = mNumLaps;
+    LOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
+    for (int i=0 ; i<n ; i++) {
+        const nsecs_t soFar = mLaps[i].soFar;
+        const nsecs_t thisLap = mLaps[i].thisLap;
+        LOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
+    }
+}
+
+const char* StopWatch::name() const
+{
+    return mName;
+}
+
+nsecs_t StopWatch::lap()
+{
+    nsecs_t elapsed = elapsedTime();
+    if (mNumLaps >= 8) {
+        elapsed = 0;
+    } else {
+        const int n = mNumLaps;
+        mLaps[n].soFar   = elapsed;
+        mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;
+        mNumLaps = n+1;
+    }
+    return elapsed;
+}
+
+nsecs_t StopWatch::elapsedTime() const
+{
+    return systemTime(mClock) - mStartTime;
+}
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
new file mode 100644
index 0000000..1f81cad
--- /dev/null
+++ b/libs/utils/String16.cpp
@@ -0,0 +1,609 @@
+/*
+ * 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 <utils/String16.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#ifdef HAVE_WINSOCK
+# undef  nhtol
+# undef  htonl
+# undef  nhtos
+# undef  htons
+
+# 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
+#else
+# include <netinet/in.h>
+#endif
+
+#include <memory.h>
+#include <stdio.h>
+#include <ctype.h>
+
+// ---------------------------------------------------------------------------
+
+int strcmp16(const char16_t *s1, const char16_t *s2)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( 1 ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( n-- ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+char16_t *strcpy16(char16_t *dst, const char16_t *src)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char16_t ch;
+
+  do {
+    *q++ = ch = *p++;
+  } while ( ch );
+
+  return dst;
+}
+
+size_t strlen16(const char16_t *s)
+{
+  const char16_t *ss = s;
+  while ( *ss )
+    ss++;
+  return ss-s;
+}
+
+
+char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char ch;
+
+  while (n) {
+    n--;
+    *q++ = ch = *p++;
+    if ( !ch )
+      break;
+  }
+
+  *q = 0;
+
+  return dst;
+}
+
+size_t strnlen16(const char16_t *s, size_t maxlen)
+{
+  const char16_t *ss = s;
+
+  /* Important: the maxlen test must precede the reference through ss;
+     since the byte beyond the maximum may segfault */
+  while ((maxlen > 0) && *ss) {
+    ss++;
+    maxlen--;
+  }
+  return ss-s;
+}
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+    const char16_t* e1 = s1+n1;
+    const char16_t* e2 = s2+n2;
+
+    while (s1 < e1 && s2 < e2) {
+        const int d = (int)*s1++ - (int)*s2++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)*s2)
+        : (n1 > n2
+           ? ((int)*s1 - 0)
+           : 0);
+}
+
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
+{
+    const char16_t* e1 = s1H+n1;
+    const char16_t* e2 = s2N+n2;
+
+    while (s1H < e1 && s2N < e2) {
+        const char16_t c2 = ntohs(*s2N);
+        const int d = (int)*s1H++ - (int)c2;
+        s2N++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)ntohs(*s2N))
+        : (n1 > n2
+           ? ((int)*s1H - 0)
+           : 0);
+}
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static inline size_t
+utf8_char_len(uint8_t ch)
+{
+    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
+}
+
+#define UTF8_SHIFT_AND_MASK(unicode, byte)  (unicode)<<=6; (unicode) |= (0x3f & (byte));
+
+static inline uint32_t
+utf8_to_utf32(const uint8_t *src, size_t length)
+{
+    uint32_t unicode;
+
+    switch (length)
+    {
+        case 1:
+            return src[0];
+        case 2:
+            unicode = src[0] & 0x1f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            return unicode;
+        case 3:
+            unicode = src[0] & 0x0f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            return unicode;
+        case 4:
+            unicode = src[0] & 0x07;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            UTF8_SHIFT_AND_MASK(unicode, src[3])
+            return unicode;
+        default:
+            return 0xffff;
+    }
+    
+    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char16_t* gEmptyString = NULL;
+
+static inline char16_t* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+   return gEmptyString;
+}
+
+void initialize_string16()
+{
+    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
+    char16_t* str = (char16_t*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string16()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+// Note: not dealing with generating surrogate pairs.
+static char16_t* allocFromUTF8(const char* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t chars = 0;
+    const char* end = in+len;
+    const char* p = in;
+    
+    while (p < end) {
+        chars++;
+        p += utf8_char_len(*p);
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
+    if (buf) {
+        p = in;
+        char16_t* str = (char16_t*)buf->data();
+        char16_t* d = str;
+        while (p < end) {
+            size_t len = utf8_char_len(*p);
+            *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
+            p += len;
+        }
+        *d = 0;
+        
+        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
+        //printHexData(1, str, buf->size(), 16, 1);
+        //printf("\n");
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String16::String16()
+    : mString(getEmptyString())
+{
+}
+
+String16::String16(const String16& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String16::String16(const String16& o, size_t len, size_t begin)
+    : mString(getEmptyString())
+{
+    setTo(o, len, begin);
+}
+
+String16::String16(const char16_t* o)
+{
+    size_t len = strlen16(o);
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        strcpy16(str, o);
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const char16_t* o, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, o, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const String8& o)
+    : mString(allocFromUTF8(o.string(), o.size()))
+{
+}
+
+String16::String16(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+}
+
+String16::String16(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+}
+
+String16::~String16()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String16::setTo(const String16& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String16::setTo(const String16& other, size_t len, size_t begin)
+{
+    const size_t N = other.size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        setTo(other);
+        return NO_ERROR;
+    }
+
+    if (&other == this) {
+        LOG_ALWAYS_FATAL("Not implemented");
+    }
+
+    return setTo(other.string()+begin, len);
+}
+
+status_t String16::setTo(const char16_t* other)
+{
+    return setTo(other, strlen16(other));
+}
+
+status_t String16::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, other, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const String16& other)
+{
+    const size_t myLen = size();
+    const size_t otherLen = other.size();
+    if (myLen == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const char16_t* chrs, size_t otherLen)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        setTo(chrs, otherLen);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
+        str[myLen+otherLen] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs)
+{
+    return insert(pos, chrs, strlen16(chrs));
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        return setTo(chrs, len);
+        return NO_ERROR;
+    } else if (len == 0) {
+        return NO_ERROR;
+    }
+
+    if (pos > myLen) pos = myLen;
+
+    #if 0
+    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
+           String8(*this).string(), pos,
+           len, myLen, String8(chrs, len).string());
+    #endif
+
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        if (pos < myLen) {
+            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
+        }
+        memcpy(str+pos, chrs, len*sizeof(char16_t));
+        str[myLen+len] = 0;
+        mString = str;
+        #if 0
+        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
+        #endif
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+ssize_t String16::findFirst(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        if (*p == c) {
+            return p-str;
+        }
+        p++;
+    }
+    return -1;
+}
+
+ssize_t String16::findLast(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        e--;
+        if (*e == c) {
+            return e-str;
+        }
+    }
+    return -1;
+}
+
+bool String16::startsWith(const String16& prefix) const
+{
+    const size_t ps = prefix.size();
+    if (ps > size()) return false;
+    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
+}
+
+bool String16::startsWith(const char16_t* prefix) const
+{
+    const size_t ps = strlen16(prefix);
+    if (ps > size()) return false;
+    return strncmp16(mString, prefix, ps) == 0;
+}
+
+status_t String16::makeLower()
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        const char16_t v = str[i];
+        if (v >= 'A' && v <= 'Z') {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = tolower((char)v);
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        if (str[i] == replaceThis) {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = withThis;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::remove(size_t len, size_t begin)
+{
+    const size_t N = size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        return NO_ERROR;
+    }
+
+    if (begin > 0) {
+        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+            ->editResize((N+1)*sizeof(char16_t));
+        if (!buf) {
+            return NO_MEMORY;
+        }
+        char16_t* str = (char16_t*)buf->data();
+        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
+        mString = str;
+    }
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+TextOutput& operator<<(TextOutput& to, const String16& val)
+{
+    to << String8(val).string();
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
new file mode 100644
index 0000000..ab843f6
--- /dev/null
+++ b/libs/utils/String8.cpp
@@ -0,0 +1,602 @@
+/*
+ * 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 <utils/String8.h>
+
+#include <utils/Log.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+static const uint32_t kByteMask = 0x000000BF;
+static const uint32_t kByteMark = 0x00000080;
+
+// Surrogates aren't valid for UTF-32 characters, so define some
+// constants that will let us screen them out.
+static const uint32_t kUnicodeSurrogateHighStart  = 0x0000D800;
+static const uint32_t kUnicodeSurrogateHighEnd    = 0x0000DBFF;
+static const uint32_t kUnicodeSurrogateLowStart   = 0x0000DC00;
+static const uint32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;
+static const uint32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;
+static const uint32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;
+
+// Mask used to set appropriate bits in first byte of UTF-8 sequence,
+// indexed by number of bytes in the sequence.
+static const uint32_t kFirstByteMark[] = {
+    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
+};
+
+// Separator used by resource paths. This is not platform dependent contrary
+// to OS_PATH_SEPARATOR.
+#define RES_PATH_SEPARATOR '/'
+
+// Return number of utf8 bytes required for the character.
+static size_t utf32_to_utf8_bytes(uint32_t srcChar)
+{
+    size_t bytesToWrite;
+
+    // Figure out how many bytes the result will require.
+    if (srcChar < 0x00000080)
+    {
+        bytesToWrite = 1;
+    }
+    else if (srcChar < 0x00000800)
+    {
+        bytesToWrite = 2;
+    }
+    else if (srcChar < 0x00010000)
+    {
+        if ((srcChar < kUnicodeSurrogateStart)
+         || (srcChar > kUnicodeSurrogateEnd))
+        {
+            bytesToWrite = 3;
+        }
+        else
+        {
+            // Surrogates are invalid UTF-32 characters.
+            return 0;
+        }
+    }
+    // Max code point for Unicode is 0x0010FFFF.
+    else if (srcChar < 0x00110000)
+    {
+        bytesToWrite = 4;
+    }
+    else
+    {
+        // Invalid UTF-32 character.
+        return 0;
+    }
+
+    return bytesToWrite;
+}
+
+// Write out the source character to <dstP>.
+
+static void utf32_to_utf8(uint8_t* dstP, uint32_t srcChar, size_t bytes)
+{
+    dstP += bytes;
+    switch (bytes)
+    {   /* note: everything falls through. */
+        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char* gEmptyString = NULL;
+
+extern int gDarwinCantLoadAllObjects;
+int gDarwinIsReallyAnnoying;
+
+static inline char* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+    return gEmptyString;
+}
+
+void initialize_string8()
+{
+#ifdef LIBUTILS_NATIVE
+	  // Bite me, Darwin!
+		gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
+#endif
+			
+    SharedBuffer* buf = SharedBuffer::alloc(1);
+    char* str = (char*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string8()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+static char* allocFromUTF8(const char* in, size_t len)
+{
+    if (len > 0) {
+        SharedBuffer* buf = SharedBuffer::alloc(len+1);
+        LOG_ASSERT(buf, "Unable to allocate shared buffer");
+        if (buf) {
+            char* str = (char*)buf->data();
+            memcpy(str, in, len);
+            str[len] = 0;
+            return str;
+        }
+        return NULL;
+    }
+
+    return getEmptyString();
+}
+
+// Note: not dealing with expanding surrogate pairs.
+static char* allocFromUTF16(const char16_t* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t bytes = 0;
+    const char16_t* end = in+len;
+    const char16_t* p = in;
+    
+    while (p < end) {
+        bytes += utf32_to_utf8_bytes(*p);
+        p++;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        p = in;
+        char* str = (char*)buf->data();
+        char* d = str;
+        while (p < end) {
+            uint32_t c = *p++;
+            size_t len = utf32_to_utf8_bytes(c);
+            utf32_to_utf8((uint8_t*)d, c, len);
+            d += len;
+        }
+        *d = 0;
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String8::String8()
+    : mString(getEmptyString())
+{
+}
+
+String8::String8(const String8& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String8::String8(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const String16& o)
+    : mString(allocFromUTF16(o.string(), o.size()))
+{
+}
+
+String8::String8(const char16_t* o)
+    : mString(allocFromUTF16(o, strlen16(o)))
+{
+}
+
+String8::String8(const char16_t* o, size_t len)
+    : mString(allocFromUTF16(o, len))
+{
+}
+
+String8::~String8()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String8::setTo(const String8& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String8::setTo(const char* other)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, strlen(other));
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF16(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::append(const String8& other)
+{
+    const size_t otherLen = other.bytes();
+    if (bytes() == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other.string(), otherLen);
+}
+
+status_t String8::append(const char* other)
+{
+    return append(other, strlen(other));
+}
+
+status_t String8::append(const char* other, size_t otherLen)
+{
+    if (bytes() == 0) {
+        return setTo(other, otherLen);
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other, otherLen);
+}
+
+status_t String8::real_append(const char* other, size_t otherLen)
+{
+    const size_t myLen = bytes();
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(myLen+otherLen+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        memcpy(str+myLen, other, otherLen+1);
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+char* String8::lockBuffer(size_t size)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(size+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        mString = str;
+        return str;
+    }
+    return NULL;
+}
+
+void String8::unlockBuffer()
+{
+    unlockBuffer(strlen(mString));
+}
+
+status_t String8::unlockBuffer(size_t size)
+{
+    if (size != this->size()) {
+        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+            ->editResize(size+1);
+        if (buf) {
+            char* str = (char*)buf->data();
+            str[size] = 0;
+            mString = str;
+            return NO_ERROR;
+        }
+    }
+    
+    return NO_MEMORY;
+}
+
+ssize_t String8::find(const char* other, size_t start) const
+{
+    size_t len = size();
+    if (start >= len) {
+        return -1;
+    }
+    const char* s = mString+start;
+    const char* p = strstr(s, other);
+    return p ? p-mString : -1;
+}
+
+void String8::toLower()
+{
+    toLower(0, size());
+}
+
+void String8::toLower(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = tolower(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+void String8::toUpper()
+{
+    toUpper(0, size());
+}
+
+void String8::toUpper(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = toupper(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+TextOutput& operator<<(TextOutput& to, const String8& val)
+{
+    to << val.string();
+    return to;
+}
+
+// ---------------------------------------------------------------------------
+// Path functions
+
+
+void String8::setPathName(const char* name)
+{
+    setPathName(name, strlen(name));
+}
+
+void String8::setPathName(const char* name, size_t len)
+{
+    char* buf = lockBuffer(len);
+
+    memcpy(buf, name, len);
+
+    // remove trailing path separator, if present
+    if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
+        len--;
+
+    buf[len] = '\0';
+
+    unlockBuffer(len);
+}
+
+String8 String8::getPathLeaf(void) const
+{
+    const char* cp;
+    const char*const buf = mString;
+
+    cp = strrchr(buf, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8(*this);
+    else
+        return String8(cp+1);
+}
+
+String8 String8::getPathDir(void) const
+{
+    const char* cp;
+    const char*const str = mString;
+
+    cp = strrchr(str, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8("");
+    else
+        return String8(str, cp - str);
+}
+
+String8 String8::walkPath(String8* outRemains) const
+{
+    const char* cp;
+    const char*const str = mString;
+    const char* buf = str;
+
+    cp = strchr(buf, OS_PATH_SEPARATOR);
+    if (cp == buf) {
+        // don't include a leading '/'.
+        buf = buf+1;
+        cp = strchr(buf, OS_PATH_SEPARATOR);
+    }
+
+    if (cp == NULL) {
+        String8 res = buf != str ? String8(buf) : *this;
+        if (outRemains) *outRemains = String8("");
+        return res;
+    }
+
+    String8 res(buf, cp-buf);
+    if (outRemains) *outRemains = String8(cp+1);
+    return res;
+}
+
+/*
+ * Helper function for finding the start of an extension in a pathname.
+ *
+ * Returns a pointer inside mString, or NULL if no extension was found.
+ */
+char* String8::find_extension(void) const
+{
+    const char* lastSlash;
+    const char* lastDot;
+    int extLen;
+    const char* const str = mString;
+
+    // only look at the filename
+    lastSlash = strrchr(str, OS_PATH_SEPARATOR);
+    if (lastSlash == NULL)
+        lastSlash = str;
+    else
+        lastSlash++;
+
+    // find the last dot
+    lastDot = strrchr(lastSlash, '.');
+    if (lastDot == NULL)
+        return NULL;
+
+    // looks good, ship it
+    return const_cast<char*>(lastDot);
+}
+
+String8 String8::getPathExtension(void) const
+{
+    char* ext;
+
+    ext = find_extension();
+    if (ext != NULL)
+        return String8(ext);
+    else
+        return String8("");
+}
+
+String8 String8::getBasePath(void) const
+{
+    char* ext;
+    const char* const str = mString;
+
+    ext = find_extension();
+    if (ext == NULL)
+        return String8(*this);
+    else
+        return String8(str, ext - str);
+}
+
+String8& String8::appendPath(const char* name)
+{
+    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
+    if (name[0] != OS_PATH_SEPARATOR) {
+        if (*name == '\0') {
+            // nothing to do
+            return *this;
+        }
+
+        size_t len = length();
+        if (len == 0) {
+            // no existing filename, just use the new one
+            setPathName(name);
+            return *this;
+        }
+
+        // make room for oldPath + '/' + newPath
+        int newlen = strlen(name);
+
+        char* buf = lockBuffer(len+1+newlen);
+
+        // insert a '/' if needed
+        if (buf[len-1] != OS_PATH_SEPARATOR)
+            buf[len++] = OS_PATH_SEPARATOR;
+
+        memcpy(buf+len, name, newlen+1);
+        len += newlen;
+
+        unlockBuffer(len);
+
+        return *this;
+    } else {
+        setPathName(name);
+        return *this;
+    }
+}
+
+String8& String8::convertToResPath()
+{
+#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
+    size_t len = length();
+    if (len > 0) {
+        char * buf = lockBuffer(len);
+        for (char * end = buf + len; buf < end; ++buf) {
+            if (*buf == OS_PATH_SEPARATOR)
+                *buf = RES_PATH_SEPARATOR;
+        }
+        unlockBuffer(len);
+    }
+#endif
+    return *this;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
new file mode 100644
index 0000000..2bdc0ce
--- /dev/null
+++ b/libs/utils/SystemClock.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * System clock functions.
+ */
+
+#if HAVE_ANDROID_OS
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+#endif
+
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <utils/SystemClock.h>
+#include <utils/Timers.h>
+
+#define LOG_TAG "SystemClock"
+#include "utils/Log.h"
+
+namespace android {
+
+/*
+ * Set the current time.  This only works when running as root.
+ */
+int setCurrentTimeMillis(int64_t millis)
+{
+#if WIN32
+    // not implemented
+    return -1;
+#else
+    struct timeval tv;
+#if HAVE_ANDROID_OS
+    struct timespec ts;
+    int fd;
+    int res;
+#endif
+    int ret = 0;
+
+    if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+        return -1;
+    }
+
+    tv.tv_sec = (time_t) (millis / 1000LL);
+    tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+    LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+#if HAVE_ANDROID_OS
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return -1;
+    }
+    ts.tv_sec = tv.tv_sec;
+    ts.tv_nsec = tv.tv_usec * 1000;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        LOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+#else
+    if (settimeofday(&tv, NULL) != 0) {
+        LOGW("Unable to set clock to %d.%d: %s\n",
+            (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
+        ret = -1;
+    }
+#endif
+
+    return ret;
+#endif // WIN32
+}
+
+/*
+ * native public static long uptimeMillis();
+ */
+int64_t uptimeMillis()
+{
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+}
+
+/*
+ * native public static long elapsedRealtime();
+ */
+int64_t elapsedRealtime()
+{
+#if HAVE_ANDROID_OS
+    static int s_fd = -1;
+
+    if (s_fd == -1) {
+        int fd = open("/dev/alarm", O_RDONLY);
+        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
+            close(fd);
+        }
+    }
+
+    struct timespec ts;
+    int result = ioctl(s_fd,
+            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
+
+    if (result == 0) {
+        int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    } else {
+        // XXX: there was an error, probably because the driver didn't
+        // exist ... this should return
+        // a real error, like an exception!
+        int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    }
+#else
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+#endif
+}
+
+}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
new file mode 100644
index 0000000..cebee99
--- /dev/null
+++ b/libs/utils/TextOutput.cpp
@@ -0,0 +1,146 @@
+/*
+ * 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 <utils/TextOutput.h>
+
+#include <utils/Debug.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+TextOutput& operator<<(TextOutput& to, bool val)
+{
+    if (val) to.print("true", 4);
+    else to.print("false", 5);
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, int val)
+{
+    char buf[16];
+    sprintf(buf, "%d", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long val)
+{
+    char buf[16];
+    sprintf(buf, "%ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned int val)
+{
+    char buf[16];
+    sprintf(buf, "%u", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long val)
+{
+    char buf[16];
+    sprintf(buf, "%lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static TextOutput& print_float(TextOutput& to, double value)
+{
+    char buf[64];
+    sprintf(buf, "%g", value);
+    if( !strchr(buf, '.') && !strchr(buf, 'e') &&
+        !strchr(buf, 'E') ) {
+        strncat(buf, ".0", sizeof(buf)-1);
+    }
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, float val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, double val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, const void* val)
+{
+    char buf[16];
+    sprintf(buf, "%p", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static void textOutputPrinter(void* cookie, const char* txt)
+{
+    ((TextOutput*)cookie)->print(txt, strlen(txt));
+}
+
+TextOutput& operator<<(TextOutput& to, const TypeCode& val)
+{
+    printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
+    return to;
+}
+
+HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
+    : mBuffer(buf)
+    , mSize(size)
+    , mBytesPerLine(bytesPerLine)
+    , mSingleLineCutoff(16)
+    , mAlignment(4)
+    , mCArrayStyle(false)
+{
+    if (bytesPerLine >= 16) mAlignment = 4;
+    else if (bytesPerLine >= 8) mAlignment = 2;
+    else mAlignment = 1;
+}
+
+TextOutput& operator<<(TextOutput& to, const HexDump& val)
+{
+    printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
+        val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
+        textOutputPrinter, (void*)&to);
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
new file mode 100644
index 0000000..74271ba
--- /dev/null
+++ b/libs/utils/Threads.cpp
@@ -0,0 +1,1126 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "libutils.threads"
+
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+# include <sched.h>
+# include <sys/resource.h>
+#elif defined(HAVE_WIN32_THREADS)
+# include <windows.h>
+# include <stdint.h>
+# include <process.h>
+# define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
+#endif
+
+#if defined(HAVE_FUTEX)
+#include <private/utils/futex_synchro.h>
+#endif
+
+#if defined(HAVE_PRCTL)
+#include <sys/prctl.h>
+#endif
+
+/*
+ * ===========================================================================
+ *      Thread wrappers
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+#if defined(HAVE_PTHREADS)
+#if 0
+#pragma mark -
+#pragma mark PTHREAD
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Create and run a new thead.
+ *
+ * We create it "detached", so it cleans up after itself.
+ */
+
+typedef void* (*android_pthread_entry)(void*);
+
+struct thread_data_t {
+    thread_func_t   entryFunction;
+    void*           userData;
+    int             priority;
+    char *          threadName;
+
+    // we use this trampoline when we need to set the priority with
+    // nice/setpriority.
+    static int trampoline(const thread_data_t* t) {
+        thread_func_t f = t->entryFunction;
+        void* u = t->userData;
+        int prio = t->priority;
+        char * name = t->threadName;
+        delete t;
+        setpriority(PRIO_PROCESS, 0, prio);
+        if (name) {
+#if defined(HAVE_PRCTL)
+            // Mac OS doesn't have this, and we build libutil for the host too
+            int hasAt = 0;
+            int hasDot = 0;
+            char *s = name;
+            while (*s) {
+                if (*s == '.') hasDot = 1;
+                else if (*s == '@') hasAt = 1;
+                s++;
+            }
+            int len = s - name;
+            if (len < 15 || hasAt || !hasDot) {
+                s = name;
+            } else {
+                s = name + len - 15;
+            }
+            prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#endif
+            free(name);
+        }
+        return f(u);
+    }
+};
+
+int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    pthread_attr_t attr; 
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
+    if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
+        // We could avoid the trampoline if there was a way to get to the
+        // android_thread_id_t (pid) from pthread_t
+        thread_data_t* t = new thread_data_t;
+        t->priority = threadPriority;
+        t->threadName = threadName ? strdup(threadName) : NULL;
+        t->entryFunction = entryFunction;
+        t->userData = userData;
+        entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
+        userData = t;            
+    }
+#endif
+
+    if (threadStackSize) {
+        pthread_attr_setstacksize(&attr, threadStackSize);
+    }
+    
+    errno = 0;
+    pthread_t thread;
+    int result = pthread_create(&thread, &attr,
+                    (android_pthread_entry)entryFunction, userData);
+    if (result != 0) {
+        LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
+             "(android threadPriority=%d)",
+            entryFunction, result, errno, threadPriority);
+        return 0;
+    }
+
+    if (threadId != NULL) {
+        *threadId = (android_thread_id_t)thread; // XXX: this is not portable
+    }
+    return 1;
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)pthread_self();
+}
+
+// ----------------------------------------------------------------------------
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#pragma mark WIN32_THREADS
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Trampoline to make us __stdcall-compliant.
+ *
+ * We're expected to delete "vDetails" when we're done.
+ */
+struct threadDetails {
+    int (*func)(void*);
+    void* arg;
+};
+static __stdcall unsigned int threadIntermediary(void* vDetails)
+{
+    struct threadDetails* pDetails = (struct threadDetails*) vDetails;
+    int result;
+
+    result = (*(pDetails->func))(pDetails->arg);
+
+    delete pDetails;
+
+    LOG(LOG_VERBOSE, "thread", "thread exiting\n");
+    return (unsigned int) result;
+}
+
+/*
+ * Create and run a new thread.
+ */
+static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
+{
+    HANDLE hThread;
+    struct threadDetails* pDetails = new threadDetails; // must be on heap
+    unsigned int thrdaddr;
+
+    pDetails->func = fn;
+    pDetails->arg = arg;
+
+#if defined(HAVE__BEGINTHREADEX)
+    hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
+                    &thrdaddr);
+    if (hThread == 0)
+#elif defined(HAVE_CREATETHREAD)
+    hThread = CreateThread(NULL, 0,
+                    (LPTHREAD_START_ROUTINE) threadIntermediary,
+                    (void*) pDetails, 0, (DWORD*) &thrdaddr);
+    if (hThread == NULL)
+#endif
+    {
+        LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
+        return false;
+    }
+
+#if defined(HAVE_CREATETHREAD)
+    /* close the management handle */
+    CloseHandle(hThread);
+#endif
+
+    if (id != NULL) {
+      	*id = (android_thread_id_t)thrdaddr;
+    }
+
+    return true;
+}
+
+int androidCreateRawThreadEtc(android_thread_func_t fn,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    return doCreateThread(  fn, userData, threadId);
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)GetCurrentThreadId();
+}
+
+// ----------------------------------------------------------------------------
+#else
+#error "Threads not supported"
+#endif
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Common Thread functions
+#endif
+
+int androidCreateThread(android_thread_func_t fn, void* arg)
+{
+    return createThreadEtc(fn, arg);
+}
+
+int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
+{
+    return createThreadEtc(fn, arg, "android:unnamed_thread",
+                           PRIORITY_DEFAULT, 0, id);
+}
+
+static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
+
+int androidCreateThreadEtc(android_thread_func_t entryFunction,
+                            void *userData,
+                            const char* threadName,
+                            int32_t threadPriority,
+                            size_t threadStackSize,
+                            android_thread_id_t *threadId)
+{
+    return gCreateThreadFn(entryFunction, userData, threadName,
+        threadPriority, threadStackSize, threadId);
+}
+
+void androidSetCreateThreadFunc(android_create_thread_fn func)
+{
+    gCreateThreadFn = func;
+}
+
+namespace android {
+
+/*
+ * ===========================================================================
+ *      Mutex class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Mutex
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+/*
+ * Simple pthread wrapper.
+ */
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    _init();
+}
+
+void Mutex::_init()
+{
+    pthread_mutex_t* pMutex = new pthread_mutex_t;
+    pthread_mutex_init(pMutex, NULL);
+    mState = pMutex;
+}
+
+Mutex::~Mutex()
+{
+    delete (pthread_mutex_t*) mState;
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=pthread_mutex_lock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    pthread_mutex_unlock((pthread_mutex_t*) mState);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=pthread_mutex_trylock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_mutex_t*) (&mState))
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    _init();
+}
+
+void
+Mutex::_init()
+{
+    futex_mutex_init(STATE);
+}
+
+Mutex::~Mutex()
+{
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=futex_mutex_lock(STATE, FUTEX_WAIT_INFINITE)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    futex_mutex_unlock(STATE);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=futex_mutex_trylock(STATE)) == EINTR) ;
+    return -res;
+}
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+Mutex::Mutex()
+{
+    HANDLE hMutex;
+
+    assert(sizeof(hMutex) == sizeof(mState));
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    HANDLE hMutex;
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::~Mutex()
+{
+    CloseHandle((HANDLE) mState);
+}
+
+status_t Mutex::lock()
+{
+    DWORD dwWaitResult;
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
+    return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
+}
+
+void Mutex::unlock()
+{
+    if (!ReleaseMutex((HANDLE) mState))
+        LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
+}
+
+status_t Mutex::tryLock()
+{
+    DWORD dwWaitResult;
+
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
+    if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
+        LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
+    return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
+}
+
+#else
+#error "Somebody forgot to implement threads for this platform."
+#endif
+
+
+/*
+ * ===========================================================================
+ *      Condition class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Condition
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    pthread_cond_t* pCond = new pthread_cond_t;
+
+    pthread_cond_init(pCond, NULL);
+    mState = pCond;
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+    pthread_cond_destroy((pthread_cond_t*) mState);
+    delete (pthread_cond_t*) mState;
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int cc;
+    while ((cc = pthread_cond_wait((pthread_cond_t*)mState,
+                (pthread_mutex_t*) mutex.mState)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    assert(mutex.mState != NULL);
+
+    struct timespec ts;
+    ts.tv_sec = abstime/1000000000;
+    ts.tv_nsec = abstime-(ts.tv_sec*1000000000);
+    
+    int cc;
+    while ((cc = pthread_cond_timedwait((pthread_cond_t*)mState,
+            (pthread_mutex_t*) mutex.mState, &ts)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    pthread_cond_signal((pthread_cond_t*) mState);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    pthread_cond_broadcast((pthread_cond_t*) mState);
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_cond_t*) (&mState))
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    futex_cond_init(STATE);
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int res;
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), FUTEX_WAIT_INFINITE)) == -EINTR) ;
+
+    return -res;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    nsecs_t reltime = abstime - systemTime();
+    if (reltime <= 0) return true;
+    return waitRelative(mutex, reltime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    assert(mutex.mState != NULL);
+    int res;
+    unsigned msec = ns2ms(reltime);
+    if(msec == 0)
+        return true;
+    // This code will not time out at the correct time if interrupted by signals
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), msec)) == -EINTR) ;
+    return res;
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    futex_cond_signal(STATE);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    futex_cond_broadcast(STATE);
+}
+
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+/*
+ * Windows doesn't have a condition variable solution.  It's possible
+ * to create one, but it's easy to get it wrong.  For a discussion, and
+ * the origin of this implementation, see:
+ *
+ *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ *
+ * The implementation shown on the page does NOT follow POSIX semantics.
+ * As an optimization they require acquiring the external mutex before
+ * calling signal() and broadcast(), whereas POSIX only requires grabbing
+ * it before calling wait().  The implementation here has been un-optimized
+ * to have the correct behavior.
+ */
+typedef struct WinCondition {
+    // Number of waiting threads.
+    int                 waitersCount;
+
+    // Serialize access to waitersCount.
+    CRITICAL_SECTION    waitersCountLock;
+
+    // Semaphore used to queue up threads waiting for the condition to
+    // become signaled.
+    HANDLE              sema;
+
+    // An auto-reset event used by the broadcast/signal thread to wait
+    // for all the waiting thread(s) to wake up and be released from
+    // the semaphore.
+    HANDLE              waitersDone;
+
+    // This mutex wouldn't be necessary if we required that the caller
+    // lock the external mutex before calling signal() and broadcast().
+    // I'm trying to mimic pthread semantics though.
+    HANDLE              internalMutex;
+
+    // Keeps track of whether we were broadcasting or signaling.  This
+    // allows us to optimize the code if we're just signaling.
+    bool                wasBroadcast;
+
+    status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
+    {
+        // Increment the wait count, avoiding race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+        condState->waitersCount++;
+        //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
+        //    condState->waitersCount, getThreadId());
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        DWORD timeout = INFINITE;
+        if (abstime) {
+            nsecs_t reltime = *abstime - systemTime();
+            if (reltime < 0)
+                reltime = 0;
+            timeout = reltime/1000000;
+        }
+        
+        // Atomically release the external mutex and wait on the semaphore.
+        DWORD res =
+            SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
+    
+        //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
+    
+        // Reacquire lock to avoid race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+    
+        // No longer waiting.
+        condState->waitersCount--;
+    
+        // Check to see if we're the last waiter after a broadcast.
+        bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
+    
+        //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
+        //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
+    
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        // If we're the last waiter thread during this particular broadcast
+        // then signal broadcast() that we're all awake.  It'll drop the
+        // internal mutex.
+        if (lastWaiter) {
+            // Atomically signal the "waitersDone" event and wait until we
+            // can acquire the internal mutex.  We want to do this in one step
+            // because it ensures that everybody is in the mutex FIFO before
+            // any thread has a chance to run.  Without it, another thread
+            // could wake up, do work, and hop back in ahead of us.
+            SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
+                INFINITE, FALSE);
+        } else {
+            // Grab the internal mutex.
+            WaitForSingleObject(condState->internalMutex, INFINITE);
+        }
+    
+        // Release the internal and grab the external.
+        ReleaseMutex(condState->internalMutex);
+        WaitForSingleObject(hMutex, INFINITE);
+    
+        return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
+    }
+} WinCondition;
+
+/*
+ * Constructor.  Set up the WinCondition stuff.
+ */
+Condition::Condition()
+{
+    WinCondition* condState = new WinCondition;
+
+    condState->waitersCount = 0;
+    condState->wasBroadcast = false;
+    // semaphore: no security, initial value of 0
+    condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
+    InitializeCriticalSection(&condState->waitersCountLock);
+    // auto-reset event, not signaled initially
+    condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+    // used so we don't have to lock external mutex on signal/broadcast
+    condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
+
+    mState = condState;
+}
+
+/*
+ * Destructor.  Free Windows resources as well as our allocated storage.
+ */
+Condition::~Condition()
+{
+    WinCondition* condState = (WinCondition*) mState;
+    if (condState != NULL) {
+        CloseHandle(condState->sema);
+        CloseHandle(condState->waitersDone);
+        delete condState;
+    }
+}
+
+
+status_t Condition::wait(Mutex& mutex)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+    
+    return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+
+    return ((WinCondition*)mState)->wait(condState, hMutex, &abstime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This ensures that we don't clash with
+    // broadcast().
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = (condState->waitersCount > 0);
+    LeaveCriticalSection(&condState->waitersCountLock);
+
+    // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
+    // down a notch.
+    if (haveWaiters)
+        ReleaseSemaphore(condState->sema, 1, 0);
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ *
+ * First we have to wake up all threads waiting on the semaphore, then
+ * we wait until all of the threads have actually been woken before
+ * releasing the internal mutex.  This ensures that all threads are woken.
+ */
+void Condition::broadcast()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This keeps the guys we're waking up
+    // from getting too far.
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = false;
+
+    if (condState->waitersCount > 0) {
+        haveWaiters = true;
+        condState->wasBroadcast = true;
+    }
+
+    if (haveWaiters) {
+        // Wake up all the waiters.
+        ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
+
+        LeaveCriticalSection(&condState->waitersCountLock);
+
+        // Wait for all awakened threads to acquire the counting semaphore.
+        // The last guy who was waiting sets this.
+        WaitForSingleObject(condState->waitersDone, INFINITE);
+
+        // Reset wasBroadcast.  (No crit section needed because nobody
+        // else can wake up to poke at it.)
+        condState->wasBroadcast = 0;
+    } else {
+        // nothing to do
+        LeaveCriticalSection(&condState->waitersCountLock);
+    }
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+#else
+#error "condition variables not supported on this platform"
+#endif
+
+
+/*
+ * ===========================================================================
+ *      ReadWriteLock class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark ReadWriteLock
+#endif
+
+/*
+ * Add a reader.  Readers are nice.  They share.
+ */
+void ReadWriteLock::lockForRead()
+{
+    mLock.lock();
+    while (mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForRead: waiting\n");
+        mReadWaiter.wait(mLock);
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a reader.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForRead()
+{
+    mLock.lock();
+    if (mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a reader.
+ */
+void ReadWriteLock::unlockForRead()
+{
+    mLock.lock();
+    if (mNumReaders == 0) {
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForRead requested, but not locked\n");
+        return;
+    }
+    assert(mNumReaders > 0);
+    assert(mNumWriters == 0);
+    mNumReaders--;
+    if (mNumReaders == 0) {           // last reader?
+#if defined(PRINT_RENDER_TIMES)
+        mDebugTimer.stop();
+        printf(" rdlk held %.3f msec\n",
+            (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+        //printf("+++ signaling writers (if any)\n");
+        mWriteWaiter.signal();      // wake one writer (if any)
+    }
+    mLock.unlock();
+}
+
+/*
+ * Add a writer.  This requires exclusive access to the object.
+ */
+void ReadWriteLock::lockForWrite()
+{
+    mLock.lock();
+    while (mNumReaders > 0 || mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForWrite: waiting\n");
+        mWriteWaiter.wait(mLock);
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a writer.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForWrite()
+{
+    mLock.lock();
+    if (mNumReaders > 0 || mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a writer.
+ */
+void ReadWriteLock::unlockForWrite()
+{
+    mLock.lock();
+    if (mNumWriters == 0) {
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForWrite requested, but not locked\n");
+        return;
+    }
+    assert(mNumWriters == 1);
+    mNumWriters--;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.stop();
+    //printf(" wrlk held %.3f msec\n",
+    //    (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+    // mWriteWaiter.signal();       // should other writers get first dibs?
+    //printf("+++ signaling readers (if any)\n");
+    mReadWaiter.broadcast();        // wake all readers (if any)
+    mLock.unlock();
+}
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Thread::Thread
+#endif
+
+/*
+ * This is our thread object!
+ */
+
+Thread::Thread(bool canCallJava)
+    :   mCanCallJava(canCallJava),
+        mThread(thread_id_t(-1)),
+        mLock("Thread::mLock"),
+        mStatus(NO_ERROR),
+        mExitPending(false), mRunning(false)
+{
+}
+
+Thread::~Thread()
+{
+}
+
+status_t Thread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+status_t Thread::run(const char* name, int32_t priority, size_t stack)
+{
+    Mutex::Autolock _l(mLock);
+
+    if (mRunning) {
+        // thread already started
+        return INVALID_OPERATION;
+    }
+
+    // reset status and exitPending to their default value, so we can
+    // try again after an error happened (either below, or in readyToRun())
+    mStatus = NO_ERROR;
+    mExitPending = false;
+    mThread = thread_id_t(-1);
+    
+    // hold a strong reference on ourself
+    mHoldSelf = this;
+
+    bool res;
+    if (mCanCallJava) {
+        res = createThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    } else {
+        res = androidCreateRawThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    }
+    
+    if (res == false) {
+        mStatus = UNKNOWN_ERROR;   // something happened!
+        mRunning = false;
+        mThread = thread_id_t(-1);
+    }
+    
+    if (mStatus < 0) {
+        // something happened, don't leak
+        mHoldSelf.clear();
+    }
+    
+    return mStatus;
+}
+
+int Thread::_threadLoop(void* user)
+{
+    Thread* const self = static_cast<Thread*>(user);
+    sp<Thread> strong(self->mHoldSelf);
+    wp<Thread> weak(strong);
+    self->mHoldSelf.clear();
+
+    // we're about to run...
+    self->mStatus = self->readyToRun();
+    if (self->mStatus!=NO_ERROR || self->mExitPending) {
+        // pretend the thread never started...
+        self->mExitPending = false;
+        self->mRunning = false;
+        return 0;
+    }
+    
+    // thread is running now
+    self->mRunning = true;
+
+    do {
+        bool result = self->threadLoop();
+        if (result == false || self->mExitPending) {
+            self->mExitPending = true;
+            self->mLock.lock();
+            self->mRunning = false;
+            self->mThreadExitedCondition.signal();
+            self->mLock.unlock();
+            break;
+        }
+        
+        // Release our strong reference, to let a chance to the thread
+        // to die a peaceful death.
+        strong.clear();
+        // And immediately, reacquire a strong reference for the next loop
+        strong = weak.promote();
+    } while(strong != 0);
+    
+    return 0;
+}
+
+void Thread::requestExit()
+{
+    mExitPending = true;
+}
+
+status_t Thread::requestExitAndWait()
+{
+    if (mStatus == OK) {
+
+        if (mThread == getThreadId()) {
+            LOGW(
+            "Thread (this=%p): don't call waitForExit() from this "
+            "Thread object's thread. It's a guaranteed deadlock!",
+            this);
+            return WOULD_BLOCK;
+        }
+        
+        requestExit();
+
+        Mutex::Autolock _l(mLock);
+        while (mRunning == true) {
+            mThreadExitedCondition.wait(mLock);
+        }
+        mExitPending = false;
+    }
+    return mStatus;
+}
+
+bool Thread::exitPending() const
+{
+    return mExitPending;
+}
+
+
+
+};  // namespace android
diff --git a/libs/utils/TimerProbe.cpp b/libs/utils/TimerProbe.cpp
new file mode 100644
index 0000000..835480d
--- /dev/null
+++ b/libs/utils/TimerProbe.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#include <utils/TimerProbe.h>
+ 
+#if ENABLE_TIMER_PROBE
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "time"
+
+namespace android {
+
+Vector<TimerProbe::Bucket> TimerProbe::gBuckets;
+TimerProbe* TimerProbe::gExecuteChain;
+int TimerProbe::gIndent;
+timespec TimerProbe::gRealBase;
+
+TimerProbe::TimerProbe(const char tag[], int* slot) : mTag(tag)
+{
+    mNext = gExecuteChain;
+    gExecuteChain = this;
+    mIndent = gIndent;
+    gIndent += 1;
+    if (mIndent > 0) {
+        if (*slot == 0) {
+            int count = gBuckets.add();
+            *slot = count;
+            Bucket& bucket = gBuckets.editItemAt(count);
+            memset(&bucket, 0, sizeof(Bucket));
+            bucket.mTag = tag;
+            bucket.mSlotPtr = slot;
+            bucket.mIndent = mIndent;
+        }
+        mBucket = *slot;
+    }
+    clock_gettime(CLOCK_REALTIME, &mRealStart);
+    if (gRealBase.tv_sec == 0)
+        gRealBase = mRealStart;
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mPStart);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mTStart);
+}
+
+void TimerProbe::end()
+{
+    timespec realEnd, pEnd, tEnd;
+    clock_gettime(CLOCK_REALTIME, &realEnd);
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pEnd);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tEnd);
+    print(realEnd, pEnd, tEnd);
+    mTag = NULL;
+}
+
+TimerProbe::~TimerProbe()
+{
+    if (mTag != NULL)
+        end();
+    gExecuteChain = mNext;
+    gIndent--;
+}
+
+
+uint32_t TimerProbe::ElapsedTime(const timespec& start, const timespec& end)
+{
+    int sec = end.tv_sec - start.tv_sec;
+    int nsec = end.tv_nsec - start.tv_nsec;
+    if (nsec < 0) {
+        sec--;
+        nsec += 1000000000;
+    }
+    return sec * 1000000 + nsec / 1000;
+}
+
+void TimerProbe::print(const timespec& r, const timespec& p,
+        const timespec& t) const
+{
+    uint32_t es = ElapsedTime(gRealBase, mRealStart);
+    uint32_t er = ElapsedTime(mRealStart, r);
+    uint32_t ep = ElapsedTime(mPStart, p);
+    uint32_t et = ElapsedTime(mTStart, t);
+    if (mIndent > 0) {
+        Bucket& bucket = gBuckets.editItemAt(mBucket);
+        if (bucket.mStart == 0)
+            bucket.mStart = es;
+        bucket.mReal += er;
+        bucket.mProcess += ep;
+        bucket.mThread += et;
+        bucket.mCount++;
+        return;
+    }
+    int index = 0;
+    int buckets = gBuckets.size();
+    int count = 1;
+    const char* tag = mTag;
+    int indent = mIndent;
+    do {
+        LOGD("%-30.30s: (%3d) %-5.*s time=%-10.3f real=%7dus process=%7dus (%3d%%) thread=%7dus (%3d%%)\n", 
+            tag, count, indent > 5 ? 5 : indent, "+++++", es / 1000000.0,
+            er, ep, ep * 100 / er, et, et * 100 / er);
+        if (index >= buckets)
+            break;
+        Bucket& bucket = gBuckets.editItemAt(index);
+        count = bucket.mCount;
+        es = bucket.mStart;
+        er = bucket.mReal;
+        ep = bucket.mProcess;
+        et = bucket.mThread;
+        tag = bucket.mTag;
+        indent = bucket.mIndent;
+        *bucket.mSlotPtr = 0;
+    } while (++index); // always true
+    gBuckets.clear();
+}
+
+}; // namespace android
+
+#endif
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
new file mode 100644
index 0000000..2abc811
--- /dev/null
+++ b/libs/utils/Timers.cpp
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+//
+// Timer functions.
+//
+#include <utils/Timers.h>
+#include <utils/ported.h>     // may need usleep
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+nsecs_t systemTime(int clock)
+{
+#if defined(HAVE_POSIX_CLOCKS)
+    static const clockid_t clocks[] = {
+            CLOCK_REALTIME,
+            CLOCK_MONOTONIC,
+            CLOCK_PROCESS_CPUTIME_ID,
+            CLOCK_THREAD_CPUTIME_ID
+    };
+    struct timespec t;
+    t.tv_sec = t.tv_nsec = 0;
+    clock_gettime(clocks[clock], &t);
+    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
+#else
+    // we don't support the clocks here.
+    struct timeval t;
+    t.tv_sec = t.tv_usec = 0;
+    gettimeofday(&t, NULL);
+    return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
+#endif
+}
+
+//#define MONITOR_USLEEP
+
+/*
+ * Sleep long enough that we'll wake up "interval" milliseconds after
+ * the previous snooze.
+ *
+ * The "nextTick" argument is updated on each call, and should be passed
+ * in every time.  Set its fields to zero on the first call.
+ *
+ * Returns the #of intervals we have overslept, which will be zero if we're
+ * on time.  [Currently just returns 0 or 1.]
+ */
+int sleepForInterval(long interval, struct timeval* pNextTick)
+{
+    struct timeval now;
+    long long timeBeforeNext;
+    long sleepTime = 0;
+    bool overSlept = false;
+    //int usleepBias = 0;
+
+#ifdef USLEEP_BIAS
+    /*
+     * Linux likes to add 9000ms or so.
+     * [not using this for now]
+     */
+    //usleepBias = USLEEP_BIAS;
+#endif
+
+    gettimeofday(&now, NULL);
+
+    if (pNextTick->tv_sec == 0) {
+        /* special-case for first time through */
+        *pNextTick = now;
+        sleepTime = interval;
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    } else {
+        /*
+         * Compute how much time there is before the next tick.  If this
+         * value is negative, we've run over.  If we've run over a little
+         * bit we can shorten the next frame to keep the pace steady, but
+         * if we've dramatically overshot we need to re-sync.
+         */
+        timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now);
+        //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n",
+        //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+        //    (long) timeBeforeNext);
+        if (timeBeforeNext < -interval) {
+            /* way over */
+            overSlept = true;
+            sleepTime = 0;
+            *pNextTick = now;
+        } else if (timeBeforeNext <= 0) {
+            /* slightly over, keep the pace steady */
+            overSlept = true;
+            sleepTime = 0;
+        } else if (timeBeforeNext <= interval) {
+            /* right on schedule */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) {
+            /* sleep call returned early; do a longer sleep this time */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval) {
+            /* we went back in time -- somebody updated system clock? */
+            /* (could also be a *seriously* broken usleep()) */
+            LOG(LOG_DEBUG, "",
+                " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext);
+            sleepTime = 0;
+            *pNextTick = now;
+        }
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    }
+    //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n",
+    //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+    //    sleepTime);
+
+    /*
+     * Sleep for the designated period of time.
+     *
+     * Linux tends to sleep for longer than requested, often by 17-18ms.
+     * MinGW tends to sleep for less than requested, by as much as 14ms,
+     * but occasionally oversleeps for 40+ms (looks like some external
+     * factors plus round-off on a 64Hz clock).  Cygwin is pretty steady.
+     *
+     * If you start the MinGW version, and then launch the Cygwin version,
+     * the MinGW clock becomes more erratic.  Not entirely sure why.
+     *
+     * (There's a lot of stuff here; it's really just a usleep() call with
+     * a bunch of instrumentation.)
+     */
+    if (sleepTime > 0) {
+#if defined(MONITOR_USLEEP)
+        struct timeval before, after;
+        long long actual;
+
+        gettimeofday(&before, NULL);
+        usleep((long) sleepTime);
+        gettimeofday(&after, NULL);
+
+        /* check usleep() accuracy; default Linux threads are pretty sloppy */
+        actual = android::DurationTimer::subtractTimevals(&after, &before);
+        if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ ||
+            (long) actual > sleepTime + 20000 /*(sleepTime/10)*/)
+        {
+            LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime,
+                (long) actual);
+        }
+#else
+#ifdef HAVE_WIN32_THREADS
+        Sleep( sleepTime/1000 );
+#else        
+        usleep((long) sleepTime);
+#endif        
+#endif
+    }
+
+    //printf("slept %d\n", sleepTime);
+
+    if (overSlept)
+        return 1;       // close enough
+    else
+        return 0;
+}
+
+
+/*
+ * ===========================================================================
+ *      DurationTimer
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// Start the timer.
+void DurationTimer::start(void)
+{
+    gettimeofday(&mStartWhen, NULL);
+}
+
+// Stop the timer.
+void DurationTimer::stop(void)
+{
+    gettimeofday(&mStopWhen, NULL);
+}
+
+// Get the duration in microseconds.
+long long DurationTimer::durationUsecs(void) const
+{
+    return (long) subtractTimevals(&mStopWhen, &mStartWhen);
+}
+
+// Subtract two timevals.  Returns the difference (ptv1-ptv2) in
+// microseconds.
+/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
+    const struct timeval* ptv2)
+{
+    long long stop  = ((long long) ptv1->tv_sec) * 1000000LL +
+                      ((long long) ptv1->tv_usec);
+    long long start = ((long long) ptv2->tv_sec) * 1000000LL +
+                      ((long long) ptv2->tv_usec);
+    return stop - start;
+}
+
+// Add the specified amount of time to the timeval.
+/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
+{
+    if (usec < 0) {
+        LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
+        return;
+    }
+
+    // normalize tv_usec if necessary
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_sec += ptv->tv_usec / 1000000;
+        ptv->tv_usec %= 1000000;
+    }
+
+    ptv->tv_usec += usec % 1000000;
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_usec -= 1000000;
+        ptv->tv_sec++;
+    }
+    ptv->tv_sec += usec / 1000000;
+}
+
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
new file mode 100644
index 0000000..33f535f
--- /dev/null
+++ b/libs/utils/Unicode.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+#include "utils/AndroidUnicode.h"
+#include "characterData.h"
+
+#define LOG_TAG "Unicode"
+#include "utils/Log.h"
+
+// ICU headers for using macros
+#include <unicode/utf16.h>
+
+#define MIN_RADIX 2
+#define MAX_RADIX 36
+
+#define TYPE_SHIFT 0
+#define TYPE_MASK ((1<<5)-1)
+
+#define DIRECTION_SHIFT (TYPE_SHIFT+5)
+#define DIRECTION_MASK ((1<<5)-1)
+
+#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
+#define MIRRORED_MASK ((1<<1)-1)
+
+#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
+#define TOUPPER_MASK ((1<<6)-1)
+
+#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
+#define TOLOWER_MASK ((1<<6)-1)
+
+#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
+#define TOTITLE_MASK ((1<<2)-1)
+
+#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
+#define MIRROR_MASK ((1<<5)-1)
+
+#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
+#define NUMERIC_MASK ((1<<7)-1)
+
+#define DECOMPOSITION_SHIFT (11)
+#define DECOMPOSITION_MASK ((1<<5)-1)
+
+/*
+ * Returns the value stored in the CharacterData tables that contains
+ * an index into the packed data table and the decomposition type.
+ */
+static uint16_t findCharacterValue(UChar32 c)
+{
+    LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
+    if (c < 256)
+        return CharacterData::LATIN1_DATA[c];
+
+    // Rotate the bits because the tables are separated into even and odd codepoints
+    c = (c >> 1) | ((c & 1) << 20);
+
+    CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
+    const uint32_t* array = search.array;
+ 
+    // This trick is so that that compare in the while loop does not
+    // need to shift the array entry down by 16
+    c <<= 16;
+    c |= 0xFFFF;
+
+    int high = (int)search.length - 1;
+    int low = 0;
+
+    if (high < 0)
+        return 0;
+    
+    while (low < high - 1)
+    {
+        int probe = (high + low) >> 1;
+
+        // The entries contain the codepoint in the high 16 bits and the index
+        // into PACKED_DATA in the low 16.
+        if (array[probe] > (unsigned)c)
+            high = probe;
+        else
+            low = probe;
+    }
+
+    LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
+    return array[low] & 0xFFFF;
+}
+
+uint32_t android::Unicode::getPackedData(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
+}
+
+android::Unicode::CharType android::Unicode::getType(UChar32 c)
+{
+    if (c < 0 || c >= 0x10FFFF)
+        return CHARTYPE_UNASSIGNED;
+    return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
+}
+
+android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
+}
+
+int android::Unicode::getDigitValue(UChar32 c, int radix)
+{
+    if (radix < MIN_RADIX || radix > MAX_RADIX)
+        return -1;
+
+    int tempValue = radix;
+    
+    if (c >= '0' && c <= '9')
+        tempValue = c - '0';
+    else if (c >= 'a' && c <= 'z')
+        tempValue = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'Z')
+        tempValue = c - 'A' + 10;
+    
+    return tempValue < radix ? tempValue : -1;
+}
+
+int android::Unicode::getNumericValue(UChar32 c)
+{
+    if (isMirrored(c))
+        return -1;
+    
+    return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
+}
+
+UChar32 android::Unicode::toLower(UChar32 c)
+{
+    return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
+}
+
+UChar32 android::Unicode::toUpper(UChar32 c)
+{
+    return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
+}
+
+android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
+{
+    uint32_t data = getPackedData(c);
+
+    if (0 == data)
+        return DIRECTIONALITY_UNDEFINED;
+
+    Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
+
+    if (DIRECTION_MASK == d)
+        return DIRECTIONALITY_UNDEFINED;
+    
+    return d;
+}
+
+bool android::Unicode::isMirrored(UChar32 c)
+{
+    return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
+}
+
+UChar32 android::Unicode::toMirror(UChar32 c)
+{
+    if (!isMirrored(c))
+        return c;
+
+    return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
+}
+
+UChar32 android::Unicode::toTitle(UChar32 c)
+{
+    int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
+
+    if (TOTITLE_MASK == diff)
+        return toUpper(c);
+    
+    return c + diff;
+}
+
+
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
new file mode 100644
index 0000000..2c2d667
--- /dev/null
+++ b/libs/utils/VectorImpl.cpp
@@ -0,0 +1,611 @@
+/*
+ * 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 "Vector"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+#include <utils/VectorImpl.h>
+
+/*****************************************************************************/
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+const size_t kMinVectorCapacity = 4;
+
+static inline size_t max(size_t a, size_t b) {
+    return a>b ? a : b;
+}
+
+// ----------------------------------------------------------------------------
+
+VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
+    : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)
+{
+}
+
+VectorImpl::VectorImpl(const VectorImpl& rhs)
+    :   mStorage(rhs.mStorage), mCount(rhs.mCount),
+        mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
+{
+    if (mStorage) {
+        SharedBuffer::sharedBuffer(mStorage)->acquire();
+    }
+}
+
+VectorImpl::~VectorImpl()
+{
+    LOG_ASSERT(!mCount,
+        "[%p] "
+        "subclasses of VectorImpl must call finish_vector()"
+        " in their destructor. Leaking %d bytes.",
+        this, (int)(mCount*mItemSize));
+    // We can't call _do_destroy() here because the vtable is already gone. 
+}
+
+VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
+{
+    LOG_ASSERT(mItemSize == rhs.mItemSize,
+        "Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
+    if (this != &rhs) {
+        release_storage();
+        if (rhs.mCount) {
+            mStorage = rhs.mStorage;
+            mCount = rhs.mCount;
+            SharedBuffer::sharedBuffer(mStorage)->acquire();
+        } else {
+            mStorage = 0;
+            mCount = 0;
+        }
+    }
+    return *this;
+}
+
+void* VectorImpl::editArrayImpl()
+{
+    if (mStorage) {
+        SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit();
+        if (sb == 0) {
+            sb = SharedBuffer::alloc(capacity() * mItemSize);
+            if (sb) {
+                _do_copy(sb->data(), mStorage, mCount);
+                release_storage();
+                mStorage = sb->data();
+            }
+        }
+    }
+    return mStorage;
+}
+
+size_t VectorImpl::capacity() const
+{
+    if (mStorage) {
+        return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize;
+    }
+    return 0;
+}
+
+ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, vector.size());
+    if (where) {
+        _do_copy(where, vector.arrayImpl(), vector.size());
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+ssize_t VectorImpl::appendVector(const VectorImpl& vector)
+{
+    return insertVectorAt(vector, size());
+}
+
+ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
+{
+    return insertAt(0, index, numItems);
+}
+
+ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, numItems);
+    if (where) {
+        if (item) {
+            _do_splat(where, item, numItems);
+        } else {
+            _do_construct(where, numItems);
+        }
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+static int sortProxy(const void* lhs, const void* rhs, void* func)
+{
+    return (*(VectorImpl::compar_t)func)(lhs, rhs);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_t cmp)
+{
+    return sort(sortProxy, (void*)cmp);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
+{
+    // the sort must be stable. we're using insertion sort which
+    // is well suited for small and already sorted arrays
+    // for big arrays, it could be better to use mergesort
+    const ssize_t count = size();
+    if (count > 1) {
+        void* array = const_cast<void*>(arrayImpl());
+        void* temp = 0;
+        ssize_t i = 1;
+        while (i < count) {
+            void* item = reinterpret_cast<char*>(array) + mItemSize*(i);
+            void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+            if (cmp(curr, item, state) > 0) {
+
+                if (!temp) {
+                    // we're going to have to modify the array...
+                    array = editArrayImpl();
+                    if (!array) return NO_MEMORY;
+                    temp = malloc(mItemSize);
+                    if (!temp) return NO_MEMORY;
+                    _do_construct(temp, 1);
+                    item = reinterpret_cast<char*>(array) + mItemSize*(i);
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+                }
+
+                _do_copy(temp, item, 1);
+
+                ssize_t j = i-1;
+                void* next = reinterpret_cast<char*>(array) + mItemSize*(i);                    
+                do {
+                    _do_copy(next, curr, 1);
+                    next = curr;
+                    --j;
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(j);                    
+                } while (j>=0 && (cmp(curr, temp, state) > 0));
+
+                _do_copy(next, temp, 1);
+            }
+            i++;
+        }
+        
+        if (temp) {
+            _do_destroy(temp, 1);
+            free(temp);
+        }
+    }
+    return NO_ERROR;
+}
+
+void VectorImpl::pop()
+{
+    if (size())
+        removeItemsAt(size()-1, 1);
+}
+
+void VectorImpl::push()
+{
+    push(0);
+}
+
+void VectorImpl::push(const void* item)
+{
+    insertAt(item, size());
+}
+
+ssize_t VectorImpl::add()
+{
+    return add(0);
+}
+
+ssize_t VectorImpl::add(const void* item)
+{
+    return insertAt(item, size());
+}
+
+ssize_t VectorImpl::replaceAt(size_t index)
+{
+    return replaceAt(0, index);
+}
+
+ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
+{
+    LOG_ASSERT(index<size(),
+        "[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
+
+    void* item = editItemLocation(index);
+    if (item == 0)
+        return NO_MEMORY;
+    _do_destroy(item, 1);
+    if (prototype == 0) {
+        _do_construct(item, 1);
+    } else {
+        _do_copy(item, prototype, 1);
+    }
+    return ssize_t(index);
+}
+
+ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
+{
+    LOG_ASSERT((index+count)<=size(),
+        "[%p] remove: index=%d, count=%d, size=%d",
+               this, (int)index, (int)count, (int)size());
+
+    if ((index+count) > size())
+        return BAD_VALUE;
+   _shrink(index, count);
+   return index;
+}
+
+void VectorImpl::finish_vector()
+{
+    release_storage();
+    mStorage = 0;
+    mCount = 0;
+}
+
+void VectorImpl::clear()
+{
+    _shrink(0, mCount);
+}
+
+void* VectorImpl::editItemLocation(size_t index)
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] itemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+            
+    void* buffer = editArrayImpl();
+    if (buffer)
+        return reinterpret_cast<char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+const void* VectorImpl::itemLocation(size_t index) const
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] editItemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+
+    const  void* buffer = arrayImpl();
+    if (buffer)
+        return reinterpret_cast<const char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+ssize_t VectorImpl::setCapacity(size_t new_capacity)
+{
+    size_t current_capacity = capacity();
+    ssize_t amount = new_capacity - size();
+    if (amount <= 0) {
+        // we can't reduce the capacity
+        return current_capacity;
+    } 
+    SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+    if (sb) {
+        void* array = sb->data();
+        _do_copy(array, mStorage, size());
+        release_storage();
+        mStorage = const_cast<void*>(array);
+    } else {
+        return NO_MEMORY;
+    }
+    return new_capacity;
+}
+
+void VectorImpl::release_storage()
+{
+    if (mStorage) {
+        const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage);
+        if (sb->release(SharedBuffer::eKeepStorage) == 1) {
+            _do_destroy(mStorage, mCount);
+            SharedBuffer::dealloc(sb);
+        } 
+    }
+}
+
+void* VectorImpl::_grow(size_t where, size_t amount)
+{
+//    LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where > mCount)
+        where = mCount;
+      
+    const size_t new_size = mCount + amount;
+    if (capacity() < new_size) {
+        const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
+//        LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((mStorage) &&
+            (mCount==where) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount>where) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+                    _do_copy(dest, from, mCount-where);
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        ssize_t s = mCount-where;
+        if (s>0) {
+            void* array = editArrayImpl();    
+            void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
+            _do_move_forward(to, from, s);
+        }
+    }
+    mCount += amount;
+    void* free_space = const_cast<void*>(itemLocation(where));
+    return free_space;
+}
+
+void VectorImpl::_shrink(size_t where, size_t amount)
+{
+    if (!mStorage)
+        return;
+
+//    LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where >= mCount)
+        where = mCount - amount;
+
+    const size_t new_size = mCount - amount;
+    if (new_size*3 < capacity()) {
+        const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
+//        LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((where == mCount-amount) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount > where+amount) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+                    _do_copy(dest, from, mCount-(where+amount));
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        void* array = editArrayImpl();    
+        void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+        _do_destroy(to, amount);
+        ssize_t s = mCount-(where+amount);
+        if (s>0) {
+            const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            _do_move_backward(to, from, s);
+        }
+    }
+
+    // adjust the number of items...
+    mCount -= amount;
+}
+
+size_t VectorImpl::itemSize() const {
+    return mItemSize;
+}
+
+void VectorImpl::_do_construct(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_CTOR)) {
+        do_construct(storage, num);
+    }
+}
+
+void VectorImpl::_do_destroy(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_DTOR)) {
+        do_destroy(storage, num);
+    }
+}
+
+void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_COPY)) {
+        do_copy(dest, from, num);
+    } else {
+        memcpy(dest, from, num*itemSize());
+    }
+}
+
+void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
+    do_splat(dest, item, num);
+}
+
+void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
+    do_move_forward(dest, from, num);
+}
+
+void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
+    do_move_backward(dest, from, num);
+}
+
+void VectorImpl::reservedVectorImpl1() { }
+void VectorImpl::reservedVectorImpl2() { }
+void VectorImpl::reservedVectorImpl3() { }
+void VectorImpl::reservedVectorImpl4() { }
+void VectorImpl::reservedVectorImpl5() { }
+void VectorImpl::reservedVectorImpl6() { }
+void VectorImpl::reservedVectorImpl7() { }
+void VectorImpl::reservedVectorImpl8() { }
+
+/*****************************************************************************/
+
+SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
+    : VectorImpl(itemSize, flags)
+{
+}
+
+SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
+: VectorImpl(rhs)
+{
+}
+
+SortedVectorImpl::~SortedVectorImpl()
+{
+}
+
+SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)
+{
+    return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );
+}
+
+ssize_t SortedVectorImpl::indexOf(const void* item) const
+{
+    return _indexOrderOf(item);
+}
+
+size_t SortedVectorImpl::orderOf(const void* item) const
+{
+    size_t o;
+    _indexOrderOf(item, &o);
+    return o;
+}
+
+ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = size()-1;
+    ssize_t mid;
+    const void* a = arrayImpl();
+    const size_t s = itemSize();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
+        const int c = do_compare(curr, item);
+        if (c == 0) {
+            err = l = mid;
+            break;
+        } else if (c < 0) {
+            l = mid + 1;
+        } else {
+            h = mid - 1;
+        }
+    }
+    if (order) *order = l;
+    return err;
+}
+
+ssize_t SortedVectorImpl::add(const void* item)
+{
+    size_t order;
+    ssize_t index = _indexOrderOf(item, &order);
+    if (index < 0) {
+        index = VectorImpl::insertAt(item, order, 1);
+    } else {
+        index = VectorImpl::replaceAt(item, index);
+    }
+    return index;
+}
+
+ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
+{
+    // naive merge...
+    if (!vector.isEmpty()) {
+        const void* buffer = vector.arrayImpl();
+        const size_t is = itemSize();
+        size_t s = vector.size();
+        for (size_t i=0 ; i<s ; i++) {
+            ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );
+            if (err<0) {
+                return err;
+            }
+        }
+    }
+    return NO_ERROR;
+}
+
+ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
+{
+    // we've merging a sorted vector... nice!
+    ssize_t err = NO_ERROR;
+    if (!vector.isEmpty()) {
+        // first take care of the case where the vectors are sorted together
+        if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {
+            err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);
+        } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {
+            err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));
+        } else {
+            // this could be made a little better
+            err = merge(static_cast<const VectorImpl&>(vector));
+        }
+    }
+    return err;
+}
+
+ssize_t SortedVectorImpl::remove(const void* item)
+{
+    ssize_t i = indexOf(item);
+    if (i>=0) {
+        VectorImpl::removeItemsAt(i, 1);
+    }
+    return i;
+}
+
+void SortedVectorImpl::reservedSortedVectorImpl1() { };
+void SortedVectorImpl::reservedSortedVectorImpl2() { };
+void SortedVectorImpl::reservedSortedVectorImpl3() { };
+void SortedVectorImpl::reservedSortedVectorImpl4() { };
+void SortedVectorImpl::reservedSortedVectorImpl5() { };
+void SortedVectorImpl::reservedSortedVectorImpl6() { };
+void SortedVectorImpl::reservedSortedVectorImpl7() { };
+void SortedVectorImpl::reservedSortedVectorImpl8() { };
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/ZipEntry.cpp b/libs/utils/ZipEntry.cpp
new file mode 100644
index 0000000..fbc9e67
--- /dev/null
+++ b/libs/utils/ZipEntry.cpp
@@ -0,0 +1,696 @@
+/*
+ * 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 to entries in a Zip archive.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipEntry.h"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Initialize a new ZipEntry structure from a FILE* positioned at a
+ * CentralDirectoryEntry.
+ *
+ * On exit, the file pointer will be at the start of the next CDE or
+ * at the EOCD.
+ */
+status_t ZipEntry::initFromCDE(FILE* fp)
+{
+    status_t result;
+    long posn;
+    bool hasDD;
+
+    //LOGV("initFromCDE ---\n");
+
+    /* read the CDE */
+    result = mCDE.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mCDE.read failed\n");
+        return result;
+    }
+
+    //mCDE.dump();
+
+    /* using the info in the CDE, go load up the LFH */
+    posn = ftell(fp);
+    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+        LOGD("local header seek failed (%ld)\n",
+            mCDE.mLocalHeaderRelOffset);
+        return UNKNOWN_ERROR;
+    }
+
+    result = mLFH.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mLFH.read failed\n");
+        return result;
+    }
+
+    if (fseek(fp, posn, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    //mLFH.dump();
+
+    /*
+     * We *might* need to read the Data Descriptor at this point and
+     * integrate it into the LFH.  If this bit is set, the CRC-32,
+     * compressed size, and uncompressed size will be zero.  In practice
+     * these seem to be rare.
+     */
+    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
+    if (hasDD) {
+        // do something clever
+        //LOGD("+++ has data descriptor\n");
+    }
+
+    /*
+     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
+     * flag is set, because the LFH is incomplete.  (Not a problem, since we
+     * prefer the CDE values.)
+     */
+    if (!hasDD && !compareHeaders()) {
+        LOGW("WARNING: header mismatch\n");
+        // keep going?
+    }
+
+    /*
+     * If the mVersionToExtract is greater than 20, we may have an
+     * issue unpacking the record -- could be encrypted, compressed
+     * with something we don't support, or use Zip64 extensions.  We
+     * can defer worrying about that to when we're extracting data.
+     */
+
+    return NO_ERROR;
+}
+
+/*
+ * Initialize a new entry.  Pass in the file name and an optional comment.
+ *
+ * Initializes the CDE and the LFH.
+ */
+void ZipEntry::initNew(const char* fileName, const char* comment)
+{
+    assert(fileName != NULL && *fileName != '\0');  // name required
+
+    /* most fields are properly initialized by constructor */
+    mCDE.mVersionMadeBy = kDefaultMadeBy;
+    mCDE.mVersionToExtract = kDefaultVersion;
+    mCDE.mCompressionMethod = kCompressStored;
+    mCDE.mFileNameLength = strlen(fileName);
+    if (comment != NULL)
+        mCDE.mFileCommentLength = strlen(comment);
+    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        strcpy((char*) mCDE.mFileName, fileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        /* TODO: stop assuming null-terminated ASCII here? */
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        strcpy((char*) mCDE.mFileComment, comment);
+    }
+
+    copyCDEtoLFH();
+}
+
+/*
+ * Initialize a new entry, starting with the ZipEntry from a different
+ * archive.
+ *
+ * Initializes the CDE and the LFH.
+ */
+status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
+    const ZipEntry* pEntry)
+{
+    /*
+     * Copy everything in the CDE over, then fix up the hairy bits.
+     */
+    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        if (mCDE.mFileName == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        if (mCDE.mFileComment == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
+    }
+    if (mCDE.mExtraFieldLength > 0) {
+        /* we null-terminate this, though it may not be a string */
+        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
+        if (mCDE.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
+            mCDE.mExtraFieldLength+1);
+    }
+
+    /* construct the LFH from the CDE */
+    copyCDEtoLFH();
+
+    /*
+     * The LFH "extra" field is independent of the CDE "extra", so we
+     * handle it here.
+     */
+    assert(mLFH.mExtraField == NULL);
+    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
+    if (mLFH.mExtraFieldLength > 0) {
+        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
+        if (mLFH.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
+            mLFH.mExtraFieldLength+1);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
+ * potentially confuse something that put "extra" data in here earlier,
+ * but I can't find an actual problem.
+ */
+status_t ZipEntry::addPadding(int padding)
+{
+    if (padding <= 0)
+        return INVALID_OPERATION;
+
+    //LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
+    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);
+
+    if (mLFH.mExtraFieldLength > 0) {
+        /* extend existing field */
+        unsigned char* newExtra;
+
+        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
+        if (newExtra == NULL)
+            return NO_MEMORY;
+        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
+        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
+
+        delete[] mLFH.mExtraField;
+        mLFH.mExtraField = newExtra;
+        mLFH.mExtraFieldLength += padding;
+    } else {
+        /* create new field */
+        mLFH.mExtraField = new unsigned char[padding];
+        memset(mLFH.mExtraField, 0, padding);
+        mLFH.mExtraFieldLength = padding;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Set the fields in the LFH equal to the corresponding fields in the CDE.
+ *
+ * This does not touch the LFH "extra" field.
+ */
+void ZipEntry::copyCDEtoLFH(void)
+{
+    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
+    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
+    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
+    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
+    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
+    mLFH.mCRC32             = mCDE.mCRC32;
+    mLFH.mCompressedSize    = mCDE.mCompressedSize;
+    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
+    mLFH.mFileNameLength    = mCDE.mFileNameLength;
+    // the "extra field" is independent
+
+    delete[] mLFH.mFileName;
+    if (mLFH.mFileNameLength > 0) {
+        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
+        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
+    } else {
+        mLFH.mFileName = NULL;
+    }
+}
+
+/*
+ * Set some information about a file after we add it.
+ */
+void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+    int compressionMethod)
+{
+    mCDE.mCompressionMethod = compressionMethod;
+    mCDE.mCRC32 = crc32;
+    mCDE.mCompressedSize = compLen;
+    mCDE.mUncompressedSize = uncompLen;
+    mCDE.mCompressionMethod = compressionMethod;
+    if (compressionMethod == kCompressDeflated) {
+        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
+    }
+    copyCDEtoLFH();
+}
+
+/*
+ * See if the data in mCDE and mLFH match up.  This is mostly useful for
+ * debugging these classes, but it can be used to identify damaged
+ * archives.
+ *
+ * Returns "false" if they differ.
+ */
+bool ZipEntry::compareHeaders(void) const
+{
+    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
+        LOGV("cmp: VersionToExtract\n");
+        return false;
+    }
+    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
+        LOGV("cmp: GPBitFlag\n");
+        return false;
+    }
+    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
+        LOGV("cmp: CompressionMethod\n");
+        return false;
+    }
+    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
+        LOGV("cmp: LastModFileTime\n");
+        return false;
+    }
+    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
+        LOGV("cmp: LastModFileDate\n");
+        return false;
+    }
+    if (mCDE.mCRC32 != mLFH.mCRC32) {
+        LOGV("cmp: CRC32\n");
+        return false;
+    }
+    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
+        LOGV("cmp: CompressedSize\n");
+        return false;
+    }
+    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
+        LOGV("cmp: UncompressedSize\n");
+        return false;
+    }
+    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
+        LOGV("cmp: FileNameLength\n");
+        return false;
+    }
+#if 0       // this seems to be used for padding, not real data
+    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
+        LOGV("cmp: ExtraFieldLength\n");
+        return false;
+    }
+#endif
+    if (mCDE.mFileName != NULL) {
+        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
+            LOGV("cmp: FileName\n");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+/*
+ * Convert the DOS date/time stamp into a UNIX time stamp.
+ */
+time_t ZipEntry::getModWhen(void) const
+{
+    struct tm parts;
+
+    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
+    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
+    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
+    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
+    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
+    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
+    parts.tm_wday = parts.tm_yday = 0;
+    parts.tm_isdst = -1;        // DST info "not available"
+
+    return mktime(&parts);
+}
+
+/*
+ * Set the CDE/LFH timestamp from UNIX time.
+ */
+void ZipEntry::setModWhen(time_t when)
+{
+#ifdef HAVE_LOCALTIME_R
+    struct tm tmResult;
+#endif
+    time_t even;
+    unsigned short zdate, ztime;
+
+    struct tm* ptm;
+
+    /* round up to an even number of seconds */
+    even = (time_t)(((unsigned long)(when) + 1) & (~1));
+
+    /* expand */
+#ifdef HAVE_LOCALTIME_R
+    ptm = localtime_r(&even, &tmResult);
+#else
+    ptm = localtime(&even);
+#endif
+
+    int year;
+    year = ptm->tm_year;
+    if (year < 80)
+        year = 80;
+
+    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
+    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+
+    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
+    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::LocalFileHeader
+ * ===========================================================================
+ */
+
+/*
+ * Read a local file header.
+ *
+ * On entry, "fp" points to the signature at the start of the header.
+ * On exit, "fp" points to the start of data.
+ */
+status_t ZipEntry::LocalFileHeader::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kLFHLen];
+
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+
+    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
+
+    // TODO: validate sizes
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* grab extra field */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a local file header.
+ */
+status_t ZipEntry::LocalFileHeader::write(FILE* fp)
+{
+    unsigned char buf[kLFHLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
+    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
+
+    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Dump the contents of a LocalFileHeader object.
+ */
+void ZipEntry::LocalFileHeader::dump(void) const
+{
+    LOGD(" LocalFileHeader contents:\n");
+    LOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u\n",
+        mFileNameLength, mExtraFieldLength);
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::CentralDirEntry
+ * ===========================================================================
+ */
+
+/*
+ * Read the central dir entry that appears next in the file.
+ *
+ * On entry, "fp" should be positioned on the signature bytes for the
+ * entry.  On exit, "fp" will point at the signature word for the next
+ * entry or for the EOCD.
+ */
+status_t ZipEntry::CentralDirEntry::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kCDELen];
+
+    /* no re-use */
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+    assert(mFileComment == NULL);
+
+    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("Whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
+    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
+    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
+    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
+    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
+    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
+
+    // TODO: validate sizes and offsets
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* read "extra field" */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+
+    /* grab comment, if any */
+    if (mFileCommentLength != 0) {
+        mFileComment = new unsigned char[mFileCommentLength+1];
+        if (mFileComment == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+        {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileComment[mFileCommentLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a central dir entry.
+ */
+status_t ZipEntry::CentralDirEntry::write(FILE* fp)
+{
+    unsigned char buf[kCDELen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
+    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x10], mCRC32);
+    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
+    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
+    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
+    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
+    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
+    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
+
+    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write comment */
+    if (mFileCommentLength != 0) {
+        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of a CentralDirEntry object.
+ */
+void ZipEntry::CentralDirEntry::dump(void) const
+{
+    LOGD(" CentralDirEntry contents:\n");
+    LOGD("  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u commentLen=%u\n",
+        mFileNameLength, mExtraFieldLength, mFileCommentLength);
+    LOGD("  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
+        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
+        mLocalHeaderRelOffset);
+
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+    if (mFileComment != NULL)
+        LOGD("  comment: '%s'\n", mFileComment);
+}
+
diff --git a/libs/utils/ZipFile.cpp b/libs/utils/ZipFile.cpp
new file mode 100644
index 0000000..89aa874
--- /dev/null
+++ b/libs/utils/ZipFile.cpp
@@ -0,0 +1,1296 @@
+/*
+ * 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 to Zip archives.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipFile.h"
+#include "utils/ZipUtils.h"
+#include "utils/Log.h"
+
+#include <zlib.h>
+#define DEF_MEM_LEVEL 8                // normally in zutil.h?
+
+#include <memory.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Some environments require the "b", some choke on it.
+ */
+#define FILE_OPEN_RO        "rb"
+#define FILE_OPEN_RW        "r+b"
+#define FILE_OPEN_RW_CREATE "w+b"
+
+/* should live somewhere else? */
+static status_t errnoToStatus(int err)
+{
+    if (err == ENOENT)
+        return NAME_NOT_FOUND;
+    else if (err == EACCES)
+        return PERMISSION_DENIED;
+    else
+        return UNKNOWN_ERROR;
+}
+
+/*
+ * Open a file and parse its guts.
+ */
+status_t ZipFile::open(const char* zipFileName, int flags)
+{
+    bool newArchive = false;
+
+    assert(mZipFp == NULL);     // no reopen
+
+    if ((flags & kOpenTruncate))
+        flags |= kOpenCreate;           // trunc implies create
+
+    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // not both
+    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
+        return INVALID_OPERATION;       // not neither
+    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // create requires write
+
+    if (flags & kOpenTruncate) {
+        newArchive = true;
+    } else {
+        newArchive = (access(zipFileName, F_OK) != 0);
+        if (!(flags & kOpenCreate) && newArchive) {
+            /* not creating, must already exist */
+            LOGD("File %s does not exist", zipFileName);
+            return NAME_NOT_FOUND;
+        }
+    }
+
+    /* open the file */
+    const char* openflags;
+    if (flags & kOpenReadWrite) {
+        if (newArchive)
+            openflags = FILE_OPEN_RW_CREATE;
+        else
+            openflags = FILE_OPEN_RW;
+    } else {
+        openflags = FILE_OPEN_RO;
+    }
+    mZipFp = fopen(zipFileName, openflags);
+    if (mZipFp == NULL) {
+		int err = errno;
+		LOGD("fopen failed: %d\n", err);
+        return errnoToStatus(err);
+	}
+
+    status_t result;
+    if (!newArchive) {
+        /*
+         * Load the central directory.  If that fails, then this probably
+         * isn't a Zip archive.
+         */
+        result = readCentralDir();
+    } else {
+        /*
+         * Newly-created.  The EndOfCentralDir constructor actually
+         * sets everything to be the way we want it (all zeroes).  We
+         * set mNeedCDRewrite so that we create *something* if the
+         * caller doesn't add any files.  (We could also just unlink
+         * the file if it's brand new and nothing was added, but that's
+         * probably doing more than we really should -- the user might
+         * have a need for empty zip files.)
+         */
+        mNeedCDRewrite = true;
+        result = NO_ERROR;
+    }
+
+    if (flags & kOpenReadOnly)
+        mReadOnly = true;
+    else
+        assert(!mReadOnly);
+
+    return result;
+}
+
+/*
+ * Return the Nth entry in the archive.
+ */
+ZipEntry* ZipFile::getEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= (int) mEntries.size())
+        return NULL;
+
+    return mEntries[idx];
+}
+
+/*
+ * Find an entry by name.
+ */
+ZipEntry* ZipFile::getEntryByName(const char* fileName) const
+{
+    /*
+     * Do a stupid linear string-compare search.
+     *
+     * There are various ways to speed this up, especially since it's rare
+     * to intermingle changes to the archive with "get by name" calls.  We
+     * don't want to sort the mEntries vector itself, however, because
+     * it's used to recreate the Central Directory.
+     *
+     * (Hash table works, parallel list of pointers in sorted order is good.)
+     */
+    int idx;
+
+    for (idx = mEntries.size()-1; idx >= 0; idx--) {
+        ZipEntry* pEntry = mEntries[idx];
+        if (!pEntry->getDeleted() &&
+            strcmp(fileName, pEntry->getFileName()) == 0)
+        {
+            return pEntry;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Empty the mEntries vector.
+ */
+void ZipFile::discardEntries(void)
+{
+    int count = mEntries.size();
+
+    while (--count >= 0)
+        delete mEntries[count];
+
+    mEntries.clear();
+}
+
+
+/*
+ * Find the central directory and read the contents.
+ *
+ * The fun thing about ZIP archives is that they may or may not be
+ * readable from start to end.  In some cases, notably for archives
+ * that were written to stdout, the only length information is in the
+ * central directory at the end of the file.
+ *
+ * Of course, the central directory can be followed by a variable-length
+ * comment field, so we have to scan through it backwards.  The comment
+ * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
+ * itself, plus apparently sometimes people throw random junk on the end
+ * just for the fun of it.
+ *
+ * This is all a little wobbly.  If the wrong value ends up in the EOCD
+ * area, we're hosed.  This appears to be the way that everbody handles
+ * it though, so we're in pretty good company if this fails.
+ */
+status_t ZipFile::readCentralDir(void)
+{
+    status_t result = NO_ERROR;
+    unsigned char* buf = NULL;
+    off_t fileLength, seekStart;
+    long readAmount;
+    int i;
+
+    fseek(mZipFp, 0, SEEK_END);
+    fileLength = ftell(mZipFp);
+    rewind(mZipFp);
+
+    /* too small to be a ZIP archive? */
+    if (fileLength < EndOfCentralDir::kEOCDLen) {
+        LOGD("Length is %ld -- too small\n", (long)fileLength);
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
+    if (buf == NULL) {
+		LOGD("Failure allocating %d bytes for EOCD search",
+			 EndOfCentralDir::kMaxEOCDSearch);
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
+        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
+        readAmount = EndOfCentralDir::kMaxEOCDSearch;
+    } else {
+        seekStart = 0;
+        readAmount = (long) fileLength;
+    }
+    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
+		LOGD("Failure seeking to end of zip at %ld", (long) seekStart);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* read the last part of the file into the buffer */
+    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
+        LOGD("short file? wanted %ld\n", readAmount);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* find the end-of-central-dir magic */
+    for (i = readAmount - 4; i >= 0; i--) {
+        if (buf[i] == 0x50 &&
+            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
+        {
+            LOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        LOGD("EOCD not found, not Zip\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /* extract eocd values */
+    result = mEOCD.readBuf(buf + i, readAmount - i);
+    if (result != NO_ERROR) {
+		LOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
+        goto bail;
+	}
+    //mEOCD.dump();
+
+    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
+        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
+    {
+        LOGD("Archive spanning not supported\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /*
+     * So far so good.  "mCentralDirSize" is the size in bytes of the
+     * central directory, so we can just seek back that far to find it.
+     * We can also seek forward mCentralDirOffset bytes from the
+     * start of the file.
+     *
+     * We're not guaranteed to have the rest of the central dir in the
+     * buffer, nor are we guaranteed that the central dir will have any
+     * sort of convenient size.  We need to skip to the start of it and
+     * read the header, then the other goodies.
+     *
+     * The only thing we really need right now is the file comment, which
+     * we're hoping to preserve.
+     */
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+		LOGD("Failure seeking to central dir offset %ld\n",
+			 mEOCD.mCentralDirOffset);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Loop through and read the central dir entries.
+     */
+    LOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
+    int entry;
+    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
+        ZipEntry* pEntry = new ZipEntry;
+
+        result = pEntry->initFromCDE(mZipFp);
+        if (result != NO_ERROR) {
+            LOGD("initFromCDE failed\n");
+            delete pEntry;
+            goto bail;
+        }
+
+        mEntries.add(pEntry);
+    }
+
+
+    /*
+     * If all went well, we should now be back at the EOCD.
+     */
+    {
+        unsigned char checkBuf[4];
+        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
+            LOGD("EOCD check read failed\n");
+            result = INVALID_OPERATION;
+            goto bail;
+        }
+        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
+            LOGD("EOCD read check failed\n");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        LOGV("+++ EOCD read check passed\n");
+    }
+
+bail:
+    delete[] buf;
+    return result;
+}
+
+
+/*
+ * Add a new file to the archive.
+ *
+ * This requires creating and populating a ZipEntry structure, and copying
+ * the data into the file at the appropriate position.  The "appropriate
+ * position" is the current location of the central directory, which we
+ * casually overwrite (we can put it back later).
+ *
+ * If we were concerned about safety, we would want to make all changes
+ * in a temp file and then overwrite the original after everything was
+ * safely written.  Not really a concern for us.
+ */
+status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
+    const char* storageName, int sourceType, int compressionMethod,
+    ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result = NO_ERROR;
+    long lfhPosn, startPosn, endPosn, uncompressedLen;
+    FILE* inputFp = NULL;
+    unsigned long crc;
+    time_t modWhen;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    assert(compressionMethod == ZipEntry::kCompressDeflated ||
+           compressionMethod == ZipEntry::kCompressStored);
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    /* make sure it doesn't already exist */
+    if (getEntryByName(storageName) != NULL)
+        return ALREADY_EXISTS;
+
+    if (!data) {
+        inputFp = fopen(fileName, FILE_OPEN_RO);
+        if (inputFp == NULL)
+            return errnoToStatus(errno);
+    }
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    pEntry->initNew(storageName, NULL);
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH, even though it's still mostly blank.  We need it
+     * as a place-holder.  In theory the LFH isn't necessary, but in
+     * practice some utilities demand it.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+    startPosn = ftell(mZipFp);
+
+    /*
+     * Copy the data in, possibly compressing it as we go.
+     */
+    if (sourceType == ZipEntry::kCompressStored) {
+        if (compressionMethod == ZipEntry::kCompressDeflated) {
+            bool failed = false;
+            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
+            if (result != NO_ERROR) {
+                LOGD("compression failed, storing\n");
+                failed = true;
+            } else {
+                /*
+                 * Make sure it has compressed "enough".  This probably ought
+                 * to be set through an API call, but I don't expect our
+                 * criteria to change over time.
+                 */
+                long src = inputFp ? ftell(inputFp) : size;
+                long dst = ftell(mZipFp) - startPosn;
+                if (dst + (dst / 10) > src) {
+                    LOGD("insufficient compression (src=%ld dst=%ld), storing\n",
+                        src, dst);
+                    failed = true;
+                }
+            }
+
+            if (failed) {
+                compressionMethod = ZipEntry::kCompressStored;
+                if (inputFp) rewind(inputFp);
+                fseek(mZipFp, startPosn, SEEK_SET);
+                /* fall through to kCompressStored case */
+            }
+        }
+        /* handle "no compression" request, or failed compression from above */
+        if (compressionMethod == ZipEntry::kCompressStored) {
+            if (inputFp) {
+                result = copyFpToFp(mZipFp, inputFp, &crc);
+            } else {
+                result = copyDataToFp(mZipFp, data, size, &crc);
+            }
+            if (result != NO_ERROR) {
+                // don't need to truncate; happens in CDE rewrite
+                LOGD("failed copying data in\n");
+                goto bail;
+            }
+        }
+
+        // currently seeked to end of file
+        uncompressedLen = inputFp ? ftell(inputFp) : size;
+    } else if (sourceType == ZipEntry::kCompressDeflated) {
+        /* we should support uncompressed-from-compressed, but it's not
+         * important right now */
+        assert(compressionMethod == ZipEntry::kCompressDeflated);
+
+        bool scanResult;
+        int method;
+        long compressedLen;
+
+        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
+                        &compressedLen, &crc);
+        if (!scanResult || method != ZipEntry::kCompressDeflated) {
+            LOGD("this isn't a deflated gzip file?");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+
+        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
+        if (result != NO_ERROR) {
+            LOGD("failed copying gzip data in\n");
+            goto bail;
+        }
+    } else {
+        assert(false);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * We could write the "Data Descriptor", but there doesn't seem to
+     * be any point since we're going to go back and write the LFH.
+     *
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);            // seeked to end of compressed data
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
+        compressionMethod);
+    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
+    pEntry->setModWhen(modWhen);
+    pEntry->setLFHOffset(lfhPosn);
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Go back and write the LFH.
+     */
+    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+bail:
+    if (inputFp != NULL)
+        fclose(inputFp);
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Add an entry by copying it from another zip file.  If "padding" is
+ * nonzero, the specified number of bytes will be added to the "extra"
+ * field in the header.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+    int padding, ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result;
+    long lfhPosn, endPosn;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    if (pEntry == NULL) {
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
+    if (result != NO_ERROR)
+        goto bail;
+    if (padding != 0) {
+        result = pEntry->addPadding(padding);
+        if (result != NO_ERROR)
+            goto bail;
+    }
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH.  Since we're not recompressing the data, we already
+     * have all of the fields filled out.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Copy the data over.
+     *
+     * If the "has data descriptor" flag is set, we want to copy the DD
+     * fields as well.  This is a fixed-size area immediately following
+     * the data.
+     */
+    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
+    {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    off_t copyLen;
+    copyLen = pSourceEntry->getCompressedLen();
+    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
+        copyLen += ZipEntry::kDataDescriptorLen;
+
+    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
+        != NO_ERROR)
+    {
+        LOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+    result = NO_ERROR;
+
+bail:
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data.
+ */
+status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (1) {
+        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
+        if (ferror(srcFp) || ferror(dstFp))
+            return errnoToStatus(errno);
+        if (count == 0)
+            break;
+
+        *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "dstFp" will be seeked immediately past the data.
+ */
+status_t ZipFile::copyDataToFp(FILE* dstFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+    if (size > 0) {
+        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
+        if (fwrite(data, 1, size, dstFp) != size) {
+            LOGD("fwrite %d bytes failed\n", (int) size);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy some of the bytes in "src" to "dst".
+ *
+ * If "pCRC32" is NULL, the CRC will not be computed.
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data just written.
+ */
+status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+    unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    if (pCRC32 != NULL)
+        *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (length) {
+        long readSize;
+        
+        readSize = sizeof(tmpBuf);
+        if (readSize > length)
+            readSize = length;
+
+        count = fread(tmpBuf, 1, readSize, srcFp);
+        if ((long) count != readSize) {     // error or unexpected EOF
+            LOGD("fread %d bytes failed\n", (int) readSize);
+            return UNKNOWN_ERROR;
+        }
+
+        if (pCRC32 != NULL)
+            *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+
+        length -= readSize;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Compress all of the data in "srcFp" and write it to "dstFp".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the compressed data.
+ */
+status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    status_t result = NO_ERROR;
+	const size_t kBufSize = 32768;
+	unsigned char* inBuf = NULL;
+	unsigned char* outBuf = NULL;
+	z_stream zstream;
+    bool atEof = false;     // no feof() aviailable yet
+	unsigned long crc;
+	int zerr;
+
+	/*
+	 * Create an input buffer and an output buffer.
+	 */
+	inBuf = new unsigned char[kBufSize];
+	outBuf = new unsigned char[kBufSize];
+	if (inBuf == NULL || outBuf == NULL) {
+		result = NO_MEMORY;
+		goto bail;
+	}
+
+	/*
+	 * 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 = outBuf;
+	zstream.avail_out = kBufSize;
+	zstream.data_type = Z_UNKNOWN;
+
+	zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
+		Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (zerr != Z_OK) {
+		result = UNKNOWN_ERROR;
+		if (zerr == Z_VERSION_ERROR) {
+			LOGE("Installed zlib is not compatible with linked version (%s)\n",
+				ZLIB_VERSION);
+		} else {
+			LOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
+		}
+		goto bail;
+	}
+
+ 	crc = crc32(0L, Z_NULL, 0);
+
+	/*
+	 * Loop while we have data.
+	 */
+	do {
+		size_t getSize;
+		int flush;
+
+		/* only read if the input buffer is empty */
+		if (zstream.avail_in == 0 && !atEof) {
+            LOGV("+++ reading %d bytes\n", (int)kBufSize);
+            if (data) {
+                getSize = size > kBufSize ? kBufSize : size;
+                memcpy(inBuf, data, getSize);
+                data = ((const char*)data) + getSize;
+                size -= getSize;
+            } else {
+                getSize = fread(inBuf, 1, kBufSize, srcFp);
+                if (ferror(srcFp)) {
+                    LOGD("deflate read failed (errno=%d)\n", errno);
+                    goto z_bail;
+                }
+            }
+            if (getSize < kBufSize) {
+                LOGV("+++  got %d bytes, EOF reached\n",
+                    (int)getSize);
+                atEof = true;
+            }
+
+			crc = crc32(crc, inBuf, getSize);
+
+			zstream.next_in = inBuf;
+			zstream.avail_in = getSize;
+		}
+
+		if (atEof)
+			flush = Z_FINISH;       /* tell zlib that we're done */
+		else
+			flush = Z_NO_FLUSH;     /* more to come! */
+
+		zerr = deflate(&zstream, flush);
+		if (zerr != Z_OK && zerr != Z_STREAM_END) {
+			LOGD("zlib deflate call failed (zerr=%d)\n", zerr);
+			result = UNKNOWN_ERROR;
+			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 != (uInt) kBufSize))
+		{
+			LOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
+            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
+                (size_t)(zstream.next_out - outBuf))
+            {
+				LOGD("write %d failed in deflate\n",
+                    (int) (zstream.next_out - outBuf));
+				goto z_bail;
+			}
+
+			zstream.next_out = outBuf;
+			zstream.avail_out = kBufSize;
+		}
+	} while (zerr == Z_OK);
+
+	assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+	*pCRC32 = crc;
+
+z_bail:
+	deflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] inBuf;
+	delete[] outBuf;
+
+	return result;
+}
+
+/*
+ * Mark an entry as deleted.
+ *
+ * We will eventually need to crunch the file down, but if several files
+ * are being removed (perhaps as part of an "update" process) we can make
+ * things considerably faster by deferring the removal to "flush" time.
+ */
+status_t ZipFile::remove(ZipEntry* pEntry)
+{
+    /*
+     * Should verify that pEntry is actually part of this archive, and
+     * not some stray ZipEntry from a different file.
+     */
+
+    /* mark entry as deleted, and mark archive as dirty */
+    pEntry->setDeleted();
+    mNeedCDRewrite = true;
+    return NO_ERROR;
+}
+
+/*
+ * Flush any pending writes.
+ *
+ * In particular, this will crunch out deleted entries, and write the
+ * Central Directory and EOCD if we have stomped on them.
+ */
+status_t ZipFile::flush(void)
+{
+    status_t result = NO_ERROR;
+    long eocdPosn;
+    int i, count;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+    if (!mNeedCDRewrite)
+        return NO_ERROR;
+
+    assert(mZipFp != NULL);
+
+    result = crunchArchive();
+    if (result != NO_ERROR)
+        return result;
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    count = mEntries.size();
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        pEntry->mCDE.write(mZipFp);
+    }
+
+    eocdPosn = ftell(mZipFp);
+    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
+
+    mEOCD.write(mZipFp);
+
+    /*
+     * If we had some stuff bloat up during compression and get replaced
+     * with plain files, or if we deleted some entries, there's a lot
+     * of wasted space at the end of the file.  Remove it now.
+     */
+    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
+        LOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
+        // not fatal
+    }
+
+    /* should we clear the "newly added" flag in all entries now? */
+
+    mNeedCDRewrite = false;
+    return NO_ERROR;
+}
+
+/*
+ * Crunch deleted files out of an archive by shifting the later files down.
+ *
+ * Because we're not using a temp file, we do the operation inside the
+ * current file.
+ */
+status_t ZipFile::crunchArchive(void)
+{
+    status_t result = NO_ERROR;
+    int i, count;
+    long delCount, adjust;
+
+#if 0
+    printf("CONTENTS:\n");
+    for (i = 0; i < (int) mEntries.size(); i++) {
+        printf(" %d: lfhOff=%ld del=%d\n",
+            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
+    }
+    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
+#endif
+
+    /*
+     * Roll through the set of files, shifting them as appropriate.  We
+     * could probably get a slight performance improvement by sliding
+     * multiple files down at once (because we could use larger reads
+     * when operating on batches of small files), but it's not that useful.
+     */
+    count = mEntries.size();
+    delCount = adjust = 0;
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        long span;
+
+        if (pEntry->getLFHOffset() != 0) {
+            long nextOffset;
+
+            /* Get the length of this entry by finding the offset
+             * of the next entry.  Directory entries don't have
+             * file offsets, so we need to find the next non-directory
+             * entry.
+             */
+            nextOffset = 0;
+            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
+                nextOffset = mEntries[ii]->getLFHOffset();
+            if (nextOffset == 0)
+                nextOffset = mEOCD.mCentralDirOffset;
+            span = nextOffset - pEntry->getLFHOffset();
+
+            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
+        } else {
+            /* This is a directory entry.  It doesn't have
+             * any actual file contents, so there's no need to
+             * move anything.
+             */
+            span = 0;
+        }
+
+        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
+        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
+
+        if (pEntry->getDeleted()) {
+            adjust += span;
+            delCount++;
+
+            delete pEntry;
+            mEntries.removeAt(i);
+
+            /* adjust loop control */
+            count--;
+            i--;
+        } else if (span != 0 && adjust > 0) {
+            /* shuffle this entry back */
+            //printf("+++ Shuffling '%s' back %ld\n",
+            //    pEntry->getFileName(), adjust);
+            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
+                        pEntry->getLFHOffset(), span);
+            if (result != NO_ERROR) {
+                /* this is why you use a temp file */
+                LOGE("error during crunch - archive is toast\n");
+                return result;
+            }
+
+            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
+        }
+    }
+
+    /*
+     * Fix EOCD info.  We have to wait until the end to do some of this
+     * because we use mCentralDirOffset to determine "span" for the
+     * last entry.
+     */
+    mEOCD.mCentralDirOffset -= adjust;
+    mEOCD.mNumEntries -= delCount;
+    mEOCD.mTotalNumEntries -= delCount;
+    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()
+
+    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
+    assert(mEOCD.mNumEntries == count);
+
+    return result;
+}
+
+/*
+ * Works like memmove(), but on pieces of a file.
+ */
+status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
+{
+    if (dst == src || n <= 0)
+        return NO_ERROR;
+
+    unsigned char readBuf[32768];
+
+    if (dst < src) {
+        /* shift stuff toward start of file; must read from start */
+        while (n != 0) {
+            size_t getSize = sizeof(readBuf);
+            if (getSize > n)
+                getSize = n;
+
+            if (fseek(fp, (long) src, SEEK_SET) != 0) {
+                LOGD("filemove src seek %ld failed\n", (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fread(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove read %ld off=%ld failed\n",
+                    (long) getSize, (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
+                LOGD("filemove dst seek %ld failed\n", (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove write %ld off=%ld failed\n",
+                    (long) getSize, (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            src += getSize;
+            dst += getSize;
+            n -= getSize;
+        }
+    } else {
+        /* shift stuff toward end of file; must read from end */
+        assert(false);      // write this someday, maybe
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Get the modification time from a file descriptor.
+ */
+time_t ZipFile::getModTime(int fd)
+{
+    struct stat sb;
+
+    if (fstat(fd, &sb) < 0) {
+        LOGD("HEY: fstat on fd %d failed\n", fd);
+        return (time_t) -1;
+    }
+
+    return sb.st_mtime;
+}
+
+
+#if 0       /* this is a bad idea */
+/*
+ * Get a copy of the Zip file descriptor.
+ *
+ * We don't allow this if the file was opened read-write because we tend
+ * to leave the file contents in an uncertain state between calls to
+ * flush().  The duplicated file descriptor should only be valid for reads.
+ */
+int ZipFile::getZipFd(void) const
+{
+    if (!mReadOnly)
+        return INVALID_OPERATION;
+    assert(mZipFp != NULL);
+
+    int fd;
+    fd = dup(fileno(mZipFp));
+    if (fd < 0) {
+        LOGD("didn't work, errno=%d\n", errno);
+    }
+
+    return fd;
+}
+#endif
+
+
+#if 0
+/*
+ * Expand data.
+ */
+bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
+{
+    return false;
+}
+#endif
+
+// free the memory when you're done
+void* ZipFile::uncompress(const ZipEntry* entry)
+{
+    size_t unlen = entry->getUncompressedLen();
+    size_t clen = entry->getCompressedLen();
+
+    void* buf = malloc(unlen);
+    if (buf == NULL) {
+        return NULL;
+    }
+
+    fseek(mZipFp, 0, SEEK_SET);
+
+    off_t offset = entry->getFileOffset();
+    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
+        goto bail;
+    }
+
+    switch (entry->getCompressionMethod())
+    {
+        case ZipEntry::kCompressStored: {
+            ssize_t amt = fread(buf, 1, unlen, mZipFp);
+            if (amt != (ssize_t)unlen) {
+                goto bail;
+            }
+#if 0
+            printf("data...\n");
+            const unsigned char* p = (unsigned char*)buf;
+            const unsigned char* end = p+unlen;
+            for (int i=0; i<32 && p < end; i++) {
+                printf("0x%08x ", (int)(offset+(i*0x10)));
+                for (int j=0; j<0x10 && p < end; j++) {
+                    printf(" %02x", *p);
+                    p++;
+                }
+                printf("\n");
+            }
+#endif
+
+            }
+            break;
+        case ZipEntry::kCompressDeflated: {
+            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
+                goto bail;
+            }
+            }
+            break;
+        default:
+            goto bail;
+    }
+    return buf;
+
+bail:
+    free(buf);
+    return NULL;
+}
+
+
+/*
+ * ===========================================================================
+ *		ZipFile::EndOfCentralDir
+ * ===========================================================================
+ */
+
+/*
+ * Read the end-of-central-dir fields.
+ *
+ * "buf" should be positioned at the EOCD signature, and should contain
+ * the entire EOCD area including the comment.
+ */
+status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
+{
+    /* don't allow re-use */
+    assert(mComment == NULL);
+
+    if (len < kEOCDLen) {
+        /* looks like ZIP file got truncated */
+        LOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
+            kEOCDLen, len);
+        return INVALID_OPERATION;
+    }
+
+    /* this should probably be an assert() */
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
+        return UNKNOWN_ERROR;
+
+    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
+    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
+    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
+    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
+    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
+    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
+    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
+
+    // TODO: validate mCentralDirOffset
+
+    if (mCommentLen > 0) {
+        if (kEOCDLen + mCommentLen > len) {
+            LOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
+                kEOCDLen, mCommentLen, len);
+            return UNKNOWN_ERROR;
+        }
+        mComment = new unsigned char[mCommentLen];
+        memcpy(mComment, buf + kEOCDLen, mCommentLen);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Write an end-of-central-directory section.
+ */
+status_t ZipFile::EndOfCentralDir::write(FILE* fp)
+{
+    unsigned char buf[kEOCDLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
+    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
+    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
+    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
+    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
+    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
+    ZipEntry::putShortLE(&buf[0x14], mCommentLen);
+
+    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
+        return UNKNOWN_ERROR;
+    if (mCommentLen > 0) {
+        assert(mComment != NULL);
+        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of an EndOfCentralDir object.
+ */
+void ZipFile::EndOfCentralDir::dump(void) const
+{
+    LOGD(" EndOfCentralDir contents:\n");
+    LOGD("  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
+        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
+    LOGD("  centDirSize=%lu centDirOff=%lu commentLen=%u\n",
+        mCentralDirSize, mCentralDirOffset, mCommentLen);
+}
+
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
new file mode 100644
index 0000000..d312daf
--- /dev/null
+++ b/libs/utils/ZipFileCRO.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include "utils/ZipFileCRO.h"
+#include "utils/ZipFileRO.h"
+
+using namespace android;
+
+ZipFileCRO ZipFileXRO_open(const char* path) {
+    ZipFileRO* zip = new ZipFileRO();
+    if (zip->open(path) == NO_ERROR) {
+        return (ZipFileCRO)zip;
+    }
+    return NULL;
+}
+
+void ZipFileCRO_destroy(ZipFileCRO zipToken) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    delete zip;
+}
+
+ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
+        const char* fileName) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    return (ZipEntryCRO)zip->findEntryByName(fileName);
+}
+
+bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
+        int* pMethod, long* pUncompLen,
+        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
+            pModWhen, pCrc32);
+}
+
+bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->uncompressEntry(entry, fd);
+}
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
new file mode 100644
index 0000000..ae8c719
--- /dev/null
+++ b/libs/utils/ZipFileRO.cpp
@@ -0,0 +1,724 @@
+/*
+ * 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 "utils/ZipFileRO.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+#include <zlib.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Zip file constants.
+ */
+#define kEOCDSignature      0x06054b50
+#define kEOCDLen            22
+#define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDFileOffset     16              // offset to central directory
+
+#define kMaxCommentLen      65535           // longest possible in ushort
+#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature       0x04034b50
+#define kLFHLen             30              // excluding variable-len fields
+#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 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
+
+/*
+ * 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
+
+/*
+ * 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 = ((long) entry) - kZipEntryAdj;
+    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
+        LOGW("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;
+    off_t length;
+
+    assert(mFileMap == NULL);
+
+    /*
+     * Open and map the specified file.
+     */
+    fd = ::open(zipFileName, O_RDONLY);
+    if (fd < 0) {
+        LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
+        return NAME_NOT_FOUND;
+    }
+
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFileMap = new FileMap();
+    if (mFileMap == NULL) {
+        close(fd);
+        return NO_MEMORY;
+    }
+    if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
+        LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFd = fd;
+
+    /*
+     * Got it mapped, verify it and create data structures for fast access.
+     */
+    if (!parseZipArchive()) {
+        mFileMap->release();
+        mFileMap = NULL;
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+/*
+ * Parse the Zip archive, verifying its contents and initializing internal
+ * data structures.
+ */
+bool ZipFileRO::parseZipArchive(void)
+{
+#define CHECK_OFFSET(_off) {                                                \
+        if ((unsigned int) (_off) >= maxOffset) {                           \
+            LOGE("ERROR: bad offset %u (max %d): %s\n",                     \
+                (unsigned int) (_off), maxOffset, #_off);                   \
+            goto bail;                                                      \
+        }                                                                   \
+    }
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    const unsigned char* ptr;
+    size_t length = mFileMap->getDataLength();
+    bool result = false;
+    unsigned int i, numEntries, cdOffset;
+    unsigned int val;
+
+    /*
+     * The first 4 bytes of the file will either be the local header
+     * signature for the first file (kLFHSignature) or, if the archive doesn't
+     * have any files in it, the end-of-central-directory signature
+     * (kEOCDSignature).
+     */
+    val = get4LE(basePtr);
+    if (val == kEOCDSignature) {
+        LOGI("Found Zip archive, but it looks empty\n");
+        goto bail;
+    } else if (val != kLFHSignature) {
+        LOGV("Not a Zip archive (found 0x%08x)\n", val);
+        goto bail;
+    }
+
+    /*
+     * Find the EOCD.  We'll find it immediately unless they have a file
+     * comment.
+     */
+    ptr = basePtr + length - kEOCDLen;
+
+    while (ptr >= basePtr) {
+        if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
+            break;
+        ptr--;
+    }
+    if (ptr < basePtr) {
+        LOGI("Could not find end-of-central-directory in Zip\n");
+        goto bail;
+    }
+
+    /*
+     * There are two interesting items in the EOCD block: the number of
+     * entries in the file, and the file offset of the start of the
+     * central directory.
+     *
+     * (There's actually a count of the #of entries in this file, and for
+     * all files which comprise a spanned archive, but for our purposes
+     * we're only interested in the current file.  Besides, we expect the
+     * two to be equivalent for our stuff.)
+     */
+    numEntries = get2LE(ptr + kEOCDNumEntries);
+    cdOffset = get4LE(ptr + kEOCDFileOffset);
+
+    /* valid offsets are [0,EOCD] */
+    unsigned int maxOffset;
+    maxOffset = (ptr - basePtr) +1;
+
+    LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
+    if (numEntries == 0 || cdOffset >= length) {
+        LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
+            numEntries, cdOffset, length);
+        goto bail;
+    }
+
+    /*
+     * Create hash table.  We have a minimum 75% load factor, possibly as
+     * low as 50% after we round off to a power of 2.
+     */
+    mNumEntries = numEntries;
+    mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
+    mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
+
+    /*
+     * Walk through the central directory, adding entries to the hash
+     * table.
+     */
+    ptr = basePtr + cdOffset;
+    for (i = 0; i < numEntries; i++) {
+        unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
+        const unsigned char* localHdr;
+        unsigned int hash;
+
+        if (get4LE(ptr) != kCDESignature) {
+            LOGW("Missed a central dir sig (at %d)\n", i);
+            goto bail;
+        }
+        if (ptr + kCDELen > basePtr + length) {
+            LOGW("Ran off the end (at %d)\n", i);
+            goto bail;
+        }
+
+        localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        CHECK_OFFSET(localHdrOffset);
+        fileNameLen = get2LE(ptr + kCDENameLen);
+        extraLen = get2LE(ptr + kCDEExtraLen);
+        commentLen = get2LE(ptr + kCDECommentLen);
+
+        //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
+        //    i, localHdrOffset, fileNameLen, extraLen, commentLen);
+        //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
+
+        /* add the CDE filename to the hash table */
+        hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
+        addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
+
+        localHdr = basePtr + localHdrOffset;
+        if (get4LE(localHdr) != kLFHSignature) {
+            LOGW("Bad offset to local header: %d (at %d)\n",
+                localHdrOffset, i);
+            goto bail;
+        }
+
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
+        CHECK_OFFSET(ptr - basePtr);
+    }
+
+    result = true;
+
+bail:
+    return result;
+#undef CHECK_OFFSET
+}
+
+
+/*
+ * 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 0 if not found.
+ */
+ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
+{
+    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) (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) {
+        LOGW("Invalid index %d\n", idx);
+        return NULL;
+    }
+
+    for (int ent = 0; ent < mHashTableSize; ent++) {
+        if (mHashTable[ent].name != NULL) {
+            if (idx-- == 0)
+                return (ZipEntryRO) (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, long* pUncompLen,
+    long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return false;
+
+    /*
+     * Recover the start of the central directory entry from the filename
+     * pointer.
+     */
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
+    size_t zipLength = mFileMap->getDataLength();
+
+    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);
+
+    /*
+     * We 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.
+     */
+    unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+    if (localHdrOffset + kLFHLen >= zipLength) {
+        LOGE("ERROR: bad local hdr offset in zip\n");
+        return false;
+    }
+    const unsigned char* localHdr = basePtr + localHdrOffset;
+    off_t dataOffset = localHdrOffset + kLFHLen
+        + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
+    if ((unsigned long) dataOffset >= zipLength) {
+        LOGE("ERROR: bad data offset in zip\n");
+        return false;
+    }
+
+    if (pCompLen != NULL) {
+        *pCompLen = get4LE(ptr + kCDECompLen);
+        if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
+            LOGE("ERROR: bad compressed length in zip\n");
+            return false;
+        }
+    }
+    if (pUncompLen != NULL) {
+        *pUncompLen = get4LE(ptr + kCDEUncompLen);
+        if (*pUncompLen < 0) {
+            LOGE("ERROR: negative uncompressed length in zip\n");
+            return false;
+        }
+        if (method == kCompressStored &&
+            (size_t)(dataOffset + *pUncompLen) >= zipLength)
+        {
+            LOGE("ERROR: bad uncompressed length in zip\n");
+            return false;
+        }
+    }
+
+    if (pOffset != NULL) {
+        *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;
+    long compLen;
+    off_t offset;
+
+    if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
+        return NULL;
+
+    newMap = new FileMap();
+    if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, 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 int kSequentialMin = 32768;
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    int method;
+    long uncompLen, compLen;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    /*
+     * 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)
+        mFileMap->advise(FileMap::SEQUENTIAL);
+
+    if (method == kCompressStored) {
+        memcpy(buffer, basePtr + offset, uncompLen);
+    } else {
+        if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    if (compLen > kSequentialMin)
+        mFileMap->advise(FileMap::NORMAL);
+
+    result = true;
+
+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 -1;
+
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    int method;
+    long uncompLen, compLen;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    if (method == kCompressStored) {
+        ssize_t actual;
+
+        actual = write(fd, basePtr + offset, uncompLen);
+        if (actual < 0) {
+            LOGE("Write failed: %s\n", strerror(errno));
+            goto bail;
+        } else if (actual != uncompLen) {
+            LOGE("Partial write during uncompress (%d of %ld)\n",
+                (int)actual, uncompLen);
+            goto bail;
+        } else {
+            LOGI("+++ successful write\n");
+        }
+    } else {
+        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to another.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
+    long uncompLen, long 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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Expand data.
+     */
+    zerr = inflate(&zstream, Z_FINISH);
+    if (zerr != Z_STREAM_END) {
+        LOGW("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 ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, 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,
+    long uncompLen, long compLen)
+{
+    bool result = false;
+    const int 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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("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) {
+            LOGW("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 = write(fd, writeBuf, writeSize);
+            if (cc != (int) writeSize) {
+                LOGW("write failed in inflate (%d vs %ld)\n", 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 ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
new file mode 100644
index 0000000..bfbacfe
--- /dev/null
+++ b/libs/utils/ZipUtils.cpp
@@ -0,0 +1,344 @@
+/*
+ * 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 "utils/ZipUtils.h"
+#include "utils/ZipFileRO.h"
+#include "utils/Log.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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("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;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = read(fd, readBuf, getSize);
+            if (cc != (int) getSize) {
+                LOGD("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) {
+            LOGD("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) {
+        LOGW("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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("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;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = fread(readBuf, getSize, 1, fp);
+            if (cc != (int) getSize) {
+                LOGD("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) {
+            LOGD("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) {
+        LOGW("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/utils/characterData.h b/libs/utils/characterData.h
new file mode 100644
index 0000000..e931d99
--- /dev/null
+++ b/libs/utils/characterData.h
@@ -0,0 +1,730 @@
+/*
+ * 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.
+ */
+
+// Automatically generated on 07-11-2006 by make-CharacterDataC
+// DO NOT EDIT DIRECTLY
+namespace CharacterData {
+
+    // Structure containing an array of ranges
+    struct Range {
+        int length;
+        const uint32_t* array;
+    };
+
+    // For Latin1 characters just index into this array to get the index and decomposition
+    static const uint16_t LATIN1_DATA[] = {
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002, 
+        0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006, 
+        0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C, 
+        0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 
+        0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006, 
+        0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 
+        0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 
+        0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 
+        0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038, 
+        0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 
+        0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 
+        0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 
+        0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054, 
+        0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037, 
+        0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006, 
+        0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
+    };
+
+    // Each of these arrays is stripped into ranges. In order to build the arrays, each
+    // codepoint was bit-shifted so that even and odd characters were separated into different
+    // arrays. The identifier of each array is the top byte after bit-shifting.
+    // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
+    // index into another array of all possible packed data values. The top 16 bits are the
+    // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
+    // and the rest for the index.
+    static const uint32_t a0[] = {
+        0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863, 
+        0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063, 
+        0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067, 
+        0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C, 
+        0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065, 
+        0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055, 
+        0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073, 
+        0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075, 
+        0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077, 
+        0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055, 
+        0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055, 
+        0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082, 
+        0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881, 
+        0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083, 
+        0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037, 
+        0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060, 
+        0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861, 
+        0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F, 
+        0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892, 
+        0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063, 
+        0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865, 
+        0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863, 
+        0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096, 
+        0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083, 
+        0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078, 
+        0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083, 
+        0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E, 
+        0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5, 
+        0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D, 
+        0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010, 
+        0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E, 
+        0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083, 
+        0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7, 
+        0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097, 
+        0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7, 
+        0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071, 
+        0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7, 
+        0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8, 
+        0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE, 
+        0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071, 
+        0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7, 
+        0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071, 
+        0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083, 
+        0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078, 
+        0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078, 
+        0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083, 
+        0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7, 
+        0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071, 
+        0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7, 
+        0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8, 
+        0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078, 
+        0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071, 
+        0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7, 
+        0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB, 
+        0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071, 
+        0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083, 
+        0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA, 
+        0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071, 
+        0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083, 
+        0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA, 
+        0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7, 
+        0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8, 
+        0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071, 
+        0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083, 
+        0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097, 
+        0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8, 
+        0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078, 
+        0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078, 
+        0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071, 
+        0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC, 
+        0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097, 
+        0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC, 
+        0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871, 
+        0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071, 
+        0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083, 
+        0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078, 
+        0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083, 
+        0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097, 
+        0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881, 
+        0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071, 
+        0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071, 
+        0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6, 
+        0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD, 
+        0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071, 
+        0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071, 
+        0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071, 
+        0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083, 
+        0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7, 
+        0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB, 
+        0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078, 
+        0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA, 
+        0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071, 
+        0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083, 
+        0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9, 
+        0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA, 
+        0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055, 
+        0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855, 
+        0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3, 
+        0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855, 
+        0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855, 
+        0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA, 
+        0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006, 
+        0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD, 
+        0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006, 
+        0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038, 
+        0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4, 
+        0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4, 
+        0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008, 
+        0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877, 
+        0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054, 
+        0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877, 
+        0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054, 
+        0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F, 
+        0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0, 
+        0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8, 
+        0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019, 
+        0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019, 
+        0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019, 
+        0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8, 
+        0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8, 
+        0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019, 
+        0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD, 
+        0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019, 
+        0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8, 
+        0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD, 
+        0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102, 
+        0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8, 
+        0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4, 
+        0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906, 
+        0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E, 
+        0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C, 
+        0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112, 
+        0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919, 
+        0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5, 
+        0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054, 
+        0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054, 
+        0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106, 
+        0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109, 
+        0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078, 
+        0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078, 
+        0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD, 
+        0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121, 
+        0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8, 
+        0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8, 
+        0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019, 
+        0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019, 
+        0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8, 
+        0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8, 
+        0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8, 
+        0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8, 
+        0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123, 
+        0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019, 
+        0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063, 
+        0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 
+        0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0, 
+        0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054, 
+        0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054, 
+        0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127, 
+        0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B, 
+        0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871, 
+        0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078, 
+        0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871, 
+        0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871, 
+        0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD, 
+        0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094, 
+        0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078, 
+        0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936, 
+        0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894, 
+        0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094, 
+        0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854, 
+        0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078, 
+        0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083, 
+        0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871, 
+        0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055, 
+        0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B, 
+        0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E, 
+        0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E, 
+        0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E, 
+        0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E, 
+        0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078, 
+        0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E, 
+        0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E, 
+        0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E, 
+        0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E, 
+        0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E, 
+        0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083, 
+        0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038, 
+        0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099, 
+        0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E, 
+        0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E, 
+        0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E, 
+        0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E, 
+        0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E, 
+        0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E, 
+        0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078, 
+        0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810, 
+        0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860, 
+        0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071, 
+        0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071, 
+        0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854, 
+        0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078, 
+        0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078, 
+        0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8, 
+        0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143, 
+        0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A, 
+        0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150, 
+        0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156, 
+        0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151, 
+        0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0, 
+        0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078, 
+        0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071, 
+        0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B, 
+        0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B, 
+        0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B, 
+        0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F, 
+        0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078, 
+        0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083, 
+        0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078, 
+        0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 
+        0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877, 
+        0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877, 
+        0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877, 
+        0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 
+        0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 
+        0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855, 
+        0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812, 
+        0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E, 
+        0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814, 
+        0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
+    };
+
+    static const uint32_t a1[] = {
+        0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a7[] = {
+        0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a8[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+    static const uint32_t a16[] = {
+        0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865, 
+        0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065, 
+        0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063, 
+        0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166, 
+        0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F, 
+        0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071, 
+        0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863, 
+        0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C, 
+        0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063, 
+        0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A, 
+        0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173, 
+        0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881, 
+        0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 
+        0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037, 
+        0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860, 
+        0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177, 
+        0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065, 
+        0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060, 
+        0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893, 
+        0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078, 
+        0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865, 
+        0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865, 
+        0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098, 
+        0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B, 
+        0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D, 
+        0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E, 
+        0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B, 
+        0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E, 
+        0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083, 
+        0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6, 
+        0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E, 
+        0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071, 
+        0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083, 
+        0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083, 
+        0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071, 
+        0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071, 
+        0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083, 
+        0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078, 
+        0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181, 
+        0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083, 
+        0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071, 
+        0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083, 
+        0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E, 
+        0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083, 
+        0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071, 
+        0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078, 
+        0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083, 
+        0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071, 
+        0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078, 
+        0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078, 
+        0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071, 
+        0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071, 
+        0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 
+        0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078, 
+        0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008, 
+        0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078, 
+        0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083, 
+        0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180, 
+        0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078, 
+        0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078, 
+        0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071, 
+        0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7, 
+        0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078, 
+        0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078, 
+        0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181, 
+        0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071, 
+        0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078, 
+        0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008, 
+        0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182, 
+        0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078, 
+        0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078, 
+        0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181, 
+        0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083, 
+        0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083, 
+        0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871, 
+        0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7, 
+        0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883, 
+        0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078, 
+        0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083, 
+        0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181, 
+        0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 
+        0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071, 
+        0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071, 
+        0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071, 
+        0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071, 
+        0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD, 
+        0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188, 
+        0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071, 
+        0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097, 
+        0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071, 
+        0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078, 
+        0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7, 
+        0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E, 
+        0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108, 
+        0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F, 
+        0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078, 
+        0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083, 
+        0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F, 
+        0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180, 
+        0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081, 
+        0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855, 
+        0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA, 
+        0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837, 
+        0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9, 
+        0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B, 
+        0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005, 
+        0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D, 
+        0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F, 
+        0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006, 
+        0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005, 
+        0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912, 
+        0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112, 
+        0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083, 
+        0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054, 
+        0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054, 
+        0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855, 
+        0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078, 
+        0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197, 
+        0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F, 
+        0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819, 
+        0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8, 
+        0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019, 
+        0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE, 
+        0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE, 
+        0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE, 
+        0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE, 
+        0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6, 
+        0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019, 
+        0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE, 
+        0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054, 
+        0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054, 
+        0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078, 
+        0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A, 
+        0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7, 
+        0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3, 
+        0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD, 
+        0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F, 
+        0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019, 
+        0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078, 
+        0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078, 
+        0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7, 
+        0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5, 
+        0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD, 
+        0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019, 
+        0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE, 
+        0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE, 
+        0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A, 
+        0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE, 
+        0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8, 
+        0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019, 
+        0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD, 
+        0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD, 
+        0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD, 
+        0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8, 
+        0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078, 
+        0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006, 
+        0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078, 
+        0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078, 
+        0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078, 
+        0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099, 
+        0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078, 
+        0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A, 
+        0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6, 
+        0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054, 
+        0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871, 
+        0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871, 
+        0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871, 
+        0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078, 
+        0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 
+        0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9, 
+        0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD, 
+        0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7, 
+        0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4, 
+        0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078, 
+        0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854, 
+        0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071, 
+        0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071, 
+        0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871, 
+        0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055, 
+        0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078, 
+        0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E, 
+        0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E, 
+        0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E, 
+        0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E, 
+        0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E, 
+        0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E, 
+        0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E, 
+        0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF, 
+        0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E, 
+        0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E, 
+        0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 
+        0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 
+        0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083, 
+        0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038, 
+        0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D, 
+        0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078, 
+        0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E, 
+        0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E, 
+        0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E, 
+        0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E, 
+        0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E, 
+        0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E, 
+        0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D, 
+        0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819, 
+        0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836, 
+        0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078, 
+        0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078, 
+        0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141, 
+        0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078, 
+        0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE, 
+        0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184, 
+        0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0, 
+        0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E, 
+        0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150, 
+        0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6, 
+        0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078, 
+        0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071, 
+        0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078, 
+        0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181, 
+        0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078, 
+        0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083, 
+        0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094, 
+        0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094, 
+        0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 
+        0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054, 
+        0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877, 
+        0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078, 
+        0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078, 
+        0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877, 
+        0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855, 
+        0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877, 
+        0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC, 
+        0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC, 
+        0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855, 
+        0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811, 
+        0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817, 
+        0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813, 
+        0xEBFE2815, 0xEBFF2817, 0xEC000078
+    };
+
+    static const uint32_t a17[] = {
+        0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a23[] = {
+        0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a24[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+
+    // The full set of all arrays to be searched.
+    static const Range FULL_DATA[] = {
+        {sizeof(a0)/sizeof(uint32_t), a0},
+        {sizeof(a1)/sizeof(uint32_t), a1},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a7)/sizeof(uint32_t), a7},
+        {sizeof(a8)/sizeof(uint32_t), a8},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a16)/sizeof(uint32_t), a16},
+        {sizeof(a17)/sizeof(uint32_t), a17},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a23)/sizeof(uint32_t), a23},
+        {sizeof(a24)/sizeof(uint32_t), a24},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0}
+    };
+
+    // Array of uppercase differences
+    static const short UCDIFF[] = {
+            0,   -32,   743,   121,    -1,  -232,  -300,    97, 
+          163,   130,    56,    -2,   -79,  -210,  -206,  -205, 
+         -202,  -203,  -207,  -209,  -211,  -213,  -214,  -218, 
+         -217,  -219,   -83,    84,   -38,   -37,   -31,   -64, 
+          -63,   -62,   -57,   -47,   -54,   -86,   -80,     7, 
+          -96,   -48,   -59,     8,    74,    86,   100,   128, 
+          112,   126,     9, -7205,   -16,   -26, -7264,   -40
+    };
+
+    // Array of lowercase differences
+    static const short LCDIFF[] = {
+            0,    32,     1,  -199,  -121,   210,   206,   205, 
+           79,   202,   203,   207,   211,   209,   213,   214, 
+          218,   217,   219,     2,   -97,   -56,  -130,  -163, 
+           83,    38,    37,    64,    63,   -60,    -7,    80, 
+           48,  7264,    -8,   -74,    -9,   -86,  -100,  -112, 
+         -128,  -126, -7517, -8383, -8262,    16,    26,    40
+    };
+
+    // Array of titlecase differences
+    static const short TCDIFF[] = {
+            3,     1,     0,    -1
+    };
+
+    // Array of mirrored character differences
+    static const short MIRROR_DIFF[] = {
+            0,     1,    -1,     2,    -2,    16,   -16,     3, 
+           -3,  2016,   138,  1824,  2104,  2108,  2106,  -138, 
+            8,     7,    -8,    -7, -1824, -2016, -2104, -2106, 
+        -2108
+    };
+
+   // Array of all possible numeric values
+   static const int NUMERICS[] = {
+            -1,      0,      1,      2,      3,      4,      5,      6, 
+             7,      8,      9,     10,     11,     12,     13,     14, 
+            15,     16,     17,     18,     19,     20,     21,     22, 
+            23,     24,     25,     26,     27,     28,     29,     30, 
+            31,     32,     33,     34,     35,     -2,    100,   1000, 
+            40,     50,     60,     70,     80,     90,  10000,    500, 
+          5000,     36,     37,     38,     39,     41,     42,     43, 
+            44,     45,     46,     47,     48,     49,    200,    300, 
+           400,    600,    700,    800,    900,   2000,   3000,   4000, 
+          6000,   7000,   8000,   9000,  20000,  30000,  40000,  50000, 
+         60000,  70000,  80000,  90000
+    };
+
+    // All possible packed data values, no duplicates
+    static const uint32_t PACKED_DATA[] = {
+        0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8, 
+        0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069, 
+        0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069, 
+        0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001, 
+        0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001, 
+        0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001, 
+        0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB, 
+        0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802, 
+        0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802, 
+        0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802, 
+        0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130, 
+        0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB, 
+        0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001, 
+        0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001, 
+        0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001, 
+        0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802, 
+        0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001, 
+        0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802, 
+        0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018, 
+        0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044, 
+        0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008, 
+        0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B, 
+        0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B, 
+        0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6, 
+        0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB, 
+        0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002, 
+        0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001, 
+        0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230, 
+        0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001, 
+        0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A, 
+        0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A, 
+        0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9, 
+        0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB, 
+        0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB, 
+        0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B, 
+        0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB, 
+        0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A, 
+        0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B, 
+        0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB, 
+        0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012, 
+        0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B, 
+        0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA, 
+        0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA, 
+        0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B, 
+        0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001, 
+        0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802, 
+        0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802, 
+        0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009, 
+        0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B, 
+        0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210, 
+        0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A, 
+        0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A, 
+        0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9, 
+        0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5, 
+        0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A, 
+        0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB, 
+        0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB, 
+        0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B, 
+        0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA, 
+        0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
+    };
+}
diff --git a/libs/utils/executablepath_darwin.cpp b/libs/utils/executablepath_darwin.cpp
new file mode 100644
index 0000000..2e3c3a0
--- /dev/null
+++ b/libs/utils/executablepath_darwin.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#include <utils/executablepath.h>
+#import <Carbon/Carbon.h>
+#include <unistd.h>
+
+void executablepath(char s[PATH_MAX])
+{
+    ProcessSerialNumber psn;
+    GetCurrentProcess(&psn);
+    CFDictionaryRef dict;
+    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
+    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
+                CFSTR("CFBundleExecutable"));
+    CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
+}
+
diff --git a/libs/utils/executablepath_linux.cpp b/libs/utils/executablepath_linux.cpp
new file mode 100644
index 0000000..b8d2a3d
--- /dev/null
+++ b/libs/utils/executablepath_linux.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include <utils/executablepath.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdio.h>
+
+void executablepath(char exe[PATH_MAX])
+{
+    char proc[100];
+    sprintf(proc, "/proc/%d/exe", getpid());
+    
+    int err = readlink(proc, exe, PATH_MAX);
+}
+
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
new file mode 100644
index 0000000..c13760d
--- /dev/null
+++ b/libs/utils/futex_synchro.c
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <limits.h>
+
+#include <sys/time.h>
+#include <sched.h>
+
+#include <errno.h>
+
+#include <private/utils/futex_synchro.h>
+
+
+// This futex glue code is need on desktop linux, but is part of klibc on ARM
+#if !defined(__arm__)
+
+#include <sys/syscall.h>
+typedef unsigned int u32;
+#define asmlinkage
+#define __user
+#include <linux/futex.h>
+#include <utils/Atomic.h>
+
+
+int futex (int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3)
+{
+    int err = syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
+    return err == 0 ? 0 : -errno;
+}
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout)
+{
+    return futex((int*)ftx, FUTEX_WAIT, val, timeout, NULL, 0);
+}
+
+int __futex_wake(volatile void *ftx, int count)
+{
+    return futex((int*)ftx, FUTEX_WAKE, count, NULL, NULL, 0);
+}
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr)
+{
+    return android_atomic_cmpxchg(old, _new, ptr);
+}
+
+int __atomic_swap(int _new, volatile int *ptr)
+{
+    return android_atomic_swap(_new, ptr);
+}
+
+int __atomic_dec(volatile int *ptr)
+{
+    return android_atomic_dec(ptr);
+}
+
+#else // !defined(__arm__)
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+int __futex_wake(volatile void *ftx, int count);
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr);
+int __atomic_swap(int _new, volatile int *ptr);
+int __atomic_dec(volatile int *ptr);
+
+#endif // !defined(__arm__)
+
+
+// lock states
+//
+// 0: unlocked
+// 1: locked, no waiters
+// 2: locked, maybe waiters
+
+void futex_mutex_init(futex_mutex_t *m)
+{
+    m->value = 0;
+}
+
+int futex_mutex_lock(futex_mutex_t *m, unsigned msec)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    if(msec == FUTEX_WAIT_INFINITE) {
+        while(__atomic_swap(2, &m->value) != 0) {
+            __futex_wait(&m->value, 2, 0);
+        }
+    } else {
+        struct timespec ts;
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        while(__atomic_swap(2, &m->value) != 0) {
+            if(__futex_wait(&m->value, 2, &ts) == -ETIMEDOUT) {
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+int futex_mutex_trylock(futex_mutex_t *m)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    return -1;
+}
+
+void futex_mutex_unlock(futex_mutex_t *m)
+{
+    if(__atomic_dec(&m->value) != 1) {
+        m->value = 0;
+        __futex_wake(&m->value, 1);
+    }
+}
+
+/* XXX *technically* there is a race condition that could allow
+ * XXX a signal to be missed.  If thread A is preempted in _wait()
+ * XXX after unlocking the mutex and before waiting, and if other
+ * XXX threads call signal or broadcast UINT_MAX times (exactly),
+ * XXX before thread A is scheduled again and calls futex_wait(),
+ * XXX then the signal will be lost.
+ */
+
+void futex_cond_init(futex_cond_t *c)
+{
+    c->value = 0;
+}
+
+int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec)
+{
+    if(msec == FUTEX_WAIT_INFINITE){
+        int oldvalue = c->value;
+        futex_mutex_unlock(m);
+        __futex_wait(&c->value, oldvalue, 0);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return 0;
+    } else {
+        int oldvalue = c->value;
+        struct timespec ts;        
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        futex_mutex_unlock(m);
+        const int err = __futex_wait(&c->value, oldvalue, &ts);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return err;
+    }
+}
+
+void futex_cond_signal(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, 1);
+}
+
+void futex_cond_broadcast(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, INT_MAX);
+}
+
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
new file mode 100644
index 0000000..dc89d15
--- /dev/null
+++ b/libs/utils/misc.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+//
+// Miscellaneous utility functions.
+//
+#include <utils/misc.h>
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+
+using namespace android;
+
+namespace android {
+
+/*
+ * Like strdup(), but uses C++ "new" operator instead of malloc.
+ */
+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;
+}
+
+/*
+ * Concatenate an argument vector.
+ */
+char* concatArgv(int argc, const char* const argv[])
+{
+    char* newStr = NULL;
+    int len, totalLen, posn, idx;
+
+    /*
+     * First, figure out the total length.
+     */
+    totalLen = idx = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            totalLen++;  // leave a space between args
+        totalLen += strlen(argv[idx]);
+        idx++;
+    }
+
+    /*
+     * Alloc the string.
+     */
+    newStr = new char[totalLen +1];
+    if (newStr == NULL)
+        return NULL;
+
+    /*
+     * Finally, allocate the string and copy data over.
+     */
+    idx = posn = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            newStr[posn++] = ' ';
+
+        len = strlen(argv[idx]);
+        memcpy(&newStr[posn], argv[idx], len);
+        posn += len;
+
+        idx++;
+    }
+
+    assert(posn == totalLen);
+    newStr[posn] = '\0';
+
+    return newStr;
+}
+
+/*
+ * Count the #of args in an argument vector.  Don't count the final NULL.
+ */
+int countArgv(const char* const argv[])
+{
+    int count = 0;
+
+    while (argv[count] != NULL)
+        count++;
+
+    return count;
+}
+
+
+#include <stdio.h>
+/*
+ * 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;
+}
+
+/*
+ * Round up to the next highest power of 2.
+ *
+ * Found on http://graphics.stanford.edu/~seander/bithacks.html.
+ */
+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;
+}
+
+}; // namespace android
+
diff --git a/libs/utils/ported.cpp b/libs/utils/ported.cpp
new file mode 100644
index 0000000..656e46f
--- /dev/null
+++ b/libs/utils/ported.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+//
+// Ports of standard functions that don't exist on a specific platform.
+//
+// Note these are NOT in the "android" namespace.
+//
+#include <utils/ported.h>
+
+#if defined(NEED_GETTIMEOFDAY) || defined(NEED_USLEEP)
+# include <sys/time.h>
+# include <windows.h>
+#endif
+
+
+#if defined(NEED_GETTIMEOFDAY)
+/*
+ * Replacement gettimeofday() for Windows environments (primarily MinGW).
+ *
+ * Ignores "tz".
+ */
+int gettimeofday(struct timeval* ptv, struct timezone* tz)
+{
+    long long nsTime;   // time in 100ns units since Jan 1 1601
+    FILETIME ft;
+
+    if (tz != NULL) {
+        // oh well
+    }
+
+    ::GetSystemTimeAsFileTime(&ft);
+    nsTime = (long long) ft.dwHighDateTime << 32 |
+             (long long) ft.dwLowDateTime;
+    // convert to time in usec since Jan 1 1970
+    ptv->tv_usec = (long) ((nsTime / 10LL) % 1000000LL);
+    ptv->tv_sec = (long) ((nsTime - 116444736000000000LL) / 10000000LL);
+
+    return 0;
+}
+#endif
+
+#if defined(NEED_USLEEP)
+//
+// Replacement usleep for Windows environments (primarily MinGW).
+//
+void usleep(unsigned long usec)
+{
+    // Win32 API function Sleep() takes milliseconds
+    ::Sleep((usec + 500) / 1000);
+}
+#endif
+
+#if 0 //defined(NEED_PIPE)
+//
+// Replacement pipe() command for MinGW
+//
+// The _O_NOINHERIT flag sets bInheritHandle to FALSE in the
+// SecurityAttributes argument to CreatePipe().  This means the handles
+// aren't inherited when a new process is created.  The examples I've seen
+// use it, possibly because there's a lot of junk going on behind the
+// scenes.  (I'm assuming "process" and "thread" are different here, so
+// we should be okay spinning up a thread.)  The recommended practice is
+// to dup() the descriptor you want the child to have.
+//
+// It appears that unnamed pipes can't do non-blocking ("overlapped") I/O.
+// You can't use select() either, since that only works on sockets.  The
+// Windows API calls that are useful here all operate on a HANDLE, not
+// an integer file descriptor, and I don't think you can get there from
+// here.  The "named pipe" stuff is insane.
+//
+int pipe(int filedes[2])
+{
+    return _pipe(filedes, 0, _O_BINARY | _O_NOINHERIT);
+}
+#endif
+
+#if defined(NEED_SETENV)
+/*
+ * MinGW lacks these.  For now, just stub them out so the code compiles.
+ */
+int setenv(const char* name, const char* value, int overwrite)
+{
+    return 0;
+}
+void unsetenv(const char* name)
+{
+}
+char* getenv(const char* name)
+{
+    return NULL;
+}
+#endif
