Merge "Set mActualScale when initialScale is set."
diff --git a/api/current.txt b/api/current.txt
index 559672f..46cf2af 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14392,7 +14392,7 @@
     method public static final void sendSignal(int, int);
     method public static final void setThreadPriority(int, int) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
     method public static final void setThreadPriority(int) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
-    method public static final boolean supportsProcesses();
+    method public static final deprecated boolean supportsProcesses();
     field public static final int BLUETOOTH_GID = 2000; // 0x7d0
     field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710
     field public static final int LAST_APPLICATION_UID = 99999; // 0x1869f
@@ -22740,7 +22740,7 @@
     method public void requestDisallowInterceptTouchEvent(boolean);
     method public boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public void requestTransparentRegion(android.view.View);
-    method protected void resetLayoutDirectionResolution();
+    method protected void resetResolvedLayoutDirection();
     method public void scheduleLayoutAnimation();
     method public void setAddStatesFromChildren(boolean);
     method public void setAlwaysDrawnWithCacheEnabled(boolean);
@@ -26417,7 +26417,7 @@
     method protected void onTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
-    method protected void resetLayoutDirectionResolution();
+    method protected void resetResolvedLayoutDirection();
     method public void setAllCaps(boolean);
     method public final void setAutoLinkMask(int);
     method public void setCompoundDrawablePadding(int);
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 152a7cb..f2be29f 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -82,35 +82,27 @@
     virtual void onStarted()
     {
         sp<ProcessState> proc = ProcessState::self();
-        if (proc->supportsProcesses()) {
-            LOGV("App process: starting thread pool.\n");
-            proc->startThreadPool();
-        }
+        LOGV("App process: starting thread pool.\n");
+        proc->startThreadPool();
 
         AndroidRuntime* ar = AndroidRuntime::getRuntime();
         ar->callMain(mClassName, mClass, mArgC, mArgV);
 
-        if (ProcessState::self()->supportsProcesses()) {
-            IPCThreadState::self()->stopProcess();
-        }
+        IPCThreadState::self()->stopProcess();
     }
 
     virtual void onZygoteInit()
     {
         sp<ProcessState> proc = ProcessState::self();
-        if (proc->supportsProcesses()) {
-            LOGV("App process: starting thread pool.\n");
-            proc->startThreadPool();
-        }
+        LOGV("App process: starting thread pool.\n");
+        proc->startThreadPool();
     }
 
     virtual void onExit(int code)
     {
         if (mClassName == NULL) {
             // if zygote
-            if (ProcessState::self()->supportsProcesses()) {
-                IPCThreadState::self()->stopProcess();
-            }
+            IPCThreadState::self()->stopProcess();
         }
 
         AndroidRuntime::onExit(code);
diff --git a/cmds/runtime/Android.mk b/cmds/runtime/Android.mk
deleted file mode 100644
index 6a72d10..0000000
--- a/cmds/runtime/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-ifeq ($(TARGET_SIMULATOR),true)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	ServiceManager.cpp \
-	SignalHandler.cpp \
-	main_runtime.cpp 
-
-LOCAL_SHARED_LIBRARIES := \
-	libutils \
-	libbinder \
-	libandroid_runtime \
-	libcutils \
-	libui \
-	libsystem_server \
-	libhardware_legacy
-
-LOCAL_C_INCLUDES := \
-	$(JNI_H_INCLUDE)
-
-ifeq ($(TARGET_OS),linux)
-	LOCAL_CFLAGS += -DXP_UNIX
-endif
-
-LOCAL_MODULE:= runtime
-
-include $(BUILD_EXECUTABLE)
-endif
diff --git a/cmds/runtime/MODULE_LICENSE_APACHE2 b/cmds/runtime/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/cmds/runtime/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/cmds/runtime/NOTICE b/cmds/runtime/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/cmds/runtime/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   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/cmds/runtime/ServiceManager.cpp b/cmds/runtime/ServiceManager.cpp
deleted file mode 100644
index b2bef07..0000000
--- a/cmds/runtime/ServiceManager.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-
-#define LOG_TAG "ServiceManager"
-
-#include "ServiceManager.h"
-#include "SignalHandler.h"
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-#include <binder/ProcessState.h>
-
-#include <private/utils/Static.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-namespace android {
-
-BServiceManager::BServiceManager()
-{
-}
-
-sp<IBinder> BServiceManager::getService(const String16& name) const
-{
-    AutoMutex _l(mLock);
-    ssize_t i = mServices.indexOfKey(name);
-    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
-    if (i >= 0) return mServices.valueAt(i);
-    return NULL;
-}
-
-sp<IBinder> BServiceManager::checkService(const String16& name) const
-{
-    AutoMutex _l(mLock);
-    ssize_t i = mServices.indexOfKey(name);
-    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
-    if (i >= 0) return mServices.valueAt(i);
-    return NULL;
-}
-
-status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
-{
-    AutoMutex _l(mLock);
-    LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
-    const ssize_t res = mServices.add(name, service);
-    if (res >= NO_ERROR) {
-        mChanged.broadcast();
-        return NO_ERROR;
-    }
-    return res;
-}
-
-Vector<String16> BServiceManager::listServices()
-{
-    Vector<String16> res;
-
-    AutoMutex _l(mLock);
-    const size_t N = mServices.size();
-    for (size_t i=0; i<N; i++) {
-        res.add(mServices.keyAt(i));
-    }
-
-    return res;
-}
-
-}; // namespace android
diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h
deleted file mode 100644
index 090ca6d..0000000
--- a/cmds/runtime/ServiceManager.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-#ifndef ANDROID_SERVICE_MANAGER_H
-#define ANDROID_SERVICE_MANAGER_H
-
-#include <binder/IServiceManager.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BServiceManager : public BnServiceManager
-{
-public:
-                                BServiceManager();
-    
-    virtual sp<IBinder>         getService( const String16& name) const;
-    virtual sp<IBinder>         checkService( const String16& name) const;
-    virtual status_t            addService( const String16& name,
-                                            const sp<IBinder>& service);
-    virtual Vector<String16>    listServices();
-
-    
-private:
-    mutable Mutex               mLock;
-    mutable Condition           mChanged;
-    sp<IPermissionController>   mPermissionController;
-    KeyedVector<String16, sp<IBinder> > mServices;
-};
-
-// ----------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_SERVICE_MANAGER_H
diff --git a/cmds/runtime/SignalHandler.cpp b/cmds/runtime/SignalHandler.cpp
deleted file mode 100644
index cccaabf..0000000
--- a/cmds/runtime/SignalHandler.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-
-#define LOG_TAG "SignalHandler"
-
-#include "SignalHandler.h"
-
-#include <utils/Atomic.h>
-#include <utils/Debug.h>
-#include <utils/Log.h>
-
-#include <errno.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-namespace android {
-
-class SignalHandler::ProcessThread : public Thread
-{
-public:
-    ProcessThread(SignalHandler& sh)
-        : Thread(false)
-        , mOwner(sh)
-    {
-    }
-
-    virtual bool threadLoop()
-    {
-        char buffer[32];
-        read(mOwner.mAvailMsg[0], buffer, sizeof(buffer));
-
-        LOGV("Signal command processing thread woke up!");
-
-        if (mOwner.mLostCommands) {
-            LOGE("Lost %d signals!", mOwner.mLostCommands);
-            mOwner.mLostCommands = 0;
-        }
-
-        int cur;
-        while ((cur=mOwner.mCommandBottom) != mOwner.mCommandTop) {
-            if (mOwner.mCommands[cur].filled == 0) {
-                LOGV("Command at %d is not yet filled", cur);
-                break;
-            }
-
-            LOGV("Processing command at %d, top is %d",
-                 cur, mOwner.mCommandTop);
-            processCommand(mOwner.mCommands[cur]);
-            mOwner.mCommands[cur].filled = 0;
-
-            int next = mOwner.mCommandBottom+1;
-            if (next >= COMMAND_QUEUE_SIZE) {
-                next = 0;
-            }
-
-            mOwner.mCommandBottom = next;
-        }
-
-        return true;
-    }
-
-    void processCommand(const CommandEntry& entry)
-    {
-        switch (entry.signum) {
-        case SIGCHLD: {
-            mOwner.mLock.lock();
-            ssize_t i = mOwner.mChildHandlers.indexOfKey(entry.info.si_pid);
-            ChildHandler ch;
-            if (i >= 0) {
-                ch = mOwner.mChildHandlers.valueAt(i);
-                mOwner.mChildHandlers.removeItemsAt(i);
-            }
-            mOwner.mLock.unlock();
-
-            LOGD("SIGCHLD: pid=%d, handle index=%d", entry.info.si_pid, i);
-
-            if (i >= 0) {
-                int res = waitpid(entry.info.si_pid, NULL, WNOHANG);
-                LOGW_IF(res == 0,
-                        "Received SIGCHLD, but pid %d is not yet stopped",
-                        entry.info.si_pid);
-                if (ch.handler) {
-                    ch.handler(entry.info.si_pid, ch.userData);
-                }
-            } else {
-                LOGW("Unhandled SIGCHLD for pid %d", entry.info.si_pid);
-            }
-        } break;
-        }
-    }
-
-    SignalHandler& mOwner;
-};
-
-
-Mutex SignalHandler::mInstanceLock;
-SignalHandler* SignalHandler::mInstance = NULL;
-
-status_t SignalHandler::setChildHandler(pid_t childPid,
-                                        int tag,
-                                        child_callback_t handler,
-                                        void* userData)
-{
-    SignalHandler* const self = getInstance();
-
-    self->mLock.lock();
-
-    // First make sure this child hasn't already exited.
-    pid_t res = waitpid(childPid, NULL, WNOHANG);
-    if (res != 0) {
-        if (res < 0) {
-            LOGW("setChildHandler waitpid of %d failed: %d (%s)",
-                 childPid, res, strerror(errno));
-        } else {
-            LOGW("setChildHandler waitpid of %d said %d already dead",
-                 childPid, res);
-        }
-
-        // Some kind of error...  just handle the exit now.
-        self->mLock.unlock();
-
-        if (handler) {
-            handler(childPid, userData);
-        }
-
-        // Return an error code -- 0 means it already exited.
-        return (status_t)res;
-    }
-
-    ChildHandler entry;
-    entry.childPid = childPid;
-    entry.tag = tag;
-    entry.handler = handler;
-    entry.userData = userData;
-
-    // Note: this replaces an existing entry for this pid, if there already
-    // is one.  This is the required behavior.
-    LOGD("setChildHandler adding pid %d, tag %d, handler %p, data %p",
-         childPid, tag, handler, userData);
-    self->mChildHandlers.add(childPid, entry);
-
-    self->mLock.unlock();
-
-    return NO_ERROR;
-}
-
-void SignalHandler::killAllChildren(int tag)
-{
-    SignalHandler* const self = getInstance();
-
-    AutoMutex _l (self->mLock);
-    const size_t N = self->mChildHandlers.size();
-    for (size_t i=0; i<N; i++) {
-        const ChildHandler& ch(self->mChildHandlers.valueAt(i));
-        if (tag == 0 || ch.tag == tag) {
-            const pid_t pid = ch.childPid;
-            LOGI("Killing child %d (tag %d)\n", pid, ch.tag);
-            kill(pid, SIGKILL);
-        }
-    }
-}
-
-SignalHandler::SignalHandler()
-    : mCommandTop(0)
-    , mCommandBottom(0)
-    , mLostCommands(0)
-{
-    memset(mCommands, 0, sizeof(mCommands));
-
-    int res = pipe(mAvailMsg);
-    LOGE_IF(res != 0, "Unable to create signal handler pipe: %s", strerror(errno));
-
-    mProcessThread = new ProcessThread(*this);
-    mProcessThread->run("SignalHandler", PRIORITY_HIGHEST);
-
-    struct sigaction sa;
-    memset(&sa, 0, sizeof(sa));
-    sa.sa_sigaction = sigAction;
-    sa.sa_flags = SA_NOCLDSTOP|SA_SIGINFO;
-    sigaction(SIGCHLD, &sa, NULL);
-}
-
-SignalHandler::~SignalHandler()
-{
-}
-
-SignalHandler* SignalHandler::getInstance()
-{
-    AutoMutex _l(mInstanceLock);
-    if (mInstance == NULL) {
-        mInstance = new SignalHandler();
-    }
-    return mInstance;
-}
-
-void SignalHandler::sigAction(int signum, siginfo_t* info, void*)
-{
-    static const char wakeupMsg[1] = { 0xff };
-
-    // If our signal handler is being called, then we know we have
-    // already initialized the SignalHandler class and thus mInstance
-    // is valid.
-    SignalHandler* const self = mInstance;
-
-    // XXX This is not safe!
-    #if 0
-    LOGV("Signal %d: signo=%d, errno=%d, code=%d, pid=%d\n",
-           signum,
-           info->si_signo, info->si_errno, info->si_code,
-           info->si_pid);
-    #endif
-
-    int32_t oldTop, newTop;
-
-    // Find the next command slot...
-    do {
-        oldTop = self->mCommandTop;
-
-        newTop = oldTop + 1;
-        if (newTop >= COMMAND_QUEUE_SIZE) {
-            newTop = 0;
-        }
-
-        if (newTop == self->mCommandBottom) {
-            // The buffer is filled up!  Ouch!
-            // XXX This is not safe!
-            #if 0
-            LOGE("Command buffer overflow!  newTop=%d\n", newTop);
-            #endif
-            android_atomic_add(1, &self->mLostCommands);
-            write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
-            return;
-        }
-    } while(android_atomic_cmpxchg(oldTop, newTop, &(self->mCommandTop)));
-
-    // Fill in the command data...
-    self->mCommands[oldTop].signum = signum;
-    self->mCommands[oldTop].info = *info;
-
-    // And now make this command available.
-    self->mCommands[oldTop].filled = 1;
-
-    // Wake up the processing thread.
-    write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
-}
-
-}; // namespace android
-
diff --git a/cmds/runtime/SignalHandler.h b/cmds/runtime/SignalHandler.h
deleted file mode 100644
index 7f4ef8e..0000000
--- a/cmds/runtime/SignalHandler.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-#ifndef ANDROID_SIGNAL_HANDLER_H
-#define ANDROID_SIGNAL_HANDLER_H
-
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-
-#include <signal.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-enum {
-    DEFAULT_PROCESS_TAG = 1
-};
-
-class SignalHandler
-{
-public:
-    typedef void (*child_callback_t)(pid_t child, void* userData);
-
-    /**
-     * Set a handler for when a child process exits.  By calling
-     * this, a waitpid() will be done when the child exits to remove
-     * it from the zombie state.  You can also optionally specify a
-     * handler to be called when the child exits.
-     * 
-     * If there is already a handler for this child process, it is
-     * replaced by this new handler.  In this case the old handler's
-     * function is not called.
-     * 
-     * @param childPid Process ID of child to watch.
-     * @param childTag User-defined tag for this child.  Must be
-     *                 greater than zero.
-     * @param handler If non-NULL, this will be called when the
-     *                child exits.  It may be called in either a
-     *                separate signal handling thread, or
-     *                immediately if the child has already exited.
-     * @param userData Propageted as-is to handler.
-     * 
-     * @return status_t NO_ERROR if all is well.
-     */
-    static status_t             setChildHandler(pid_t childPid,
-                                                int childTag = DEFAULT_PROCESS_TAG,
-                                                child_callback_t handler = NULL,
-                                                void* userData = NULL);
-
-    /**
-     * Kill all of the child processes for which we have a waiting
-     * handler, whose tag is the given value.  If tag is 0, all
-     * children are killed.
-     * 
-     * @param tag
-     */
-    static void                 killAllChildren(int tag = 0);
-
-private:
-                                SignalHandler();
-                                ~SignalHandler();
-
-    static SignalHandler*       getInstance();
-
-    static void                 sigAction(int, siginfo_t*, void*);
-
-    // --------------------------------------------------
-    // Shared state...  all of this is protected by mLock.
-    // --------------------------------------------------
-
-    mutable Mutex                       mLock;
-
-    struct ChildHandler
-    {
-        pid_t childPid;
-        int tag;
-        child_callback_t handler;
-        void* userData;
-    };
-    KeyedVector<pid_t, ChildHandler>    mChildHandlers;
-
-    // --------------------------------------------------
-    // Commmand queue...  data is inserted by the signal
-    // handler using atomic ops, and retrieved by the
-    // signal processing thread.  Because these are touched
-    // by the signal handler, no lock is used.
-    // --------------------------------------------------
-
-    enum {
-        COMMAND_QUEUE_SIZE = 64
-    };
-    struct CommandEntry
-    {
-        int filled;
-        int signum;
-        siginfo_t info;
-    };
-
-    // The top of the queue.  This is incremented atomically by the
-    // signal handler before placing a command in the queue.
-    volatile int32_t                    mCommandTop;
-
-    // The bottom of the queue.  Only modified by the processing
-    // thread; the signal handler reads it only to determine if the
-    // queue is full.
-    int32_t                             mCommandBottom;
-
-    // Incremented each time we receive a signal and don't have room
-    // for it on the command queue.
-    volatile int32_t                    mLostCommands;
-
-    // The command processing thread.
-    class ProcessThread;
-    sp<Thread>                          mProcessThread;
-
-    // Pipe used to tell command processing thread when new commands.
-    // are available.  The thread blocks on the read end, the signal
-    // handler writes when it enqueues new commands.
-    int                                 mAvailMsg[2];
-
-    // The commands.
-    CommandEntry                        mCommands[COMMAND_QUEUE_SIZE];
-
-    // --------------------------------------------------
-    // Singleton.
-    // --------------------------------------------------
-
-    static Mutex                        mInstanceLock;
-    static SignalHandler*               mInstance;
-};
-
-// ----------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_SIGNAL_HANDLER_H
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
deleted file mode 100644
index dbff095..0000000
--- a/cmds/runtime/main_runtime.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-// Main entry point for runtime.
-//
-
-#include "ServiceManager.h"
-#include "SignalHandler.h"
-
-#include <utils/threads.h>
-#include <utils/Errors.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <utils/Log.h>
-#include <cutils/zygote.h>
-
-#include <cutils/properties.h>
-
-#include <private/utils/Static.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-
-#include <android_runtime/AndroidRuntime.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <linux/capability.h>
-#include <linux/ioctl.h>
-#ifdef HAVE_ANDROID_OS
-# include <linux/android_alarm.h>
-#endif
-
-#undef LOG_TAG
-#define LOG_TAG "runtime"
-
-static const char* ZYGOTE_ARGV[] = {
-    "--setuid=1000",
-    "--setgid=1000",
-    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
-    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
-     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
-     * CAP_SYS_BOOT CAP_SYS_NICE
-     */
-    "--capabilities=96549920,96549920",
-    "--runtime-init",
-    "--nice-name=system_server",
-    "com.android.server.SystemServer"
-};
-
-using namespace android;
-
-extern "C" status_t system_init();
-
-enum {
-    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
-};
-
-extern Mutex gEventQMutex;
-extern Condition gEventQCondition;
-
-namespace android {
-
-extern void set_finish_init_func(void (*func)());
-
-
-/**
- * This class is used to kill this process (runtime) when the system_server dies.
- */
-class GrimReaper : public IBinder::DeathRecipient {
-public:
-    GrimReaper() { }
-
-    virtual void binderDied(const wp<IBinder>& who)
-    {
-        LOGI("Grim Reaper killing runtime...");
-        kill(getpid(), SIGKILL);
-    }
-};
-
-extern void QuickTests();
-
-/*
- * Print usage info.
- */
-static void usage(const char* argv0)
-{
-    fprintf(stderr,
-        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
-        "               [-j app-component] [-v app-verb] [-d app-data]\n"
-        "\n"
-        "-l: File to send log messages to\n"
-        "-n: Don't print to stdout/stderr\n"
-        "-s: Force single-process mode\n"
-        "-j: Custom home app component name\n"
-        "-v: Custom home app intent verb\n"
-        "-d: Custom home app intent data\n"
-    );
-    exit(1);
-}
-
-// Selected application to run.
-static const char* gInitialApplication = NULL;
-static const char* gInitialVerb = NULL;
-static const char* gInitialData = NULL;
-
-static void writeStringToParcel(Parcel& parcel, const char* str)
-{
-    if (str) {
-        parcel.writeString16(String16(str));
-    } else {
-        parcel.writeString16(NULL, 0);
-    }
-}
-
-/*
- * Starting point for program logic.
- *
- * Returns with an exit status code (0 on success, nonzero on error).
- */
-static int run(sp<ProcessState>& proc)
-{
-    // Temporary hack to call startRunning() on the activity manager.
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> am;
-    while ((am = sm->getService(String16("activity"))) == NULL) {
-        LOGI("Waiting for activity manager...");
-    }
-    Parcel data, reply;
-    // XXX Need to also supply a package name for this to work again.
-    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
-    // hardcoding it here avoids having to link with the full Activity Manager library
-    data.writeInterfaceToken(String16("android.app.IActivityManager"));
-    writeStringToParcel(data, NULL);
-    writeStringToParcel(data, gInitialApplication);
-    writeStringToParcel(data, gInitialVerb);
-    writeStringToParcel(data, gInitialData);
-LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
-    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
-
-    if (proc->supportsProcesses()) {
-        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
-        // initd will restart this process and bring the system back up.
-        sp<GrimReaper> grim = new GrimReaper();
-        am->linkToDeath(grim, grim.get(), 0);
-
-        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
-        // for the linkToDeath gets processed.
-        IPCThreadState::self()->joinThreadPool();
-    } else {
-        // Keep this thread running forever...
-        while (1) {
-            usleep(100000);
-        }
-    }
-    return 1;
-}
-
-
-};  // namespace android
-
-
-/*
- * Post-system-process initialization.
- *
- * This function continues initialization after the system process
- * has been initialized.  It needs to be separate because the system
- * initialization needs to care of starting the Android runtime if it is not
- * running in its own process, which doesn't return until the runtime is
- * being shut down.  So it will call back to here from inside of Dalvik,
- * to allow us to continue booting up.
- */
-static void finish_system_init(sp<ProcessState>& proc)
-{
-    // If we are running multiprocess, we now need to have the
-    // thread pool started here.  We don't do this in boot_init()
-    // because when running single process we need to start the
-    // thread pool after the Android runtime has been started (so
-    // the pool uses Dalvik threads).
-    if (proc->supportsProcesses()) {
-        proc->startThreadPool();
-    }
-}
-
-
-// This function can be used to enforce security to different
-// root contexts.  For now, we just give every access.
-static bool contextChecker(
-    const String16& name, const sp<IBinder>& caller, void* userData)
-{
-    return true;
-}
-
-/*
- * Initialization of boot services.
- *
- * This is where we perform initialization of all of our low-level
- * boot services.  Most importantly, here we become the context
- * manager and use that to publish the service manager that will provide
- * access to all other services.
- */
-static void boot_init()
-{
-    LOGI("Entered boot_init()!\n");
-
-    sp<ProcessState> proc(ProcessState::self());
-    LOGD("ProcessState: %p\n", proc.get());
-    proc->becomeContextManager(contextChecker, NULL);
-
-    if (proc->supportsProcesses()) {
-        LOGI("Binder driver opened.  Multiprocess enabled.\n");
-    } else {
-        LOGI("Binder driver not found.  Processes not supported.\n");
-    }
-
-    sp<BServiceManager> sm = new BServiceManager;
-    proc->setContextObject(sm);
-}
-
-/*
- * Redirect stdin/stdout/stderr to /dev/null.
- */
-static void redirectStdFds(void)
-{
-    int fd = open("/dev/null", O_RDWR, 0);
-    if (fd < 0) {
-        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
-    } else {
-        dup2(fd, 0);
-        dup2(fd, 1);
-        dup2(fd, 2);
-        close(fd);
-    }
-}
-
-static int hasDir(const char* dir)
-{
-    struct stat s;
-    int res = stat(dir, &s);
-    if (res == 0) {
-        return S_ISDIR(s.st_mode);
-    }
-    return 0;
-}
-
-static void validateTime()
-{
-#if HAVE_ANDROID_OS
-    int fd;
-    int res;
-    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
-    struct timespec ts;
-
-    fd = open("/dev/alarm", O_RDWR);
-    if(fd < 0) {
-        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
-        return;
-    }
-    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
-    if(res < 0) {
-        LOGW("Unable to read rtc, %s\n", strerror(errno));
-    }
-    else if(ts.tv_sec >= min_time) {
-        goto done;
-    }
-    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
-    ts.tv_sec = min_time;
-    ts.tv_nsec = 0;
-    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
-    if(res < 0) {
-        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
-    }
-done:
-    close(fd);
-#endif
-}
-
-#ifndef HAVE_ANDROID_OS
-class QuickRuntime : public AndroidRuntime
-{
-public:
-    QuickRuntime() {}
-
-    virtual void onStarted()
-    {
-        printf("QuickRuntime: onStarted\n");
-    }
-};
-#endif
-
-static status_t start_process(const char* name);
-
-static void restart_me(pid_t child, void* userData)
-{
-    start_process((const char*)userData);
-}
-
-static status_t start_process(const char* name)
-{
-    String8 path(name);
-    Vector<const char*> args;
-    String8 leaf(path.getPathLeaf());
-    String8 parentDir(path.getPathDir());
-    args.insertAt(leaf.string(), 0);
-    args.add(parentDir.string());
-    args.add(NULL);
-    pid_t child = fork();
-    if (child < 0) {
-        status_t err = errno;
-        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
-        return -errno;
-    } else if (child == 0) {
-        LOGI("Executing: %s", path.string());
-        execv(path.string(), const_cast<char**>(args.array()));
-        int err = errno;
-        LOGE("Exec failed: %s\n", strerror(err));
-        _exit(err);
-    } else {
-        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
-                restart_me, (void*)name);
-    }
-    return -errno;
-}
-
-/*
- * Application entry point.
- *
- * Parse arguments, set some values, and pass control off to Run().
- *
- * This is redefined to "SDL_main" on SDL simulator builds, and
- * "runtime_main" on wxWidgets builds.
- */
-extern "C"
-int main(int argc, char* const argv[])
-{
-    bool singleProcess = false;
-    const char* logFile = NULL;
-    int ic;
-    int result = 1;
-    pid_t systemPid;
-
-    sp<ProcessState> proc;
-
-#ifndef HAVE_ANDROID_OS
-    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
-    //setvbuf(stdout, NULL, _IONBF, 0);
-    //setvbuf(stderr, NULL, _IONBF, 0);
-
-    LOGI("commandline args:\n");
-    for (int i = 0; i < argc; i++)
-        LOGI("  %2d: '%s'\n", i, argv[i]);
-#endif
-
-    while (1) {
-        ic = getopt(argc, argv, "g:j:v:d:l:ns");
-        if (ic < 0)
-            break;
-
-        switch (ic) {
-        case 'g':
-            break;
-        case 'j':
-            gInitialApplication = optarg;
-            break;
-        case 'v':
-            gInitialVerb = optarg;
-            break;
-        case 'd':
-            gInitialData = optarg;
-            break;
-        case 'l':
-            logFile = optarg;
-            break;
-        case 'n':
-            redirectStdFds();
-            break;
-        case 's':
-            singleProcess = true;
-            break;
-        case '?':
-        default:
-            LOGE("runtime: unrecognized flag -%c\n", ic);
-            usage(argv[0]);
-            break;
-        }
-    }
-    if (optind < argc) {
-        LOGE("runtime: extra stuff: %s\n", argv[optind]);
-        usage(argv[0]);
-    }
-
-    if (singleProcess) {
-        ProcessState::setSingleProcess(true);
-    }
-
-    if (logFile != NULL) {
-        android_logToFile(NULL, logFile);
-    }
-
-    /*
-     * Set up ANDROID_* environment variables.
-     *
-     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
-     */
-    static const char* kSystemDir = "/system";
-    static const char* kDataDir = "/data";
-    static const char* kAppSubdir = "/app";
-    const char* out = NULL;
-#ifndef HAVE_ANDROID_OS
-    //out = getenv("ANDROID_PRODUCT_OUT");
-#endif
-    if (out == NULL)
-        out = "";
-
-    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
-    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
-
-    sprintf(systemDir, "%s%s", out, kSystemDir);
-    sprintf(dataDir, "%s%s", out, kDataDir);
-    setenv("ANDROID_ROOT", systemDir, 1);
-    setenv("ANDROID_DATA", dataDir, 1);
-
-    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
-    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
-
-    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
-        systemDir, assetDir, dataDir);
-    free(systemDir);
-    free(dataDir);
-
-#ifdef HAVE_ANDROID_OS
-    /* set up a process group for easier killing on the device */
-    setpgid(0, getpid());
-#endif
-
-    // Change to asset dir.  This is only necessary if we've changed to
-    // a different directory, but there's little harm in doing it regardless.
-    //
-    // Expecting assets to live in the current dir is not a great idea,
-    // because some of our code or one of our libraries could change the
-    // directory out from under us.  Preserve the behavior for now.
-    if (chdir(assetDir) != 0) {
-        LOGW("WARNING: could not change dir to '%s': %s\n",
-             assetDir, strerror(errno));
-    }
-    free(assetDir);
-
-#if 0
-    // Hack to keep libc from beating the filesystem to death.  It's
-    // hitting /etc/localtime frequently,
-    //
-    // This statement locks us into Pacific time.  We could do better,
-    // but there's not much point until we're sure that the library
-    // can't be changed to do more along the lines of what we want.
-#ifndef XP_WIN
-    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
-#endif
-#endif
-
-    /* track our progress through the boot sequence */
-    const int LOG_BOOT_PROGRESS_START = 3000;
-    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
-        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
-
-    validateTime();
-
-    proc = ProcessState::self();
-
-    boot_init();
-
-    /* If we are in multiprocess mode, have zygote spawn the system
-     * server process and call system_init(). If we are running in
-     * single process mode just call system_init() directly.
-     */
-    if (proc->supportsProcesses()) {
-        // If stdio logging is on, system_server should not inherit our stdio
-        // The dalvikvm instance will copy stdio to the log on its own
-        char propBuf[PROPERTY_VALUE_MAX];
-        bool logStdio = false;
-        property_get("log.redirect-stdio", propBuf, "");
-        logStdio = (strcmp(propBuf, "true") == 0);
-
-        zygote_run_oneshot((int)(!logStdio),
-                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
-                ZYGOTE_ARGV);
-
-        //start_process("/system/bin/mediaserver");
-
-    } else {
-#ifndef HAVE_ANDROID_OS
-        QuickRuntime* runt = new QuickRuntime();
-        runt->start("com/android/server/SystemServer",
-                    "" /* spontaneously fork system server from zygote */);
-#endif
-    }
-
-    //printf("+++ post-zygote\n");
-
-    finish_system_init(proc);
-    run(proc);
-
-bail:
-    if (proc != NULL) {
-        proc->setContextObject(NULL);
-    }
-
-    return 0;
-}
diff --git a/cmds/system_server/library/system_init.cpp b/cmds/system_server/library/system_init.cpp
index a19711e..59360d3 100644
--- a/cmds/system_server/library/system_init.cpp
+++ b/cmds/system_server/library/system_init.cpp
@@ -76,23 +76,6 @@
         SensorService::instantiate();
     }
 
-    // On the simulator, audioflinger et al don't get started the
-    // same way as on the device, and we need to start them here
-    if (!proc->supportsProcesses()) {
-
-        // Start the AudioFlinger
-        AudioFlinger::instantiate();
-
-        // Start the media playback service
-        MediaPlayerService::instantiate();
-
-        // Start the camera service
-        CameraService::instantiate();
-
-        // Start the audio policy service
-        AudioPolicyService::instantiate();
-    }
-
     // And now start the Android runtime.  We have to do this bit
     // of nastiness because the Android runtime initialization requires
     // some of the core system services to already be started.
@@ -117,14 +100,10 @@
     }
     env->CallStaticVoidMethod(clazz, methodId);
 
-    // If running in our own process, just go into the thread
-    // pool.  Otherwise, call the initialization finished
-    // func to let this process continue its initilization.
-    if (proc->supportsProcesses()) {
-        LOGI("System server: entering thread pool.\n");
-        ProcessState::self()->startThreadPool();
-        IPCThreadState::self()->joinThreadPool();
-        LOGI("System server: exiting thread pool.\n");
-    }
+    LOGI("System server: entering thread pool.\n");
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+    LOGI("System server: exiting thread pool.\n");
+
     return NO_ERROR;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index eee14fb..ee04729 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4093,11 +4093,6 @@
         });
     }
 
-    private final void detach()
-    {
-        sThreadLocal.set(null);
-    }
-
     public static final ActivityThread systemMain() {
         HardwareRenderer.disable();
         ActivityThread thread = new ActivityThread();
@@ -4105,10 +4100,9 @@
         return thread;
     }
 
-    public final void installSystemProviders(List providers) {
+    public final void installSystemProviders(List<ProviderInfo> providers) {
         if (providers != null) {
-            installContentProviders(mInitialApplication,
-                                    (List<ProviderInfo>)providers);
+            installContentProviders(mInitialApplication, providers);
         }
     }
 
@@ -4147,14 +4141,6 @@
 
         Looper.loop();
 
-        if (Process.supportsProcesses()) {
-            throw new RuntimeException("Main thread loop unexpectedly exited");
-        }
-
-        thread.detach();
-        String name = (thread.mInitialApplication != null)
-            ? thread.mInitialApplication.getPackageName()
-            : "<unknown>";
-        Slog.i(TAG, "Main thread of " + name + " is now exiting");
+        throw new RuntimeException("Main thread loop unexpectedly exited");
     }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 8749d3e..d2323e7 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1163,9 +1163,6 @@
             throw new IllegalArgumentException("permission is null");
         }
 
-        if (!Process.supportsProcesses()) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
         try {
             return ActivityManagerNative.getDefault().checkPermission(
                     permission, pid, uid);
@@ -1180,9 +1177,6 @@
             throw new IllegalArgumentException("permission is null");
         }
 
-        if (!Process.supportsProcesses()) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
         int pid = Binder.getCallingPid();
         if (pid != Process.myPid()) {
             return checkPermission(permission, pid,
@@ -1263,9 +1257,6 @@
 
     @Override
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
-        if (!Process.supportsProcesses()) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
         try {
             return ActivityManagerNative.getDefault().checkUriPermission(
                     uri, pid, uid, modeFlags);
@@ -1276,9 +1267,6 @@
 
     @Override
     public int checkCallingUriPermission(Uri uri, int modeFlags) {
-        if (!Process.supportsProcesses()) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
         int pid = Binder.getCallingPid();
         if (pid != Process.myPid()) {
             return checkUriPermission(uri, pid,
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 52efc07..0a01dcf 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -16,7 +16,6 @@
 
 package android.bluetooth;
 
-import android.annotation.SdkConstant;
 import android.content.Context;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
@@ -67,9 +66,6 @@
      */
     public static final int CHANNEL_TYPE_ANY = 12;
 
-    private final ArrayList<BluetoothHealthAppConfiguration> mAppConfigs =
-        new ArrayList<BluetoothHealthAppConfiguration>();
-
     /**
      * Register an application configuration that acts as a Health SINK.
      * This is the configuration that will be used to communicate with health devices
@@ -86,7 +82,7 @@
      * @return If true, callback will be called.
      */
     public boolean registerSinkAppConfiguration(String name, int dataType,
-            IBluetoothHealthCallback callback) {
+            BluetoothHealthCallback callback) {
         if (!isEnabled() || name == null) return false;
 
         if (DBG) log("registerSinkApplication(" + name + ":" + dataType + ")");
@@ -111,18 +107,18 @@
      * @hide
      */
     public boolean registerAppConfiguration(String name, int dataType, int role,
-            int channelType, IBluetoothHealthCallback callback) {
+            int channelType, BluetoothHealthCallback callback) {
         boolean result = false;
         if (!isEnabled() || !checkAppParam(name, role, channelType, callback)) return result;
 
         if (DBG) log("registerApplication(" + name + ":" + dataType + ")");
+        BluetoothHealthCallbackWrapper wrapper = new BluetoothHealthCallbackWrapper(callback);
         BluetoothHealthAppConfiguration config =
-                new BluetoothHealthAppConfiguration(name, dataType, role, channelType,
-                callback);
+                new BluetoothHealthAppConfiguration(name, dataType, role, channelType);
 
         if (mService != null) {
             try {
-                result = mService.registerAppConfiguration(config);
+                result = mService.registerAppConfiguration(config, wrapper);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
@@ -130,8 +126,6 @@
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
         }
-
-        if (result) mAppConfigs.add(config);
         return result;
     }
 
@@ -147,7 +141,7 @@
      */
     public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
         boolean result = false;
-        if (mService != null && isEnabled() && isValidAppConfig(config)) {
+        if (mService != null && isEnabled() && config != null) {
             try {
                 result = mService.unregisterAppConfiguration(config);
             } catch (RemoteException e) {
@@ -157,26 +151,26 @@
             Log.w(TAG, "Proxy not attached to service");
             if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
         }
-        if (result) mAppConfigs.remove(config);
+
         return result;
     }
 
     /**
      * Connect to a health device which has the {@link #SOURCE_ROLE}.
-     * This is an asynchrnous call. If this function returns true, the callback
+     * This is an asynchronous call. If this function returns true, the callback
      * associated with the application configuration will be called.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registed using
-     *        {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using
+     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @return If true, the callback associated with the application config will be called.
      */
     public boolean connectChannelToSource(BluetoothDevice device,
             BluetoothHealthAppConfiguration config) {
         if (mService != null && isEnabled() && isValidDevice(device) &&
-                isValidAppConfig(config)) {
+                config != null) {
             try {
                 return mService.connectChannelToSource(device, config);
             } catch (RemoteException e) {
@@ -197,15 +191,15 @@
      *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registed using
-     *        {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using
+     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @return If true, the callback associated with the application config will be called.
      * @hide
      */
     public boolean connectChannelToSink(BluetoothDevice device,
             BluetoothHealthAppConfiguration config, int channelType) {
         if (mService != null && isEnabled() && isValidDevice(device) &&
-                isValidAppConfig(config)) {
+                config != null) {
             try {
                 return mService.connectChannelToSink(device, config, channelType);
             } catch (RemoteException e) {
@@ -226,8 +220,8 @@
      *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device The remote Bluetooth device.
-     * @param config The application configuration which has been registed using
-     *        {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) }
+     * @param config The application configuration which has been registered using
+     *        {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) }
      * @param fd The file descriptor that was associated with the channel.
      * @return If true, the callback associated with the application config will be called.
      * @hide
@@ -235,7 +229,7 @@
     public boolean disconnectChannel(BluetoothDevice device,
             BluetoothHealthAppConfiguration config, ParcelFileDescriptor fd) {
         if (mService != null && isEnabled() && isValidDevice(device) &&
-                isValidAppConfig(config)) {
+                config != null) {
             try {
                 return mService.disconnectChannel(device, config, fd);
             } catch (RemoteException e) {
@@ -262,7 +256,7 @@
     public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
             BluetoothHealthAppConfiguration config) {
         if (mService != null && isEnabled() && isValidDevice(device) &&
-                isValidAppConfig(config)) {
+                config != null) {
             try {
                 return mService.getMainChannelFd(device, config);
             } catch (RemoteException e) {
@@ -290,6 +284,7 @@
      *               {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
      *               {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
      */
+    @Override
     public int getConnectionState(BluetoothDevice device) {
         if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
@@ -317,6 +312,7 @@
      * local adapter.
      * @return List of devices. The list will be empty on error.
      */
+    @Override
     public List<BluetoothDevice> getConnectedDevices() {
         if (mService != null && isEnabled()) {
             try {
@@ -348,6 +344,7 @@
      *              {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
      * @return List of devices. The list will be empty on error.
      */
+    @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (mService != null && isEnabled()) {
             try {
@@ -361,6 +358,27 @@
         return new ArrayList<BluetoothDevice>();
     }
 
+    private static class BluetoothHealthCallbackWrapper extends IBluetoothHealthCallback.Stub {
+        private BluetoothHealthCallback mCallback;
+
+        public BluetoothHealthCallbackWrapper(BluetoothHealthCallback callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
+                                                         int status) {
+            mCallback.onHealthAppConfigurationStatusChange(config, status);
+        }
+
+        @Override
+        public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
+                                       BluetoothDevice device, int prevState, int newState,
+                                       ParcelFileDescriptor fd) {
+            mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd);
+        }
+    }
+
      /** Health Channel Connection State - Disconnected */
     public static final int STATE_CHANNEL_DISCONNECTED  = 0;
     /** Health Channel Connection State - Connecting */
@@ -379,7 +397,6 @@
     /** Health App Configuration un-registration failure */
     public static final int APPLICATION_UNREGISTRATION_FAILURE = 3;
 
-    private Context mContext;
     private ServiceListener mServiceListener;
     private IBluetooth mService;
     BluetoothAdapter mAdapter;
@@ -420,14 +437,8 @@
         return false;
     }
 
-    private boolean isValidAppConfig(BluetoothHealthAppConfiguration config) {
-        if (!mAppConfigs.isEmpty() && mAppConfigs.contains(config)) return true;
-        log("Not a valid config: " + config);
-        return false;
-    }
-
     private boolean checkAppParam(String name, int role, int channelType,
-            IBluetoothHealthCallback callback) {
+            BluetoothHealthCallback callback) {
         if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE) ||
                 (channelType != CHANNEL_TYPE_RELIABLE &&
                 channelType != CHANNEL_TYPE_STREAMING &&
diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
index b87aea5..7020249 100644
--- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
+++ b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
@@ -17,7 +17,6 @@
 
 package android.bluetooth;
 
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -34,21 +33,18 @@
     private final int mDataType;
     private final int mRole;
     private final int mChannelType;
-    private final IBluetoothHealthCallback mCallback;
 
     /**
      * Constructor to register the SINK role
      *
      * @param name Friendly name associated with the application configuration
      * @param dataType Data Type of the remote Bluetooth Health device
-     * @param callback Callback associated with the application configuration.
      */
-    BluetoothHealthAppConfiguration(String name, int dataType, IBluetoothHealthCallback callback) {
+    BluetoothHealthAppConfiguration(String name, int dataType) {
         mName = name;
         mDataType = dataType;
         mRole = BluetoothHealth.SINK_ROLE;
         mChannelType = BluetoothHealth.CHANNEL_TYPE_ANY;
-        mCallback = callback;
     }
 
     /**
@@ -56,17 +52,15 @@
      *
      * @param name Friendly name associated with the application configuration
      * @param dataType Data Type of the remote Bluetooth Health device
-     * @param role {@link BluetoothHealth.SOURCE_ROLE} or
-     *                     {@link BluetoothHealth.SINK_ROLE}
-     * @param callback Callback associated with the application configuration.
+     * @param role {@link BluetoothHealth#SOURCE_ROLE} or
+     *                     {@link BluetoothHealth#SINK_ROLE}
      */
-    BluetoothHealthAppConfiguration(String name, int dataType, int role, int channelType,
-            IBluetoothHealthCallback callback) {
+    BluetoothHealthAppConfiguration(String name, int dataType, int role, int
+        channelType) {
         mName = name;
         mDataType = dataType;
         mRole = role;
         mChannelType = channelType;
-        mCallback = callback;
     }
 
     @Override
@@ -77,8 +71,7 @@
             return mName.equals(config.getName()) &&
                     mDataType == config.getDataType() &&
                     mRole == config.getRole() &&
-                    mChannelType == config.getChannelType() &&
-                    mCallback.equals(config.getCallback());
+                    mChannelType == config.getChannelType();
         }
         return false;
     }
@@ -90,7 +83,6 @@
         result = 31 * result + mDataType;
         result = 31 * result + mRole;
         result = 31 * result + mChannelType;
-        result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0);
         return result;
     }
 
@@ -98,9 +90,10 @@
     public String toString() {
         return "BluetoothHealthAppConfiguration [mName = " + mName +
             ",mDataType = " + mDataType + ", mRole = " + mRole + ",mChannelType = " +
-            mChannelType +  ",callback=" + mCallback +"]";
+            mChannelType + "]";
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -144,37 +137,31 @@
         return mChannelType;
     }
 
-    /**
-     * Return the callback associated with this application configuration.
-     *
-     * @return IBluetoothHealthCallback
-     */
-    public IBluetoothHealthCallback getCallback() {
-        return mCallback;
-    }
-
     public static final Parcelable.Creator<BluetoothHealthAppConfiguration> CREATOR =
         new Parcelable.Creator<BluetoothHealthAppConfiguration>() {
+        @Override
         public BluetoothHealthAppConfiguration createFromParcel(Parcel in) {
             String name = in.readString();
             int type = in.readInt();
             int role = in.readInt();
             int channelType = in.readInt();
-            IBluetoothHealthCallback callback =
-                IBluetoothHealthCallback.Stub.asInterface(in.readStrongBinder());
-            return new BluetoothHealthAppConfiguration(name, type, role, channelType,
-                    callback);
+            return new BluetoothHealthAppConfiguration(name, type, role,
+                channelType);
         }
+
+        @Override
         public BluetoothHealthAppConfiguration[] newArray(int size) {
             return new BluetoothHealthAppConfiguration[size];
         }
     };
 
+    @Override
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mName);
         out.writeInt(mDataType);
         out.writeInt(mRole);
         out.writeInt(mChannelType);
-        out.writeStrongInterface(mCallback);
     }
+
+
 }
diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java
new file mode 100644
index 0000000..0d11bb5
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHealthCallback.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.bluetooth;
+
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+/**
+ * This class is used for all the {@link BluetoothHealth} callbacks.
+ * @hide
+ */
+public abstract class BluetoothHealthCallback {
+
+    private static final String TAG = "BluetoothHealthCallback";
+
+    public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
+                                                int status) {
+        Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + " Status:" + status);
+    }
+
+    public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
+                                    BluetoothDevice device, int prevState, int newState,
+                                    ParcelFileDescriptor fd) {
+        Log.d(TAG, "onHealthChannelStateChange: " + config + " Device:" + device +
+            "PrevState:" + prevState + "NewState:" + newState + "FileDescriptor:" + fd);
+    }
+}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 6ca6c2e..183772d 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.bluetooth.IBluetoothCallback;
+import android.bluetooth.IBluetoothHealthCallback;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHealthAppConfiguration;
 import android.os.ParcelUuid;
@@ -102,7 +103,8 @@
     boolean disconnectPanDevice(in BluetoothDevice device);
 
     // HDP profile APIs
-    boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config);
+    boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config,
+        in IBluetoothHealthCallback callback);
     boolean unregisterAppConfiguration(in BluetoothHealthAppConfiguration config);
     boolean connectChannelToSource(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
     boolean connectChannelToSink(in BluetoothDevice device, in BluetoothHealthAppConfiguration config,
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 8a678d6..76534ef 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -38,8 +38,22 @@
     /** Bring the named network interface down. */
     public native static int disableInterface(String interfaceName);
 
-    /** Reset any sockets that are connected via the named interface. */
-    public native static int resetConnections(String interfaceName);
+    /** Setting bit 0 indicates reseting of IPv4 addresses required */
+    public static final int RESET_IPV4_ADDRESSES = 0x01;
+
+    /** Setting bit 1 indicates reseting of IPv4 addresses required */
+    public static final int RESET_IPV6_ADDRESSES = 0x02;
+
+    /** Reset all addresses */
+    public static final int RESET_ALL_ADDRESSES = RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES;
+
+    /**
+     * Reset IPv6 or IPv4 sockets that are connected via the named interface.
+     *
+     * @param interfaceName is the interface to reset
+     * @param mask {@see #RESET_IPV4_ADDRESSES} and {@see #RESET_IPV6_ADDRESSES}
+     */
+    public native static int resetConnections(String interfaceName, int mask);
 
     /**
      * Start the DHCP client daemon, in order to have it request addresses
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 3edd692..c0be664 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -86,9 +86,7 @@
     public static final void prepareMainLooper() {
         prepare();
         setMainLooper(myLooper());
-        if (Process.supportsProcesses()) {
-            myLooper().mQueue.mQuitAllowed = false;
-        }
+        myLooper().mQueue.mQuitAllowed = false;
     }
 
     private synchronized static void setMainLooper(Looper looper) {
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 673b187..269e50e 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -266,7 +266,8 @@
      * @param uid The user-id under which the process will run.
      * @param gid The group-id under which the process will run.
      * @param gids Additional group-ids associated with the process.
-     * @param enableDebugger True if debugging should be enabled for this process.
+     * @param debugFlags Additional flags.
+     * @param targetSdkVersion The target SDK version for the app.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * 
      * @return int If > 0 the pid of the new process; if 0 the process is
@@ -278,72 +279,17 @@
     public static final int start(final String processClass,
                                   final String niceName,
                                   int uid, int gid, int[] gids,
-                                  int debugFlags,
-                                  String[] zygoteArgs)
-    {
-        if (supportsProcesses()) {
-            try {
-                return startViaZygote(processClass, niceName, uid, gid, gids,
-                        debugFlags, zygoteArgs);
-            } catch (ZygoteStartFailedEx ex) {
-                Log.e(LOG_TAG,
-                        "Starting VM process through Zygote failed");
-                throw new RuntimeException(
-                        "Starting VM process through Zygote failed", ex);
-            }
-        } else {
-            // Running in single-process mode
-            
-            Runnable runnable = new Runnable() {
-                        public void run() {
-                            Process.invokeStaticMain(processClass);
-                        }
-            };
-            
-            // Thread constructors must not be called with null names (see spec). 
-            if (niceName != null) {
-                new Thread(runnable, niceName).start();
-            } else {
-                new Thread(runnable).start();
-            }
-            
-            return 0;
-        }
-    }
-    
-    /**
-     * Start a new process.  Don't supply a custom nice name.
-     * {@hide}
-     */
-    public static final int start(String processClass, int uid, int gid,
-            int[] gids, int debugFlags, String[] zygoteArgs) {
-        return start(processClass, "", uid, gid, gids, 
-                debugFlags, zygoteArgs);
-    }
-
-    private static void invokeStaticMain(String className) {
-        Class cl;
-        Object args[] = new Object[1];
-
-        args[0] = new String[0];     //this is argv
-   
+                                  int debugFlags, int targetSdkVersion,
+                                  String[] zygoteArgs) {
         try {
-            cl = Class.forName(className);
-            cl.getMethod("main", new Class[] { String[].class })
-                    .invoke(null, args);            
-        } catch (Exception ex) {
-            // can be: ClassNotFoundException,
-            // NoSuchMethodException, SecurityException,
-            // IllegalAccessException, IllegalArgumentException
-            // InvocationTargetException
-            // or uncaught exception from main()
-
-            Log.e(LOG_TAG, "Exception invoking static main on " 
-                    + className, ex);
-
-            throw new RuntimeException(ex);
+            return startViaZygote(processClass, niceName, uid, gid, gids,
+                    debugFlags, targetSdkVersion, zygoteArgs);
+        } catch (ZygoteStartFailedEx ex) {
+            Log.e(LOG_TAG,
+                    "Starting VM process through Zygote failed");
+            throw new RuntimeException(
+                    "Starting VM process through Zygote failed", ex);
         }
-
     }
 
     /** retry interval for opening a zygote socket */
@@ -500,7 +446,8 @@
      * @param gid a POSIX gid that the new process shuold setgid() to
      * @param gids null-ok; a list of supplementary group IDs that the
      * new process should setgroup() to.
-     * @param enableDebugger True if debugging should be enabled for this process.
+     * @param debugFlags Additional flags.
+     * @param targetSdkVersion The target SDK version for the app.
      * @param extraArgs Additional arguments to supply to the zygote process.
      * @return PID
      * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -509,7 +456,7 @@
                                   final String niceName,
                                   final int uid, final int gid,
                                   final int[] gids,
-                                  int debugFlags,
+                                  int debugFlags, int targetSdkVersion,
                                   String[] extraArgs)
                                   throws ZygoteStartFailedEx {
         int pid;
@@ -537,6 +484,7 @@
             if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                 argsForZygote.add("--enable-assert");
             }
+            argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
 
             //TODO optionally enable debuger
             //argsForZygote.add("--enable-debugger");
@@ -736,8 +684,13 @@
      * 
      * @return Returns true if the system can run in multiple processes, else
      * false if everything is running in a single process.
+     *
+     * @deprecated This method always returns true.  Do not use.
      */
-    public static final native boolean supportsProcesses();
+    @Deprecated
+    public static final boolean supportsProcesses() {
+        return true;
+    }
 
     /**
      * Set the out-of-memory badness adjustment for a process.
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index b721665..1af24f4a 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -114,7 +114,7 @@
      * @hide
      */
     public static void initServiceCache(Map<String, IBinder> cache) {
-        if (sCache.size() != 0 && Process.supportsProcesses()) {
+        if (sCache.size() != 0) {
             throw new IllegalStateException("setServiceCache may only be called once");
         }
         sCache.putAll(cache);
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 792e4c1..60900e1 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -34,6 +34,8 @@
     private final int mMtpReserveSpace;
     private final boolean mAllowMassStorage;
     private int mStorageId;
+    // maximum file size for the storage, or zero for no limit
+    private final long mMaxFileSize;
 
     // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
     // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
@@ -41,18 +43,20 @@
     public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
 
     public StorageVolume(String path, String description, boolean removable,
-            boolean emulated, int mtpReserveSpace, boolean allowMassStorage) {
+            boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize) {
         mPath = path;
         mDescription = description;
         mRemovable = removable;
         mEmulated = emulated;
         mMtpReserveSpace = mtpReserveSpace;
         mAllowMassStorage = allowMassStorage;
+        mMaxFileSize = maxFileSize;
     }
 
     // for parcelling only
     private StorageVolume(String path, String description, boolean removable,
-            boolean emulated, int mtpReserveSpace, int storageId, boolean allowMassStorage) {
+            boolean emulated, int mtpReserveSpace, int storageId,
+            boolean allowMassStorage, long maxFileSize) {
         mPath = path;
         mDescription = description;
         mRemovable = removable;
@@ -60,6 +64,7 @@
         mMtpReserveSpace = mtpReserveSpace;
         mAllowMassStorage = allowMassStorage;
         mStorageId = storageId;
+        mMaxFileSize = maxFileSize;
     }
 
     /**
@@ -142,6 +147,15 @@
         return mAllowMassStorage;
     }
 
+    /**
+     * Returns maximum file size for the volume, or zero if it is unbounded.
+     *
+     * @return maximum file size
+     */
+    public long getMaxFileSize() {
+        return mMaxFileSize;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof StorageVolume && mPath != null) {
@@ -171,9 +185,10 @@
             int storageId = in.readInt();
             int mtpReserveSpace = in.readInt();
             int allowMassStorage = in.readInt();
+            long maxFileSize = in.readLong();
             return new StorageVolume(path, description,
-                    removable == 1, emulated == 1,
-                    mtpReserveSpace, storageId, allowMassStorage == 1);
+                    removable == 1, emulated == 1, mtpReserveSpace,
+                    storageId, allowMassStorage == 1, maxFileSize);
         }
 
         public StorageVolume[] newArray(int size) {
@@ -193,5 +208,6 @@
         parcel.writeInt(mStorageId);
         parcel.writeInt(mMtpReserveSpace);
         parcel.writeInt(mAllowMassStorage ? 1 : 0);
+        parcel.writeLong(mMaxFileSize);
     }
 }
diff --git a/core/java/android/pim/EventRecurrence.java b/core/java/android/pim/EventRecurrence.java
deleted file mode 100644
index 128b697..0000000
--- a/core/java/android/pim/EventRecurrence.java
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * 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.
- */
-
-package android.pim;
-
-import android.text.TextUtils;
-import android.text.format.Time;
-import android.util.Log;
-import android.util.TimeFormatException;
-
-import java.util.Calendar;
-import java.util.HashMap;
-
-/**
- * Event recurrence utility functions.
- */
-public class EventRecurrence {
-    private static String TAG = "EventRecur";
-
-    public static final int SECONDLY = 1;
-    public static final int MINUTELY = 2;
-    public static final int HOURLY = 3;
-    public static final int DAILY = 4;
-    public static final int WEEKLY = 5;
-    public static final int MONTHLY = 6;
-    public static final int YEARLY = 7;
-
-    public static final int SU = 0x00010000;
-    public static final int MO = 0x00020000;
-    public static final int TU = 0x00040000;
-    public static final int WE = 0x00080000;
-    public static final int TH = 0x00100000;
-    public static final int FR = 0x00200000;
-    public static final int SA = 0x00400000;
-
-    public Time      startDate;     // set by setStartDate(), not parse()
-
-    public int       freq;          // SECONDLY, MINUTELY, etc.
-    public String    until;
-    public int       count;
-    public int       interval;
-    public int       wkst;          // SU, MO, TU, etc.
-
-    /* lists with zero entries may be null references */
-    public int[]     bysecond;
-    public int       bysecondCount;
-    public int[]     byminute;
-    public int       byminuteCount;
-    public int[]     byhour;
-    public int       byhourCount;
-    public int[]     byday;
-    public int[]     bydayNum;
-    public int       bydayCount;
-    public int[]     bymonthday;
-    public int       bymonthdayCount;
-    public int[]     byyearday;
-    public int       byyeardayCount;
-    public int[]     byweekno;
-    public int       byweeknoCount;
-    public int[]     bymonth;
-    public int       bymonthCount;
-    public int[]     bysetpos;
-    public int       bysetposCount;
-
-    /** maps a part string to a parser object */
-    private static HashMap<String,PartParser> sParsePartMap;
-    static {
-        sParsePartMap = new HashMap<String,PartParser>();
-        sParsePartMap.put("FREQ", new ParseFreq());
-        sParsePartMap.put("UNTIL", new ParseUntil());
-        sParsePartMap.put("COUNT", new ParseCount());
-        sParsePartMap.put("INTERVAL", new ParseInterval());
-        sParsePartMap.put("BYSECOND", new ParseBySecond());
-        sParsePartMap.put("BYMINUTE", new ParseByMinute());
-        sParsePartMap.put("BYHOUR", new ParseByHour());
-        sParsePartMap.put("BYDAY", new ParseByDay());
-        sParsePartMap.put("BYMONTHDAY", new ParseByMonthDay());
-        sParsePartMap.put("BYYEARDAY", new ParseByYearDay());
-        sParsePartMap.put("BYWEEKNO", new ParseByWeekNo());
-        sParsePartMap.put("BYMONTH", new ParseByMonth());
-        sParsePartMap.put("BYSETPOS", new ParseBySetPos());
-        sParsePartMap.put("WKST", new ParseWkst());
-    }
-
-    /* values for bit vector that keeps track of what we have already seen */
-    private static final int PARSED_FREQ = 1 << 0;
-    private static final int PARSED_UNTIL = 1 << 1;
-    private static final int PARSED_COUNT = 1 << 2;
-    private static final int PARSED_INTERVAL = 1 << 3;
-    private static final int PARSED_BYSECOND = 1 << 4;
-    private static final int PARSED_BYMINUTE = 1 << 5;
-    private static final int PARSED_BYHOUR = 1 << 6;
-    private static final int PARSED_BYDAY = 1 << 7;
-    private static final int PARSED_BYMONTHDAY = 1 << 8;
-    private static final int PARSED_BYYEARDAY = 1 << 9;
-    private static final int PARSED_BYWEEKNO = 1 << 10;
-    private static final int PARSED_BYMONTH = 1 << 11;
-    private static final int PARSED_BYSETPOS = 1 << 12;
-    private static final int PARSED_WKST = 1 << 13;
-
-    /** maps a FREQ value to an integer constant */
-    private static final HashMap<String,Integer> sParseFreqMap = new HashMap<String,Integer>();
-    static {
-        sParseFreqMap.put("SECONDLY", SECONDLY);
-        sParseFreqMap.put("MINUTELY", MINUTELY);
-        sParseFreqMap.put("HOURLY", HOURLY);
-        sParseFreqMap.put("DAILY", DAILY);
-        sParseFreqMap.put("WEEKLY", WEEKLY);
-        sParseFreqMap.put("MONTHLY", MONTHLY);
-        sParseFreqMap.put("YEARLY", YEARLY);
-    }
-
-    /** maps a two-character weekday string to an integer constant */
-    private static final HashMap<String,Integer> sParseWeekdayMap = new HashMap<String,Integer>();
-    static {
-        sParseWeekdayMap.put("SU", SU);
-        sParseWeekdayMap.put("MO", MO);
-        sParseWeekdayMap.put("TU", TU);
-        sParseWeekdayMap.put("WE", WE);
-        sParseWeekdayMap.put("TH", TH);
-        sParseWeekdayMap.put("FR", FR);
-        sParseWeekdayMap.put("SA", SA);
-    }
-
-    /** If set, allow lower-case recurrence rule strings.  Minor performance impact. */
-    private static final boolean ALLOW_LOWER_CASE = false;
-
-    /** If set, validate the value of UNTIL parts.  Minor performance impact. */
-    private static final boolean VALIDATE_UNTIL = false;
-
-    /** If set, require that only one of {UNTIL,COUNT} is present.  Breaks compat w/ old parser. */
-    private static final boolean ONLY_ONE_UNTIL_COUNT = false;
-
-
-    /**
-     * Thrown when a recurrence string provided can not be parsed according
-     * to RFC2445.
-     */
-    public static class InvalidFormatException extends RuntimeException {
-        InvalidFormatException(String s) {
-            super(s);
-        }
-    }
-
-
-    public void setStartDate(Time date) {
-        startDate = date;
-    }
-
-    /**
-     * Converts one of the Calendar.SUNDAY constants to the SU, MO, etc.
-     * constants.  btw, I think we should switch to those here too, to
-     * get rid of this function, if possible.
-     */
-    public static int calendarDay2Day(int day)
-    {
-        switch (day)
-        {
-            case Calendar.SUNDAY:
-                return SU;
-            case Calendar.MONDAY:
-                return MO;
-            case Calendar.TUESDAY:
-                return TU;
-            case Calendar.WEDNESDAY:
-                return WE;
-            case Calendar.THURSDAY:
-                return TH;
-            case Calendar.FRIDAY:
-                return FR;
-            case Calendar.SATURDAY:
-                return SA;
-            default:
-                throw new RuntimeException("bad day of week: " + day);
-        }
-    }
-
-    public static int timeDay2Day(int day)
-    {
-        switch (day)
-        {
-            case Time.SUNDAY:
-                return SU;
-            case Time.MONDAY:
-                return MO;
-            case Time.TUESDAY:
-                return TU;
-            case Time.WEDNESDAY:
-                return WE;
-            case Time.THURSDAY:
-                return TH;
-            case Time.FRIDAY:
-                return FR;
-            case Time.SATURDAY:
-                return SA;
-            default:
-                throw new RuntimeException("bad day of week: " + day);
-        }
-    }
-    public static int day2TimeDay(int day)
-    {
-        switch (day)
-        {
-            case SU:
-                return Time.SUNDAY;
-            case MO:
-                return Time.MONDAY;
-            case TU:
-                return Time.TUESDAY;
-            case WE:
-                return Time.WEDNESDAY;
-            case TH:
-                return Time.THURSDAY;
-            case FR:
-                return Time.FRIDAY;
-            case SA:
-                return Time.SATURDAY;
-            default:
-                throw new RuntimeException("bad day of week: " + day);
-        }
-    }
-
-    /**
-     * Converts one of the SU, MO, etc. constants to the Calendar.SUNDAY
-     * constants.  btw, I think we should switch to those here too, to
-     * get rid of this function, if possible.
-     */
-    public static int day2CalendarDay(int day)
-    {
-        switch (day)
-        {
-            case SU:
-                return Calendar.SUNDAY;
-            case MO:
-                return Calendar.MONDAY;
-            case TU:
-                return Calendar.TUESDAY;
-            case WE:
-                return Calendar.WEDNESDAY;
-            case TH:
-                return Calendar.THURSDAY;
-            case FR:
-                return Calendar.FRIDAY;
-            case SA:
-                return Calendar.SATURDAY;
-            default:
-                throw new RuntimeException("bad day of week: " + day);
-        }
-    }
-
-    /**
-     * Converts one of the internal day constants (SU, MO, etc.) to the
-     * two-letter string representing that constant.
-     *
-     * @param day one the internal constants SU, MO, etc.
-     * @return the two-letter string for the day ("SU", "MO", etc.)
-     *
-     * @throws IllegalArgumentException Thrown if the day argument is not one of
-     * the defined day constants.
-     */
-    private static String day2String(int day) {
-        switch (day) {
-        case SU:
-            return "SU";
-        case MO:
-            return "MO";
-        case TU:
-            return "TU";
-        case WE:
-            return "WE";
-        case TH:
-            return "TH";
-        case FR:
-            return "FR";
-        case SA:
-            return "SA";
-        default:
-            throw new IllegalArgumentException("bad day argument: " + day);
-        }
-    }
-
-    private static void appendNumbers(StringBuilder s, String label,
-                                        int count, int[] values)
-    {
-        if (count > 0) {
-            s.append(label);
-            count--;
-            for (int i=0; i<count; i++) {
-                s.append(values[i]);
-                s.append(",");
-            }
-            s.append(values[count]);
-        }
-    }
-
-    private void appendByDay(StringBuilder s, int i)
-    {
-        int n = this.bydayNum[i];
-        if (n != 0) {
-            s.append(n);
-        }
-
-        String str = day2String(this.byday[i]);
-        s.append(str);
-    }
-
-    @Override
-    public String toString()
-    {
-        StringBuilder s = new StringBuilder();
-
-        s.append("FREQ=");
-        switch (this.freq)
-        {
-            case SECONDLY:
-                s.append("SECONDLY");
-                break;
-            case MINUTELY:
-                s.append("MINUTELY");
-                break;
-            case HOURLY:
-                s.append("HOURLY");
-                break;
-            case DAILY:
-                s.append("DAILY");
-                break;
-            case WEEKLY:
-                s.append("WEEKLY");
-                break;
-            case MONTHLY:
-                s.append("MONTHLY");
-                break;
-            case YEARLY:
-                s.append("YEARLY");
-                break;
-        }
-
-        if (!TextUtils.isEmpty(this.until)) {
-            s.append(";UNTIL=");
-            s.append(until);
-        }
-
-        if (this.count != 0) {
-            s.append(";COUNT=");
-            s.append(this.count);
-        }
-
-        if (this.interval != 0) {
-            s.append(";INTERVAL=");
-            s.append(this.interval);
-        }
-
-        if (this.wkst != 0) {
-            s.append(";WKST=");
-            s.append(day2String(this.wkst));
-        }
-
-        appendNumbers(s, ";BYSECOND=", this.bysecondCount, this.bysecond);
-        appendNumbers(s, ";BYMINUTE=", this.byminuteCount, this.byminute);
-        appendNumbers(s, ";BYSECOND=", this.byhourCount, this.byhour);
-
-        // day
-        int count = this.bydayCount;
-        if (count > 0) {
-            s.append(";BYDAY=");
-            count--;
-            for (int i=0; i<count; i++) {
-                appendByDay(s, i);
-                s.append(",");
-            }
-            appendByDay(s, count);
-        }
-
-        appendNumbers(s, ";BYMONTHDAY=", this.bymonthdayCount, this.bymonthday);
-        appendNumbers(s, ";BYYEARDAY=", this.byyeardayCount, this.byyearday);
-        appendNumbers(s, ";BYWEEKNO=", this.byweeknoCount, this.byweekno);
-        appendNumbers(s, ";BYMONTH=", this.bymonthCount, this.bymonth);
-        appendNumbers(s, ";BYSETPOS=", this.bysetposCount, this.bysetpos);
-
-        return s.toString();
-    }
-
-    public boolean repeatsOnEveryWeekDay() {
-        if (this.freq != WEEKLY) {
-            return false;
-        }
-
-        int count = this.bydayCount;
-        if (count != 5) {
-            return false;
-        }
-
-        for (int i = 0 ; i < count ; i++) {
-            int day = byday[i];
-            if (day == SU || day == SA) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Determines whether this rule specifies a simple monthly rule by weekday, such as
-     * "FREQ=MONTHLY;BYDAY=3TU" (the 3rd Tuesday of every month).
-     * <p>
-     * Negative days, e.g. "FREQ=MONTHLY;BYDAY=-1TU" (the last Tuesday of every month),
-     * will cause "false" to be returned.
-     * <p>
-     * Rules that fire every week, such as "FREQ=MONTHLY;BYDAY=TU" (every Tuesday of every
-     * month) will cause "false" to be returned.  (Note these are usually expressed as
-     * WEEKLY rules, and hence are uncommon.)
-     *
-     * @return true if this rule is of the appropriate form
-     */
-    public boolean repeatsMonthlyOnDayCount() {
-        if (this.freq != MONTHLY) {
-            return false;
-        }
-
-        if (bydayCount != 1 || bymonthdayCount != 0) {
-            return false;
-        }
-
-        if (bydayNum[0] <= 0) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Determines whether two integer arrays contain identical elements.
-     * <p>
-     * The native implementation over-allocated the arrays (and may have stuff left over from
-     * a previous run), so we can't just check the arrays -- the separately-maintained count
-     * field also matters.  We assume that a null array will have a count of zero, and that the
-     * array can hold as many elements as the associated count indicates.
-     * <p>
-     * TODO: replace this with Arrays.equals() when the old parser goes away.
-     */
-    private static boolean arraysEqual(int[] array1, int count1, int[] array2, int count2) {
-        if (count1 != count2) {
-            return false;
-        }
-
-        for (int i = 0; i < count1; i++) {
-            if (array1[i] != array2[i])
-                return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof EventRecurrence)) {
-            return false;
-        }
-
-        EventRecurrence er = (EventRecurrence) obj;
-        return  (startDate == null ?
-                        er.startDate == null : Time.compare(startDate, er.startDate) == 0) &&
-                freq == er.freq &&
-                (until == null ? er.until == null : until.equals(er.until)) &&
-                count == er.count &&
-                interval == er.interval &&
-                wkst == er.wkst &&
-                arraysEqual(bysecond, bysecondCount, er.bysecond, er.bysecondCount) &&
-                arraysEqual(byminute, byminuteCount, er.byminute, er.byminuteCount) &&
-                arraysEqual(byhour, byhourCount, er.byhour, er.byhourCount) &&
-                arraysEqual(byday, bydayCount, er.byday, er.bydayCount) &&
-                arraysEqual(bydayNum, bydayCount, er.bydayNum, er.bydayCount) &&
-                arraysEqual(bymonthday, bymonthdayCount, er.bymonthday, er.bymonthdayCount) &&
-                arraysEqual(byyearday, byyeardayCount, er.byyearday, er.byyeardayCount) &&
-                arraysEqual(byweekno, byweeknoCount, er.byweekno, er.byweeknoCount) &&
-                arraysEqual(bymonth, bymonthCount, er.bymonth, er.bymonthCount) &&
-                arraysEqual(bysetpos, bysetposCount, er.bysetpos, er.bysetposCount);
-    }
-
-    @Override public int hashCode() {
-        // We overrode equals, so we must override hashCode().  Nobody seems to need this though.
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Resets parser-modified fields to their initial state.  Does not alter startDate.
-     * <p>
-     * The original parser always set all of the "count" fields, "wkst", and "until",
-     * essentially allowing the same object to be used multiple times by calling parse().
-     * It's unclear whether this behavior was intentional.  For now, be paranoid and
-     * preserve the existing behavior by resetting the fields.
-     * <p>
-     * We don't need to touch the integer arrays; they will either be ignored or
-     * overwritten.  The "startDate" field is not set by the parser, so we ignore it here.
-     */
-    private void resetFields() {
-        until = null;
-        freq = count = interval = bysecondCount = byminuteCount = byhourCount =
-            bydayCount = bymonthdayCount = byyeardayCount = byweeknoCount = bymonthCount =
-            bysetposCount = 0;
-    }
-
-    /**
-     * Parses an rfc2445 recurrence rule string into its component pieces.  Attempting to parse
-     * malformed input will result in an EventRecurrence.InvalidFormatException.
-     *
-     * @param recur The recurrence rule to parse (in un-folded form).
-     */
-    public void parse(String recur) {
-        /*
-         * From RFC 2445 section 4.3.10:
-         *
-         * recur = "FREQ"=freq *(
-         *       ; either UNTIL or COUNT may appear in a 'recur',
-         *       ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
-         *
-         *       ( ";" "UNTIL" "=" enddate ) /
-         *       ( ";" "COUNT" "=" 1*DIGIT ) /
-         *
-         *       ; the rest of these keywords are optional,
-         *       ; but MUST NOT occur more than once
-         *
-         *       ( ";" "INTERVAL" "=" 1*DIGIT )          /
-         *       ( ";" "BYSECOND" "=" byseclist )        /
-         *       ( ";" "BYMINUTE" "=" byminlist )        /
-         *       ( ";" "BYHOUR" "=" byhrlist )           /
-         *       ( ";" "BYDAY" "=" bywdaylist )          /
-         *       ( ";" "BYMONTHDAY" "=" bymodaylist )    /
-         *       ( ";" "BYYEARDAY" "=" byyrdaylist )     /
-         *       ( ";" "BYWEEKNO" "=" bywknolist )       /
-         *       ( ";" "BYMONTH" "=" bymolist )          /
-         *       ( ";" "BYSETPOS" "=" bysplist )         /
-         *       ( ";" "WKST" "=" weekday )              /
-         *       ( ";" x-name "=" text )
-         *       )
-         *
-         * Examples:
-         *   FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
-         *   FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8
-         *
-         * Strategy:
-         * (1) Split the string at ';' boundaries to get an array of rule "parts".
-         * (2) For each part, find substrings for left/right sides of '=' (name/value).
-         * (3) Call a <name>-specific parsing function to parse the <value> into an
-         *     output field.
-         *
-         * By keeping track of which names we've seen in a bit vector, we can verify the
-         * constraints indicated above (FREQ appears first, none of them appear more than once --
-         * though x-[name] would require special treatment), and we have either UNTIL or COUNT
-         * but not both.
-         *
-         * In general, RFC 2445 property names (e.g. "FREQ") and enumerations ("TU") must
-         * be handled in a case-insensitive fashion, but case may be significant for other
-         * properties.  We don't have any case-sensitive values in RRULE, except possibly
-         * for the custom "X-" properties, but we ignore those anyway.  Thus, we can trivially
-         * convert the entire string to upper case and then use simple comparisons.
-         *
-         * Differences from previous version:
-         * - allows lower-case property and enumeration values [optional]
-         * - enforces that FREQ appears first
-         * - enforces that only one of UNTIL and COUNT may be specified
-         * - allows (but ignores) X-* parts
-         * - improved validation on various values (e.g. UNTIL timestamps)
-         * - error messages are more specific
-         */
-
-        /* TODO: replace with "if (freq != 0) throw" if nothing requires this */
-        resetFields();
-
-        int parseFlags = 0;
-        String[] parts;
-        if (ALLOW_LOWER_CASE) {
-            parts = recur.toUpperCase().split(";");
-        } else {
-            parts = recur.split(";");
-        }
-        for (String part : parts) {
-            int equalIndex = part.indexOf('=');
-            if (equalIndex <= 0) {
-                /* no '=' or no LHS */
-                throw new InvalidFormatException("Missing LHS in " + part);
-            }
-
-            String lhs = part.substring(0, equalIndex);
-            String rhs = part.substring(equalIndex + 1);
-            if (rhs.length() == 0) {
-                throw new InvalidFormatException("Missing RHS in " + part);
-            }
-
-            /*
-             * In lieu of a "switch" statement that allows string arguments, we use a
-             * map from strings to parsing functions.
-             */
-            PartParser parser = sParsePartMap.get(lhs);
-            if (parser == null) {
-                if (lhs.startsWith("X-")) {
-                    //Log.d(TAG, "Ignoring custom part " + lhs);
-                    continue;
-                }
-                throw new InvalidFormatException("Couldn't find parser for " + lhs);
-            } else {
-                int flag = parser.parsePart(rhs, this);
-                if ((parseFlags & flag) != 0) {
-                    throw new InvalidFormatException("Part " + lhs + " was specified twice");
-                }
-                if (parseFlags == 0 && flag != PARSED_FREQ) {
-                    throw new InvalidFormatException("FREQ must be specified first");
-                }
-                parseFlags |= flag;
-            }
-        }
-
-        // If not specified, week starts on Monday.
-        if ((parseFlags & PARSED_WKST) == 0) {
-            wkst = MO;
-        }
-
-        // FREQ is mandatory.
-        if ((parseFlags & PARSED_FREQ) == 0) {
-            throw new InvalidFormatException("Must specify a FREQ value");
-        }
-
-        // Can't have both UNTIL and COUNT.
-        if ((parseFlags & (PARSED_UNTIL | PARSED_COUNT)) == (PARSED_UNTIL | PARSED_COUNT)) {
-            if (ONLY_ONE_UNTIL_COUNT) {
-                throw new InvalidFormatException("Must not specify both UNTIL and COUNT: " + recur);
-            } else {
-                Log.w(TAG, "Warning: rrule has both UNTIL and COUNT: " + recur);
-            }
-        }
-    }
-
-    /**
-     * Base class for the RRULE part parsers.
-     */
-    abstract static class PartParser {
-        /**
-         * Parses a single part.
-         *
-         * @param value The right-hand-side of the part.
-         * @param er The EventRecurrence into which the result is stored.
-         * @return A bit value indicating which part was parsed.
-         */
-        public abstract int parsePart(String value, EventRecurrence er);
-
-        /**
-         * Parses an integer, with range-checking.
-         *
-         * @param str The string to parse.
-         * @param minVal Minimum allowed value.
-         * @param maxVal Maximum allowed value.
-         * @param allowZero Is 0 allowed?
-         * @return The parsed value.
-         */
-        public static int parseIntRange(String str, int minVal, int maxVal, boolean allowZero) {
-            try {
-                if (str.charAt(0) == '+') {
-                    // Integer.parseInt does not allow a leading '+', so skip it manually.
-                    str = str.substring(1);
-                }
-                int val = Integer.parseInt(str);
-                if (val < minVal || val > maxVal || (val == 0 && !allowZero)) {
-                    throw new InvalidFormatException("Integer value out of range: " + str);
-                }
-                return val;
-            } catch (NumberFormatException nfe) {
-                throw new InvalidFormatException("Invalid integer value: " + str);
-            }
-        }
-
-        /**
-         * Parses a comma-separated list of integers, with range-checking.
-         *
-         * @param listStr The string to parse.
-         * @param minVal Minimum allowed value.
-         * @param maxVal Maximum allowed value.
-         * @param allowZero Is 0 allowed?
-         * @return A new array with values, sized to hold the exact number of elements.
-         */
-        public static int[] parseNumberList(String listStr, int minVal, int maxVal,
-                boolean allowZero) {
-            int[] values;
-
-            if (listStr.indexOf(",") < 0) {
-                // Common case: only one entry, skip split() overhead.
-                values = new int[1];
-                values[0] = parseIntRange(listStr, minVal, maxVal, allowZero);
-            } else {
-                String[] valueStrs = listStr.split(",");
-                int len = valueStrs.length;
-                values = new int[len];
-                for (int i = 0; i < len; i++) {
-                    values[i] = parseIntRange(valueStrs[i], minVal, maxVal, allowZero);
-                }
-            }
-            return values;
-        }
-   }
-
-    /** parses FREQ={SECONDLY,MINUTELY,...} */
-    private static class ParseFreq extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            Integer freq = sParseFreqMap.get(value);
-            if (freq == null) {
-                throw new InvalidFormatException("Invalid FREQ value: " + value);
-            }
-            er.freq = freq;
-            return PARSED_FREQ;
-        }
-    }
-    /** parses UNTIL=enddate, e.g. "19970829T021400" */
-    private static class ParseUntil extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            if (VALIDATE_UNTIL) {
-                try {
-                    // Parse the time to validate it.  The result isn't retained.
-                    Time until = new Time();
-                    until.parse(value);
-                } catch (TimeFormatException tfe) {
-                    throw new InvalidFormatException("Invalid UNTIL value: " + value);
-                }
-            }
-            er.until = value;
-            return PARSED_UNTIL;
-        }
-    }
-    /** parses COUNT=[non-negative-integer] */
-    private static class ParseCount extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            er.count = parseIntRange(value, 0, Integer.MAX_VALUE, true);
-            return PARSED_COUNT;
-        }
-    }
-    /** parses INTERVAL=[non-negative-integer] */
-    private static class ParseInterval extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            er.interval = parseIntRange(value, 1, Integer.MAX_VALUE, false);
-            return PARSED_INTERVAL;
-        }
-    }
-    /** parses BYSECOND=byseclist */
-    private static class ParseBySecond extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] bysecond = parseNumberList(value, 0, 59, true);
-            er.bysecond = bysecond;
-            er.bysecondCount = bysecond.length;
-            return PARSED_BYSECOND;
-        }
-    }
-    /** parses BYMINUTE=byminlist */
-    private static class ParseByMinute extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] byminute = parseNumberList(value, 0, 59, true);
-            er.byminute = byminute;
-            er.byminuteCount = byminute.length;
-            return PARSED_BYMINUTE;
-        }
-    }
-    /** parses BYHOUR=byhrlist */
-    private static class ParseByHour extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] byhour = parseNumberList(value, 0, 23, true);
-            er.byhour = byhour;
-            er.byhourCount = byhour.length;
-            return PARSED_BYHOUR;
-        }
-    }
-    /** parses BYDAY=bywdaylist, e.g. "1SU,-1SU" */
-    private static class ParseByDay extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] byday;
-            int[] bydayNum;
-            int bydayCount;
-
-            if (value.indexOf(",") < 0) {
-                /* only one entry, skip split() overhead */
-                bydayCount = 1;
-                byday = new int[1];
-                bydayNum = new int[1];
-                parseWday(value, byday, bydayNum, 0);
-            } else {
-                String[] wdays = value.split(",");
-                int len = wdays.length;
-                bydayCount = len;
-                byday = new int[len];
-                bydayNum = new int[len];
-                for (int i = 0; i < len; i++) {
-                    parseWday(wdays[i], byday, bydayNum, i);
-                }
-            }
-            er.byday = byday;
-            er.bydayNum = bydayNum;
-            er.bydayCount = bydayCount;
-            return PARSED_BYDAY;
-        }
-
-        /** parses [int]weekday, putting the pieces into parallel array entries */
-        private static void parseWday(String str, int[] byday, int[] bydayNum, int index) {
-            int wdayStrStart = str.length() - 2;
-            String wdayStr;
-
-            if (wdayStrStart > 0) {
-                /* number is included; parse it out and advance to weekday */
-                String numPart = str.substring(0, wdayStrStart);
-                int num = parseIntRange(numPart, -53, 53, false);
-                bydayNum[index] = num;
-                wdayStr = str.substring(wdayStrStart);
-            } else {
-                /* just the weekday string */
-                wdayStr = str;
-            }
-            Integer wday = sParseWeekdayMap.get(wdayStr);
-            if (wday == null) {
-                throw new InvalidFormatException("Invalid BYDAY value: " + str);
-            }
-            byday[index] = wday;
-        }
-    }
-    /** parses BYMONTHDAY=bymodaylist */
-    private static class ParseByMonthDay extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] bymonthday = parseNumberList(value, -31, 31, false);
-            er.bymonthday = bymonthday;
-            er.bymonthdayCount = bymonthday.length;
-            return PARSED_BYMONTHDAY;
-        }
-    }
-    /** parses BYYEARDAY=byyrdaylist */
-    private static class ParseByYearDay extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] byyearday = parseNumberList(value, -366, 366, false);
-            er.byyearday = byyearday;
-            er.byyeardayCount = byyearday.length;
-            return PARSED_BYYEARDAY;
-        }
-    }
-    /** parses BYWEEKNO=bywknolist */
-    private static class ParseByWeekNo extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] byweekno = parseNumberList(value, -53, 53, false);
-            er.byweekno = byweekno;
-            er.byweeknoCount = byweekno.length;
-            return PARSED_BYWEEKNO;
-        }
-    }
-    /** parses BYMONTH=bymolist */
-    private static class ParseByMonth extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] bymonth = parseNumberList(value, 1, 12, false);
-            er.bymonth = bymonth;
-            er.bymonthCount = bymonth.length;
-            return PARSED_BYMONTH;
-        }
-    }
-    /** parses BYSETPOS=bysplist */
-    private static class ParseBySetPos extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            int[] bysetpos = parseNumberList(value, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
-            er.bysetpos = bysetpos;
-            er.bysetposCount = bysetpos.length;
-            return PARSED_BYSETPOS;
-        }
-    }
-    /** parses WKST={SU,MO,...} */
-    private static class ParseWkst extends PartParser {
-        @Override public int parsePart(String value, EventRecurrence er) {
-            Integer wkst = sParseWeekdayMap.get(value);
-            if (wkst == null) {
-                throw new InvalidFormatException("Invalid WKST value: " + value);
-            }
-            er.wkst = wkst;
-            return PARSED_WKST;
-        }
-    }
-}
diff --git a/core/java/android/pim/ICalendar.java b/core/java/android/pim/ICalendar.java
deleted file mode 100644
index 58c5c63..0000000
--- a/core/java/android/pim/ICalendar.java
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * 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.
- */
-
-package android.pim;
-
-import android.util.Log;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.ArrayList;
-
-/**
- * Parses RFC 2445 iCalendar objects.
- */
-public class ICalendar {
-
-    private static final String TAG = "Sync";
-
-    // TODO: keep track of VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, VALARM
-    // components, by type field or by subclass?  subclass would allow us to
-    // enforce grammars.
-
-    /**
-     * Exception thrown when an iCalendar object has invalid syntax.
-     */
-    public static class FormatException extends Exception {
-        public FormatException() {
-            super();
-        }
-
-        public FormatException(String msg) {
-            super(msg);
-        }
-
-        public FormatException(String msg, Throwable cause) {
-            super(msg, cause);
-        }
-    }
-
-    /**
-     * A component within an iCalendar (VEVENT, VTODO, VJOURNAL, VFEEBUSY,
-     * VTIMEZONE, VALARM).
-     */
-    public static class Component {
-
-        // components
-        private static final String BEGIN = "BEGIN";
-        private static final String END = "END";
-        private static final String NEWLINE = "\n";
-        public static final String VCALENDAR = "VCALENDAR";
-        public static final String VEVENT = "VEVENT";
-        public static final String VTODO = "VTODO";
-        public static final String VJOURNAL = "VJOURNAL";
-        public static final String VFREEBUSY = "VFREEBUSY";
-        public static final String VTIMEZONE = "VTIMEZONE";
-        public static final String VALARM = "VALARM";
-
-        private final String mName;
-        private final Component mParent; // see if we can get rid of this
-        private LinkedList<Component> mChildren = null;
-        private final LinkedHashMap<String, ArrayList<Property>> mPropsMap =
-                new LinkedHashMap<String, ArrayList<Property>>();
-
-        /**
-         * Creates a new component with the provided name.
-         * @param name The name of the component.
-         */
-        public Component(String name, Component parent) {
-            mName = name;
-            mParent = parent;
-        }
-
-        /**
-         * Returns the name of the component.
-         * @return The name of the component.
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns the parent of this component.
-         * @return The parent of this component.
-         */
-        public Component getParent() {
-            return mParent;
-        }
-
-        /**
-         * Helper that lazily gets/creates the list of children.
-         * @return The list of children.
-         */
-        protected LinkedList<Component> getOrCreateChildren() {
-            if (mChildren == null) {
-                mChildren = new LinkedList<Component>();
-            }
-            return mChildren;
-        }
-
-        /**
-         * Adds a child component to this component.
-         * @param child The child component.
-         */
-        public void addChild(Component child) {
-            getOrCreateChildren().add(child);
-        }
-
-        /**
-         * Returns a list of the Component children of this component.  May be
-         * null, if there are no children.
-         *
-         * @return A list of the children.
-         */
-        public List<Component> getComponents() {
-            return mChildren;
-        }
-
-        /**
-         * Adds a Property to this component.
-         * @param prop
-         */
-        public void addProperty(Property prop) {
-            String name= prop.getName();
-            ArrayList<Property> props = mPropsMap.get(name);
-            if (props == null) {
-                props = new ArrayList<Property>();
-                mPropsMap.put(name, props);
-            }
-            props.add(prop);
-        }
-
-        /**
-         * Returns a set of the property names within this component.
-         * @return A set of property names within this component.
-         */
-        public Set<String> getPropertyNames() {
-            return mPropsMap.keySet();
-        }
-
-        /**
-         * Returns a list of properties with the specified name.  Returns null
-         * if there are no such properties.
-         * @param name The name of the property that should be returned.
-         * @return A list of properties with the requested name.
-         */
-        public List<Property> getProperties(String name) {
-            return mPropsMap.get(name);
-        }
-
-        /**
-         * Returns the first property with the specified name.  Returns null
-         * if there is no such property.
-         * @param name The name of the property that should be returned.
-         * @return The first property with the specified name.
-         */
-        public Property getFirstProperty(String name) {
-            List<Property> props = mPropsMap.get(name);
-            if (props == null || props.size() == 0) {
-                return null;
-            }
-            return props.get(0);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            toString(sb);
-            sb.append(NEWLINE);
-            return sb.toString();
-        }
-
-        /**
-         * Helper method that appends this component to a StringBuilder.  The
-         * caller is responsible for appending a newline at the end of the
-         * component.
-         */
-        public void toString(StringBuilder sb) {
-            sb.append(BEGIN);
-            sb.append(":");
-            sb.append(mName);
-            sb.append(NEWLINE);
-
-            // append the properties
-            for (String propertyName : getPropertyNames()) {
-                for (Property property : getProperties(propertyName)) {
-                    property.toString(sb);
-                    sb.append(NEWLINE);
-                }
-            }
-
-            // append the sub-components
-            if (mChildren != null) {
-                for (Component component : mChildren) {
-                    component.toString(sb);
-                    sb.append(NEWLINE);
-                }
-            }
-
-            sb.append(END);
-            sb.append(":");
-            sb.append(mName);
-        }
-    }
-
-    /**
-     * A property within an iCalendar component (e.g., DTSTART, DTEND, etc.,
-     * within a VEVENT).
-     */
-    public static class Property {
-        // properties
-        // TODO: do we want to list these here?  the complete list is long.
-        public static final String DTSTART = "DTSTART";
-        public static final String DTEND = "DTEND";
-        public static final String DURATION = "DURATION";
-        public static final String RRULE = "RRULE";
-        public static final String RDATE = "RDATE";
-        public static final String EXRULE = "EXRULE";
-        public static final String EXDATE = "EXDATE";
-        // ... need to add more.
-        
-        private final String mName;
-        private LinkedHashMap<String, ArrayList<Parameter>> mParamsMap =
-                new LinkedHashMap<String, ArrayList<Parameter>>();
-        private String mValue; // TODO: make this final?
-
-        /**
-         * Creates a new property with the provided name.
-         * @param name The name of the property.
-         */
-        public Property(String name) {
-            mName = name;
-        }
-
-        /**
-         * Creates a new property with the provided name and value.
-         * @param name The name of the property.
-         * @param value The value of the property.
-         */
-        public Property(String name, String value) {
-            mName = name;
-            mValue = value;
-        }
-
-        /**
-         * Returns the name of the property.
-         * @return The name of the property.
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns the value of this property.
-         * @return The value of this property.
-         */
-        public String getValue() {
-            return mValue;
-        }
-
-        /**
-         * Sets the value of this property.
-         * @param value The desired value for this property.
-         */
-        public void setValue(String value) {
-            mValue = value;
-        }        
-
-        /**
-         * Adds a {@link Parameter} to this property.
-         * @param param The parameter that should be added.
-         */
-        public void addParameter(Parameter param) {
-            ArrayList<Parameter> params = mParamsMap.get(param.name);
-            if (params == null) {
-                params = new ArrayList<Parameter>();
-                mParamsMap.put(param.name, params);
-            }
-            params.add(param);
-        }
-
-        /**
-         * Returns the set of parameter names for this property.
-         * @return The set of parameter names for this property.
-         */
-        public Set<String> getParameterNames() {
-            return mParamsMap.keySet();
-        }
-
-        /**
-         * Returns the list of parameters with the specified name.  May return
-         * null if there are no such parameters.
-         * @param name The name of the parameters that should be returned.
-         * @return The list of parameters with the specified name.
-         */
-        public List<Parameter> getParameters(String name) {
-            return mParamsMap.get(name);
-        }
-
-        /**
-         * Returns the first parameter with the specified name.  May return
-         * nll if there is no such parameter.
-         * @param name The name of the parameter that should be returned.
-         * @return The first parameter with the specified name.
-         */
-        public Parameter getFirstParameter(String name) {
-            ArrayList<Parameter> params = mParamsMap.get(name);
-            if (params == null || params.size() == 0) {
-                return null;
-            }
-            return params.get(0);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            toString(sb);
-            return sb.toString();
-        }
-
-        /**
-         * Helper method that appends this property to a StringBuilder.  The
-         * caller is responsible for appending a newline after this property.
-         */
-        public void toString(StringBuilder sb) {
-            sb.append(mName);
-            Set<String> parameterNames = getParameterNames();
-            for (String parameterName : parameterNames) {
-                for (Parameter param : getParameters(parameterName)) {
-                    sb.append(";");
-                    param.toString(sb);
-                }
-            }
-            sb.append(":");
-            sb.append(mValue);
-        }
-    }
-
-    /**
-     * A parameter defined for an iCalendar property.
-     */
-    // TODO: make this a proper class rather than a struct?
-    public static class Parameter {
-        public String name;
-        public String value;
-
-        /**
-         * Creates a new empty parameter.
-         */
-        public Parameter() {
-        }
-
-        /**
-         * Creates a new parameter with the specified name and value.
-         * @param name The name of the parameter.
-         * @param value The value of the parameter.
-         */
-        public Parameter(String name, String value) {
-            this.name = name;
-            this.value = value;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            toString(sb);
-            return sb.toString();
-        }
-
-        /**
-         * Helper method that appends this parameter to a StringBuilder.
-         */
-        public void toString(StringBuilder sb) {
-            sb.append(name);
-            sb.append("=");
-            sb.append(value);
-        }
-    }
-
-    private static final class ParserState {
-        // public int lineNumber = 0;
-        public String line; // TODO: just point to original text
-        public int index;
-    }
-
-    // use factory method
-    private ICalendar() {
-    }
-
-    // TODO: get rid of this -- handle all of the parsing in one pass through
-    // the text.
-    private static String normalizeText(String text) {
-        // it's supposed to be \r\n, but not everyone does that
-        text = text.replaceAll("\r\n", "\n");
-        text = text.replaceAll("\r", "\n");
-
-        // we deal with line folding, by replacing all "\n " strings
-        // with nothing.  The RFC specifies "\r\n " to be folded, but
-        // we handle "\n " and "\r " too because we can get those.
-        text = text.replaceAll("\n ", "");
-
-        return text;
-    }
-
-    /**
-     * Parses text into an iCalendar component.  Parses into the provided
-     * component, if not null, or parses into a new component.  In the latter
-     * case, expects a BEGIN as the first line.  Returns the provided or newly
-     * created top-level component.
-     */
-    // TODO: use an index into the text, so we can make this a recursive
-    // function?
-    private static Component parseComponentImpl(Component component,
-                                                String text)
-            throws FormatException {
-        Component current = component;
-        ParserState state = new ParserState();
-        state.index = 0;
-
-        // split into lines
-        String[] lines = text.split("\n");
-
-        // each line is of the format:
-        // name *(";" param) ":" value
-        for (String line : lines) {
-            try {
-                current = parseLine(line, state, current);
-                // if the provided component was null, we will return the root
-                // NOTE: in this case, if the first line is not a BEGIN, a
-                // FormatException will get thrown.   
-                if (component == null) {
-                    component = current;
-                }
-            } catch (FormatException fe) {
-                if (false) {
-                    Log.v(TAG, "Cannot parse " + line, fe);
-                }
-                // for now, we ignore the parse error.  Google Calendar seems
-                // to be emitting some misformatted iCalendar objects.
-            }
-            continue;
-        }
-        return component;
-    }
-
-    /**
-     * Parses a line into the provided component.  Creates a new component if
-     * the line is a BEGIN, adding the newly created component to the provided
-     * parent.  Returns whatever component is the current one (to which new
-     * properties will be added) in the parse.
-     */
-    private static Component parseLine(String line, ParserState state,
-                                       Component component)
-            throws FormatException {
-        state.line = line;
-        int len = state.line.length();
-
-        // grab the name
-        char c = 0;
-        for (state.index = 0; state.index < len; ++state.index) {
-            c = line.charAt(state.index);
-            if (c == ';' || c == ':') {
-                break;
-            }
-        }
-        String name = line.substring(0, state.index);
-
-        if (component == null) {
-            if (!Component.BEGIN.equals(name)) {
-                throw new FormatException("Expected BEGIN");
-            }
-        }
-
-        Property property;
-        if (Component.BEGIN.equals(name)) {
-            // start a new component
-            String componentName = extractValue(state);
-            Component child = new Component(componentName, component);
-            if (component != null) {
-                component.addChild(child);
-            }
-            return child;
-        } else if (Component.END.equals(name)) {
-            // finish the current component
-            String componentName = extractValue(state);
-            if (component == null ||
-                    !componentName.equals(component.getName())) {
-                throw new FormatException("Unexpected END " + componentName);
-            }
-            return component.getParent();
-        } else {
-            property = new Property(name);
-        }
-
-        if (c == ';') {
-            Parameter parameter = null;
-            while ((parameter = extractParameter(state)) != null) {
-                property.addParameter(parameter);
-            }
-        }
-        String value = extractValue(state);
-        property.setValue(value);
-        component.addProperty(property);
-        return component;
-    }
-
-    /**
-     * Extracts the value ":..." on the current line.  The first character must
-     * be a ':'.
-     */
-    private static String extractValue(ParserState state)
-            throws FormatException {
-        String line = state.line;
-        if (state.index >= line.length() || line.charAt(state.index) != ':') {
-            throw new FormatException("Expected ':' before end of line in "
-                    + line);
-        }
-        String value = line.substring(state.index + 1);
-        state.index = line.length() - 1;
-        return value;
-    }
-
-    /**
-     * Extracts the next parameter from the line, if any.  If there are no more
-     * parameters, returns null.
-     */
-    private static Parameter extractParameter(ParserState state)
-            throws FormatException {
-        String text = state.line;
-        int len = text.length();
-        Parameter parameter = null;
-        int startIndex = -1;
-        int equalIndex = -1;
-        while (state.index < len) {
-            char c = text.charAt(state.index);
-            if (c == ':') {
-                if (parameter != null) {
-                    if (equalIndex == -1) {
-                        throw new FormatException("Expected '=' within "
-                                + "parameter in " + text);
-                    }
-                    parameter.value = text.substring(equalIndex + 1,
-                                                     state.index);
-                }
-                return parameter; // may be null
-            } else if (c == ';') {
-                if (parameter != null) {
-                    if (equalIndex == -1) {
-                        throw new FormatException("Expected '=' within "
-                                + "parameter in " + text);
-                    }
-                    parameter.value = text.substring(equalIndex + 1,
-                                                     state.index);
-                    return parameter;
-                } else {
-                    parameter = new Parameter();
-                    startIndex = state.index;
-                }
-            } else if (c == '=') {
-                equalIndex = state.index;
-                if ((parameter == null) || (startIndex == -1)) {
-                    throw new FormatException("Expected ';' before '=' in "
-                            + text);
-                }
-                parameter.name = text.substring(startIndex + 1, equalIndex);
-            } else if (c == '"') {
-                if (parameter == null) {
-                    throw new FormatException("Expected parameter before '\"' in " + text);
-                }
-                if (equalIndex == -1) {
-                    throw new FormatException("Expected '=' within parameter in " + text);
-                }
-                if (state.index > equalIndex + 1) {
-                    throw new FormatException("Parameter value cannot contain a '\"' in " + text);
-                }
-                final int endQuote = text.indexOf('"', state.index + 1);
-                if (endQuote < 0) {
-                    throw new FormatException("Expected closing '\"' in " + text);
-                }
-                parameter.value = text.substring(state.index + 1, endQuote);
-                state.index = endQuote + 1;
-                return parameter;
-            }
-            ++state.index;
-        }
-        throw new FormatException("Expected ':' before end of line in " + text);
-    }
-
-    /**
-     * Parses the provided text into an iCalendar object.  The top-level
-     * component must be of type VCALENDAR.
-     * @param text The text to be parsed.
-     * @return The top-level VCALENDAR component.
-     * @throws FormatException Thrown if the text could not be parsed into an
-     * iCalendar VCALENDAR object.
-     */
-    public static Component parseCalendar(String text) throws FormatException {
-        Component calendar = parseComponent(null, text);
-        if (calendar == null || !Component.VCALENDAR.equals(calendar.getName())) {
-            throw new FormatException("Expected " + Component.VCALENDAR);
-        }
-        return calendar;
-    }
-
-    /**
-     * Parses the provided text into an iCalendar event.  The top-level
-     * component must be of type VEVENT.
-     * @param text The text to be parsed.
-     * @return The top-level VEVENT component.
-     * @throws FormatException Thrown if the text could not be parsed into an
-     * iCalendar VEVENT.
-     */
-    public static Component parseEvent(String text) throws FormatException {
-        Component event = parseComponent(null, text);
-        if (event == null || !Component.VEVENT.equals(event.getName())) {
-            throw new FormatException("Expected " + Component.VEVENT);
-        }
-        return event;
-    }
-
-    /**
-     * Parses the provided text into an iCalendar component.
-     * @param text The text to be parsed.
-     * @return The top-level component.
-     * @throws FormatException Thrown if the text could not be parsed into an
-     * iCalendar component.
-     */
-    public static Component parseComponent(String text) throws FormatException {
-        return parseComponent(null, text);
-    }
-
-    /**
-     * Parses the provided text, adding to the provided component.
-     * @param component The component to which the parsed iCalendar data should
-     * be added.
-     * @param text The text to be parsed.
-     * @return The top-level component.
-     * @throws FormatException Thrown if the text could not be parsed as an
-     * iCalendar object.
-     */
-    public static Component parseComponent(Component component, String text)
-        throws FormatException {
-        text = normalizeText(text);
-        return parseComponentImpl(component, text);
-    }
-}
diff --git a/core/java/android/pim/RecurrenceSet.java b/core/java/android/pim/RecurrenceSet.java
deleted file mode 100644
index b7fb320..0000000
--- a/core/java/android/pim/RecurrenceSet.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * 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.
- */
-
-package android.pim;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.provider.CalendarContract;
-import android.text.TextUtils;
-import android.text.format.Time;
-import android.util.Log;
-
-import java.util.List;
-import java.util.regex.Pattern;
-
-/**
- * Basic information about a recurrence, following RFC 2445 Section 4.8.5.
- * Contains the RRULEs, RDATE, EXRULEs, and EXDATE properties.
- */
-public class RecurrenceSet {
-
-    private final static String TAG = "CalendarProvider";
-
-    private final static String RULE_SEPARATOR = "\n";
-    private final static String FOLDING_SEPARATOR = "\n ";
-
-    // TODO: make these final?
-    public EventRecurrence[] rrules = null;
-    public long[] rdates = null;
-    public EventRecurrence[] exrules = null;
-    public long[] exdates = null;
-
-    /**
-     * Creates a new RecurrenceSet from information stored in the
-     * events table in the CalendarProvider.
-     * @param values The values retrieved from the Events table.
-     */
-    public RecurrenceSet(ContentValues values)
-            throws EventRecurrence.InvalidFormatException {
-        String rruleStr = values.getAsString(CalendarContract.Events.RRULE);
-        String rdateStr = values.getAsString(CalendarContract.Events.RDATE);
-        String exruleStr = values.getAsString(CalendarContract.Events.EXRULE);
-        String exdateStr = values.getAsString(CalendarContract.Events.EXDATE);
-        init(rruleStr, rdateStr, exruleStr, exdateStr);
-    }
-
-    /**
-     * Creates a new RecurrenceSet from information stored in a database
-     * {@link Cursor} pointing to the events table in the
-     * CalendarProvider.  The cursor must contain the RRULE, RDATE, EXRULE,
-     * and EXDATE columns.
-     *
-     * @param cursor The cursor containing the RRULE, RDATE, EXRULE, and EXDATE
-     * columns.
-     */
-    public RecurrenceSet(Cursor cursor)
-            throws EventRecurrence.InvalidFormatException {
-        int rruleColumn = cursor.getColumnIndex(CalendarContract.Events.RRULE);
-        int rdateColumn = cursor.getColumnIndex(CalendarContract.Events.RDATE);
-        int exruleColumn = cursor.getColumnIndex(CalendarContract.Events.EXRULE);
-        int exdateColumn = cursor.getColumnIndex(CalendarContract.Events.EXDATE);
-        String rruleStr = cursor.getString(rruleColumn);
-        String rdateStr = cursor.getString(rdateColumn);
-        String exruleStr = cursor.getString(exruleColumn);
-        String exdateStr = cursor.getString(exdateColumn);
-        init(rruleStr, rdateStr, exruleStr, exdateStr);
-    }
-
-    public RecurrenceSet(String rruleStr, String rdateStr,
-                  String exruleStr, String exdateStr)
-            throws EventRecurrence.InvalidFormatException {
-        init(rruleStr, rdateStr, exruleStr, exdateStr);
-    }
-
-    private void init(String rruleStr, String rdateStr,
-                      String exruleStr, String exdateStr)
-            throws EventRecurrence.InvalidFormatException {
-        if (!TextUtils.isEmpty(rruleStr) || !TextUtils.isEmpty(rdateStr)) {
-
-            if (!TextUtils.isEmpty(rruleStr)) {
-                String[] rruleStrs = rruleStr.split(RULE_SEPARATOR);
-                rrules = new EventRecurrence[rruleStrs.length];
-                for (int i = 0; i < rruleStrs.length; ++i) {
-                    EventRecurrence rrule = new EventRecurrence();
-                    rrule.parse(rruleStrs[i]);
-                    rrules[i] = rrule;
-                }
-            }
-
-            if (!TextUtils.isEmpty(rdateStr)) {
-                rdates = parseRecurrenceDates(rdateStr);
-            }
-
-            if (!TextUtils.isEmpty(exruleStr)) {
-                String[] exruleStrs = exruleStr.split(RULE_SEPARATOR);
-                exrules = new EventRecurrence[exruleStrs.length];
-                for (int i = 0; i < exruleStrs.length; ++i) {
-                    EventRecurrence exrule = new EventRecurrence();
-                    exrule.parse(exruleStr);
-                    exrules[i] = exrule;
-                }
-            }
-
-            if (!TextUtils.isEmpty(exdateStr)) {
-                exdates = parseRecurrenceDates(exdateStr);
-            }
-        }
-    }
-
-    /**
-     * Returns whether or not a recurrence is defined in this RecurrenceSet.
-     * @return Whether or not a recurrence is defined in this RecurrenceSet.
-     */
-    public boolean hasRecurrence() {
-        return (rrules != null || rdates != null);
-    }
-
-    /**
-     * Parses the provided RDATE or EXDATE string into an array of longs
-     * representing each date/time in the recurrence.
-     * @param recurrence The recurrence to be parsed.
-     * @return The list of date/times.
-     */
-    public static long[] parseRecurrenceDates(String recurrence) {
-        // TODO: use "local" time as the default.  will need to handle times
-        // that end in "z" (UTC time) explicitly at that point.
-        String tz = Time.TIMEZONE_UTC;
-        int tzidx = recurrence.indexOf(";");
-        if (tzidx != -1) {
-            tz = recurrence.substring(0, tzidx);
-            recurrence = recurrence.substring(tzidx + 1);
-        }
-        Time time = new Time(tz);
-        String[] rawDates = recurrence.split(",");
-        int n = rawDates.length;
-        long[] dates = new long[n];
-        for (int i = 0; i<n; ++i) {
-            // The timezone is updated to UTC if the time string specified 'Z'.
-            time.parse(rawDates[i]);
-            dates[i] = time.toMillis(false /* use isDst */);
-            time.timezone = tz;
-        }
-        return dates;
-    }
-
-    /**
-     * Populates the database map of values with the appropriate RRULE, RDATE,
-     * EXRULE, and EXDATE values extracted from the parsed iCalendar component.
-     * @param component The iCalendar component containing the desired
-     * recurrence specification.
-     * @param values The db values that should be updated.
-     * @return true if the component contained the necessary information
-     * to specify a recurrence.  The required fields are DTSTART,
-     * one of DTEND/DURATION, and one of RRULE/RDATE.  Returns false if
-     * there was an error, including if the date is out of range.
-     */
-    public static boolean populateContentValues(ICalendar.Component component,
-            ContentValues values) {
-        ICalendar.Property dtstartProperty =
-                component.getFirstProperty("DTSTART");
-        String dtstart = dtstartProperty.getValue();
-        ICalendar.Parameter tzidParam =
-                dtstartProperty.getFirstParameter("TZID");
-        // NOTE: the timezone may be null, if this is a floating time.
-        String tzid = tzidParam == null ? null : tzidParam.value;
-        Time start = new Time(tzidParam == null ? Time.TIMEZONE_UTC : tzid);
-        boolean inUtc = start.parse(dtstart);
-        boolean allDay = start.allDay;
-
-        // We force TimeZone to UTC for "all day recurring events" as the server is sending no
-        // TimeZone in DTSTART for them
-        if (inUtc || allDay) {
-            tzid = Time.TIMEZONE_UTC;
-        }
-                
-        String duration = computeDuration(start, component);
-        String rrule = flattenProperties(component, "RRULE");
-        String rdate = extractDates(component.getFirstProperty("RDATE"));
-        String exrule = flattenProperties(component, "EXRULE");
-        String exdate = extractDates(component.getFirstProperty("EXDATE"));
-
-        if ((TextUtils.isEmpty(dtstart))||
-                (TextUtils.isEmpty(duration))||
-                ((TextUtils.isEmpty(rrule))&&
-                        (TextUtils.isEmpty(rdate)))) {
-                if (false) {
-                    Log.d(TAG, "Recurrence missing DTSTART, DTEND/DURATION, "
-                                + "or RRULE/RDATE: "
-                                + component.toString());
-                }
-                return false;
-        }
-        
-        if (allDay) {
-            start.timezone = Time.TIMEZONE_UTC;
-        }
-        long millis = start.toMillis(false /* use isDst */);
-        values.put(CalendarContract.Events.DTSTART, millis);
-        if (millis == -1) {
-            if (false) {
-                Log.d(TAG, "DTSTART is out of range: " + component.toString());
-            }
-            return false;
-        }
-        
-        values.put(CalendarContract.Events.RRULE, rrule);
-        values.put(CalendarContract.Events.RDATE, rdate);
-        values.put(CalendarContract.Events.EXRULE, exrule);
-        values.put(CalendarContract.Events.EXDATE, exdate);
-        values.put(CalendarContract.Events.EVENT_TIMEZONE, tzid);
-        values.put(CalendarContract.Events.DURATION, duration);
-        values.put(CalendarContract.Events.ALL_DAY, allDay ? 1 : 0);
-        return true;
-    }
-
-    // This can be removed when the old CalendarSyncAdapter is removed.
-    public static boolean populateComponent(Cursor cursor,
-                                            ICalendar.Component component) {
-        
-        int dtstartColumn = cursor.getColumnIndex(CalendarContract.Events.DTSTART);
-        int durationColumn = cursor.getColumnIndex(CalendarContract.Events.DURATION);
-        int tzidColumn = cursor.getColumnIndex(CalendarContract.Events.EVENT_TIMEZONE);
-        int rruleColumn = cursor.getColumnIndex(CalendarContract.Events.RRULE);
-        int rdateColumn = cursor.getColumnIndex(CalendarContract.Events.RDATE);
-        int exruleColumn = cursor.getColumnIndex(CalendarContract.Events.EXRULE);
-        int exdateColumn = cursor.getColumnIndex(CalendarContract.Events.EXDATE);
-        int allDayColumn = cursor.getColumnIndex(CalendarContract.Events.ALL_DAY);
-
-
-        long dtstart = -1;
-        if (!cursor.isNull(dtstartColumn)) {
-            dtstart = cursor.getLong(dtstartColumn);
-        }
-        String duration = cursor.getString(durationColumn);
-        String tzid = cursor.getString(tzidColumn);
-        String rruleStr = cursor.getString(rruleColumn);
-        String rdateStr = cursor.getString(rdateColumn);
-        String exruleStr = cursor.getString(exruleColumn);
-        String exdateStr = cursor.getString(exdateColumn);
-        boolean allDay = cursor.getInt(allDayColumn) == 1;
-
-        if ((dtstart == -1) ||
-            (TextUtils.isEmpty(duration))||
-            ((TextUtils.isEmpty(rruleStr))&&
-                (TextUtils.isEmpty(rdateStr)))) {
-                // no recurrence.
-                return false;
-        }
-
-        ICalendar.Property dtstartProp = new ICalendar.Property("DTSTART");
-        Time dtstartTime = null;
-        if (!TextUtils.isEmpty(tzid)) {
-            if (!allDay) {
-                dtstartProp.addParameter(new ICalendar.Parameter("TZID", tzid));
-            }
-            dtstartTime = new Time(tzid);
-        } else {
-            // use the "floating" timezone
-            dtstartTime = new Time(Time.TIMEZONE_UTC);
-        }
-        
-        dtstartTime.set(dtstart);
-        // make sure the time is printed just as a date, if all day.
-        // TODO: android.pim.Time really should take care of this for us.
-        if (allDay) {
-            dtstartProp.addParameter(new ICalendar.Parameter("VALUE", "DATE"));
-            dtstartTime.allDay = true;
-            dtstartTime.hour = 0;
-            dtstartTime.minute = 0;
-            dtstartTime.second = 0;
-        }
-
-        dtstartProp.setValue(dtstartTime.format2445());
-        component.addProperty(dtstartProp);
-        ICalendar.Property durationProp = new ICalendar.Property("DURATION");
-        durationProp.setValue(duration);
-        component.addProperty(durationProp);
-
-        addPropertiesForRuleStr(component, "RRULE", rruleStr);
-        addPropertyForDateStr(component, "RDATE", rdateStr);
-        addPropertiesForRuleStr(component, "EXRULE", exruleStr);
-        addPropertyForDateStr(component, "EXDATE", exdateStr);
-        return true;
-    }
-
-public static boolean populateComponent(ContentValues values,
-                                            ICalendar.Component component) {
-        long dtstart = -1;
-        if (values.containsKey(CalendarContract.Events.DTSTART)) {
-            dtstart = values.getAsLong(CalendarContract.Events.DTSTART);
-        }
-        String duration = values.getAsString(CalendarContract.Events.DURATION);
-        String tzid = values.getAsString(CalendarContract.Events.EVENT_TIMEZONE);
-        String rruleStr = values.getAsString(CalendarContract.Events.RRULE);
-        String rdateStr = values.getAsString(CalendarContract.Events.RDATE);
-        String exruleStr = values.getAsString(CalendarContract.Events.EXRULE);
-        String exdateStr = values.getAsString(CalendarContract.Events.EXDATE);
-        Integer allDayInteger = values.getAsInteger(CalendarContract.Events.ALL_DAY);
-        boolean allDay = (null != allDayInteger) ? (allDayInteger == 1) : false;
-
-        if ((dtstart == -1) ||
-            (TextUtils.isEmpty(duration))||
-            ((TextUtils.isEmpty(rruleStr))&&
-                (TextUtils.isEmpty(rdateStr)))) {
-                // no recurrence.
-                return false;
-        }
-
-        ICalendar.Property dtstartProp = new ICalendar.Property("DTSTART");
-        Time dtstartTime = null;
-        if (!TextUtils.isEmpty(tzid)) {
-            if (!allDay) {
-                dtstartProp.addParameter(new ICalendar.Parameter("TZID", tzid));
-            }
-            dtstartTime = new Time(tzid);
-        } else {
-            // use the "floating" timezone
-            dtstartTime = new Time(Time.TIMEZONE_UTC);
-        }
-
-        dtstartTime.set(dtstart);
-        // make sure the time is printed just as a date, if all day.
-        // TODO: android.pim.Time really should take care of this for us.
-        if (allDay) {
-            dtstartProp.addParameter(new ICalendar.Parameter("VALUE", "DATE"));
-            dtstartTime.allDay = true;
-            dtstartTime.hour = 0;
-            dtstartTime.minute = 0;
-            dtstartTime.second = 0;
-        }
-
-        dtstartProp.setValue(dtstartTime.format2445());
-        component.addProperty(dtstartProp);
-        ICalendar.Property durationProp = new ICalendar.Property("DURATION");
-        durationProp.setValue(duration);
-        component.addProperty(durationProp);
-
-        addPropertiesForRuleStr(component, "RRULE", rruleStr);
-        addPropertyForDateStr(component, "RDATE", rdateStr);
-        addPropertiesForRuleStr(component, "EXRULE", exruleStr);
-        addPropertyForDateStr(component, "EXDATE", exdateStr);
-        return true;
-    }
-
-    private static void addPropertiesForRuleStr(ICalendar.Component component,
-                                                String propertyName,
-                                                String ruleStr) {
-        if (TextUtils.isEmpty(ruleStr)) {
-            return;
-        }
-        String[] rrules = getRuleStrings(ruleStr);
-        for (String rrule : rrules) {
-            ICalendar.Property prop = new ICalendar.Property(propertyName);
-            prop.setValue(rrule);
-            component.addProperty(prop);
-        }
-    }
-
-    private static String[] getRuleStrings(String ruleStr) {
-        if (null == ruleStr) {
-            return new String[0];
-        }
-        String unfoldedRuleStr = unfold(ruleStr);
-        String[] split = unfoldedRuleStr.split(RULE_SEPARATOR);
-        int count = split.length;
-        for (int n = 0; n < count; n++) {
-            split[n] = fold(split[n]);
-        }
-        return split;
-    }
-
-
-    private static final Pattern IGNORABLE_ICAL_WHITESPACE_RE =
-            Pattern.compile("(?:\\r\\n?|\\n)[ \t]");
-
-    private static final Pattern FOLD_RE = Pattern.compile(".{75}");
-
-    /**
-    * fold and unfolds ical content lines as per RFC 2445 section 4.1.
-    *
-    * <h3>4.1 Content Lines</h3>
-    *
-    * <p>The iCalendar object is organized into individual lines of text, called
-    * content lines. Content lines are delimited by a line break, which is a CRLF
-    * sequence (US-ASCII decimal 13, followed by US-ASCII decimal 10).
-    *
-    * <p>Lines of text SHOULD NOT be longer than 75 octets, excluding the line
-    * break. Long content lines SHOULD be split into a multiple line
-    * representations using a line "folding" technique. That is, a long line can
-    * be split between any two characters by inserting a CRLF immediately
-    * followed by a single linear white space character (i.e., SPACE, US-ASCII
-    * decimal 32 or HTAB, US-ASCII decimal 9). Any sequence of CRLF followed
-    * immediately by a single linear white space character is ignored (i.e.,
-    * removed) when processing the content type.
-    */
-    public static String fold(String unfoldedIcalContent) {
-        return FOLD_RE.matcher(unfoldedIcalContent).replaceAll("$0\r\n ");
-    }
-
-    public static String unfold(String foldedIcalContent) {
-        return IGNORABLE_ICAL_WHITESPACE_RE.matcher(
-            foldedIcalContent).replaceAll("");
-    }
-
-    private static void addPropertyForDateStr(ICalendar.Component component,
-                                              String propertyName,
-                                              String dateStr) {
-        if (TextUtils.isEmpty(dateStr)) {
-            return;
-        }
-
-        ICalendar.Property prop = new ICalendar.Property(propertyName);
-        String tz = null;
-        int tzidx = dateStr.indexOf(";");
-        if (tzidx != -1) {
-            tz = dateStr.substring(0, tzidx);
-            dateStr = dateStr.substring(tzidx + 1);
-        }
-        if (!TextUtils.isEmpty(tz)) {
-            prop.addParameter(new ICalendar.Parameter("TZID", tz));
-        }
-        prop.setValue(dateStr);
-        component.addProperty(prop);
-    }
-    
-    private static String computeDuration(Time start,
-                                          ICalendar.Component component) {
-        // see if a duration is defined
-        ICalendar.Property durationProperty =
-                component.getFirstProperty("DURATION");
-        if (durationProperty != null) {
-            // just return the duration
-            return durationProperty.getValue();
-        }
-
-        // must compute a duration from the DTEND
-        ICalendar.Property dtendProperty =
-                component.getFirstProperty("DTEND");
-        if (dtendProperty == null) {
-            // no DURATION, no DTEND: 0 second duration
-            return "+P0S";
-        }
-        ICalendar.Parameter endTzidParameter =
-                dtendProperty.getFirstParameter("TZID");
-        String endTzid = (endTzidParameter == null)
-                ? start.timezone : endTzidParameter.value;
-
-        Time end = new Time(endTzid);
-        end.parse(dtendProperty.getValue());
-        long durationMillis = end.toMillis(false /* use isDst */)
-                - start.toMillis(false /* use isDst */);
-        long durationSeconds = (durationMillis / 1000);
-        if (start.allDay && (durationSeconds % 86400) == 0) {
-            return "P" + (durationSeconds / 86400) + "D"; // Server wants this instead of P86400S
-        } else {
-            return "P" + durationSeconds + "S";
-        }
-    }
-
-    private static String flattenProperties(ICalendar.Component component,
-                                            String name) {
-        List<ICalendar.Property> properties = component.getProperties(name);
-        if (properties == null || properties.isEmpty()) {
-            return null;
-        }
-
-        if (properties.size() == 1) {
-            return properties.get(0).getValue();
-        }
-
-        StringBuilder sb = new StringBuilder();
-
-        boolean first = true;
-        for (ICalendar.Property property : component.getProperties(name)) {
-            if (first) {
-                first = false;
-            } else {
-                // TODO: use commas.  our RECUR parsing should handle that
-                // anyway.
-                sb.append(RULE_SEPARATOR);
-            }
-            sb.append(property.getValue());
-        }
-        return sb.toString();
-    }
-
-    private static String extractDates(ICalendar.Property recurrence) {
-        if (recurrence == null) {
-            return null;
-        }
-        ICalendar.Parameter tzidParam =
-                recurrence.getFirstParameter("TZID");
-        if (tzidParam != null) {
-            return tzidParam.value + ";" + recurrence.getValue();
-        }
-        return recurrence.getValue();
-    }
-}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 65babc2..23b53ae 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3833,6 +3833,11 @@
         /** {@hide} */
         public static final String NETSTATS_TAG_MAX_HISTORY = "netstats_tag_max_history";
 
+        /** Preferred NTP server. {@hide} */
+        public static final String NTP_SERVER = "ntp_server";
+        /** Timeout in milliseconds to wait for NTP server. {@hide} */
+        public static final String NTP_TIMEOUT = "ntp_timeout";
+
         /**
          * @hide
          */
diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java
index 7f862e0..105ff332 100644
--- a/core/java/android/server/BluetoothHealthProfileHandler.java
+++ b/core/java/android/server/BluetoothHealthProfileHandler.java
@@ -20,15 +20,12 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHealth;
 import android.bluetooth.BluetoothHealthAppConfiguration;
-import android.bluetooth.BluetoothHealth;
-import android.bluetooth.BluetoothInputDevice;
+import android.bluetooth.IBluetoothHealthCallback;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.provider.Settings;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -36,10 +33,6 @@
 import java.util.List;
 import java.util.Map.Entry;
 
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-
 /**
  * This handles all the operations on the Bluetooth Health profile.
  * All functions are called by BluetoothService, as Bluetooth Service
@@ -58,6 +51,7 @@
     private ArrayList<HealthChannel> mHealthChannels;
     private HashMap <BluetoothHealthAppConfiguration, String> mHealthAppConfigs;
     private HashMap <BluetoothDevice, Integer> mHealthDevices;
+    private HashMap <BluetoothHealthAppConfiguration, IBluetoothHealthCallback> mCallbacks;
 
     private static final int MESSAGE_REGISTER_APPLICATION = 0;
     private static final int MESSAGE_UNREGISTER_APPLICATION = 1;
@@ -103,6 +97,7 @@
                 }
 
                 if (path == null) {
+                    mCallbacks.remove(registerApp);
                     callHealthApplicationStatusCallback(registerApp,
                             BluetoothHealth.APPLICATION_REGISTRATION_FAILURE);
                 } else {
@@ -118,6 +113,7 @@
                 boolean result = mBluetoothService.unregisterHealthApplicationNative(
                         mHealthAppConfigs.get(unregisterApp));
                 if (result) {
+                    mCallbacks.remove(unregisterApp);
                     callHealthApplicationStatusCallback(unregisterApp,
                             BluetoothHealth.APPLICATION_UNREGISTRATION_SUCCESS);
                 } else {
@@ -149,6 +145,7 @@
         mHealthAppConfigs = new HashMap<BluetoothHealthAppConfiguration, String>();
         mHealthChannels = new ArrayList<HealthChannel>();
         mHealthDevices = new HashMap<BluetoothDevice, Integer>();
+        mCallbacks = new HashMap<BluetoothHealthAppConfiguration, IBluetoothHealthCallback>();
     }
 
     static synchronized BluetoothHealthProfileHandler getInstance(Context context,
@@ -157,10 +154,12 @@
         return sInstance;
     }
 
-    boolean registerAppConfiguration(BluetoothHealthAppConfiguration config) {
+    boolean registerAppConfiguration(BluetoothHealthAppConfiguration config,
+                                     IBluetoothHealthCallback callback) {
         Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_APPLICATION);
         msg.obj = config;
         mHandler.sendMessage(msg);
+        mCallbacks.put(config, callback);
         return true;
     }
 
@@ -442,11 +441,11 @@
 
         debugLog("Health Device Callback: " + device + " State Change: "
                 + prevState + "->" + state);
-        try {
-            config.getCallback().onHealthChannelStateChange(config, device, prevState,
-                    state, fd);
-        } catch (RemoteException e) {
-            errorLog("Error while making health channel state change callback: " + e);
+        IBluetoothHealthCallback callback = mCallbacks.get(config);
+        if (callback != null) {
+            try {
+                callback.onHealthChannelStateChange(config, device, prevState, state, fd);
+            } catch (RemoteException e) {}
         }
     }
 
@@ -454,10 +453,11 @@
             BluetoothHealthAppConfiguration config, int status) {
         debugLog("Health Device Application: " + config + " State Change: status:"
                 + status);
-        try {
-            config.getCallback().onHealthAppConfigurationStatusChange(config, status);
-        } catch (RemoteException e) {
-            errorLog("Error while making health app registration state change callback: " + e);
+        IBluetoothHealthCallback callback = mCallbacks.get(config);
+        if (callback != null) {
+            try {
+                callback.onHealthAppConfigurationStatusChange(config, status);
+            } catch (RemoteException e) {}
         }
     }
 
@@ -526,19 +526,19 @@
             List<HealthChannel> chan;
             switch (currDeviceState) {
                 case BluetoothHealth.STATE_DISCONNECTED:
-                    updateAndsendIntent(device, currDeviceState, newDeviceState);
+                    updateAndSendIntent(device, currDeviceState, newDeviceState);
                     break;
                 case BluetoothHealth.STATE_CONNECTING:
                     // Channel got connected.
                     if (newDeviceState == BluetoothHealth.STATE_CONNECTED) {
-                        updateAndsendIntent(device, currDeviceState, newDeviceState);
+                        updateAndSendIntent(device, currDeviceState, newDeviceState);
                     } else {
                         // Channel got disconnected
                         chan = findChannelByStates(device, new int [] {
                                     BluetoothHealth.STATE_CHANNEL_CONNECTING,
                                     BluetoothHealth.STATE_CHANNEL_DISCONNECTING});
                         if (chan.isEmpty()) {
-                            updateAndsendIntent(device, currDeviceState, newDeviceState);
+                            updateAndSendIntent(device, currDeviceState, newDeviceState);
                         }
                     }
                     break;
@@ -548,22 +548,23 @@
                                 BluetoothHealth.STATE_CHANNEL_CONNECTING,
                                 BluetoothHealth.STATE_CHANNEL_CONNECTED});
                     if (chan.isEmpty()) {
-                        updateAndsendIntent(device, currDeviceState, newDeviceState);
+                        updateAndSendIntent(device, currDeviceState, newDeviceState);
                     }
+                    break;
                 case BluetoothHealth.STATE_DISCONNECTING:
                     // Channel got disconnected.
                     chan = findChannelByStates(device, new int [] {
                                 BluetoothHealth.STATE_CHANNEL_CONNECTING,
                                 BluetoothHealth.STATE_CHANNEL_DISCONNECTING});
                     if (chan.isEmpty()) {
-                        updateAndsendIntent(device, currDeviceState, newDeviceState);
+                        updateAndSendIntent(device, currDeviceState, newDeviceState);
                     }
                     break;
             }
         }
     }
 
-    private void updateAndsendIntent(BluetoothDevice device, int prevDeviceState,
+    private void updateAndSendIntent(BluetoothDevice device, int prevDeviceState,
             int newDeviceState) {
         mHealthDevices.put(device, newDeviceState);
         mBluetoothService.sendConnectionStateChange(device, prevDeviceState, newDeviceState);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
old mode 100644
new mode 100755
index 9839f76..b23e3ce
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -24,8 +24,6 @@
 
 package android.server;
 
-import com.android.internal.app.IBatteryStats;
-
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
@@ -40,6 +38,7 @@
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetooth;
 import android.bluetooth.IBluetoothCallback;
+import android.bluetooth.IBluetoothHealthCallback;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -58,6 +57,8 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.app.IBatteryStats;
+
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -2111,11 +2112,12 @@
     /**** Handlers for Health Device Profile ****/
     // TODO: All these need to be converted to a state machine.
 
-    public boolean registerAppConfiguration(BluetoothHealthAppConfiguration config) {
+    public boolean registerAppConfiguration(BluetoothHealthAppConfiguration config,
+                                            IBluetoothHealthCallback callback) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
                 "Need BLUETOOTH permission");
         synchronized (mBluetoothHealthProfileHandler) {
-                return mBluetoothHealthProfileHandler.registerAppConfiguration(config);
+                return mBluetoothHealthProfileHandler.registerAppConfiguration(config, callback);
         }
     }
 
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 5b19ecd..2179ff3 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -16,41 +16,71 @@
 
 package android.util;
 
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
 import android.net.SntpClient;
 import android.os.SystemClock;
+import android.provider.Settings;
 
 /**
- * {@link TrustedTime} that connects with a remote NTP server as its remote
- * trusted time source.
+ * {@link TrustedTime} that connects with a remote NTP server as its trusted
+ * time source.
  *
  * @hide
  */
 public class NtpTrustedTime implements TrustedTime {
-    private String mNtpServer;
-    private long mNtpTimeout;
+    private static final String TAG = "NtpTrustedTime";
+    private static final boolean LOGD = false;
+
+    private static NtpTrustedTime sSingleton;
+
+    private final String mServer;
+    private final long mTimeout;
 
     private boolean mHasCache;
     private long mCachedNtpTime;
     private long mCachedNtpElapsedRealtime;
     private long mCachedNtpCertainty;
 
-    public NtpTrustedTime() {
+    private NtpTrustedTime(String server, long timeout) {
+        if (LOGD) Log.d(TAG, "creating NtpTrustedTime using " + server);
+        mServer = server;
+        mTimeout = timeout;
     }
 
-    public void setNtpServer(String server, long timeout) {
-        mNtpServer = server;
-        mNtpTimeout = timeout;
+    public static synchronized NtpTrustedTime getInstance(Context context) {
+        if (sSingleton == null) {
+            final Resources res = context.getResources();
+            final ContentResolver resolver = context.getContentResolver();
+
+            final String defaultServer = res.getString(
+                    com.android.internal.R.string.config_ntpServer);
+            final long defaultTimeout = res.getInteger(
+                    com.android.internal.R.integer.config_ntpTimeout);
+
+            final String secureServer = Settings.Secure.getString(
+                    resolver, Settings.Secure.NTP_SERVER);
+            final long timeout = Settings.Secure.getLong(
+                    resolver, Settings.Secure.NTP_TIMEOUT, defaultTimeout);
+
+            final String server = secureServer != null ? secureServer : defaultServer;
+            sSingleton = new NtpTrustedTime(server, timeout);
+        }
+
+        return sSingleton;
     }
 
     /** {@inheritDoc} */
     public boolean forceRefresh() {
-        if (mNtpServer == null) {
+        if (mServer == null) {
             // missing server, so no trusted time available
             return false;
         }
 
+        if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
         final SntpClient client = new SntpClient();
-        if (client.requestTime(mNtpServer, (int) mNtpTimeout)) {
+        if (client.requestTime(mServer, (int) mTimeout)) {
             mHasCache = true;
             mCachedNtpTime = client.getNtpTime();
             mCachedNtpElapsedRealtime = client.getNtpTimeReference();
@@ -89,9 +119,19 @@
         if (!mHasCache) {
             throw new IllegalStateException("Missing authoritative time source");
         }
+        if (LOGD) Log.d(TAG, "currentTimeMillis() cache hit");
 
         // current time is age after the last ntp cache; callers who
         // want fresh values will hit makeAuthoritative() first.
         return mCachedNtpTime + getCacheAge();
     }
+
+    public long getCachedNtpTime() {
+        if (LOGD) Log.d(TAG, "getCachedNtpTime() cache hit");
+        return mCachedNtpTime;
+    }
+
+    public long getCachedNtpTimeReference() {
+        return mCachedNtpElapsedRealtime;
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1245898..74dc100 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4474,7 +4474,7 @@
     @RemotableViewMethod
     public void setLayoutDirection(int layoutDirection) {
         if (getLayoutDirection() != layoutDirection) {
-            resetLayoutDirectionResolution();
+            resetResolvedLayoutDirection();
             // Setting the flag will also request a layout.
             setFlags(layoutDirection, LAYOUT_DIRECTION_MASK);
         }
@@ -9043,10 +9043,8 @@
             mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
         }
         jumpDrawablesToCurrentState();
-        resetLayoutDirectionResolution();
         resolveLayoutDirectionIfNeeded();
         resolvePadding();
-        resetResolvedTextDirection();
         resolveTextDirection();
         if (isFocused()) {
             InputMethodManager imm = InputMethodManager.peekInstance();
@@ -9143,7 +9141,7 @@
      *
      * @hide
      */
-    protected void resetLayoutDirectionResolution() {
+    protected void resetResolvedLayoutDirection() {
         // Reset the current View resolution
         mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED;
     }
@@ -9190,6 +9188,9 @@
         }
 
         mCurrentAnimation = null;
+
+        resetResolvedLayoutDirection();
+        resetResolvedTextDirection();
     }
 
     /**
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index c0619a5..b4f323c 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -3848,10 +3848,6 @@
         }
 
         private static int checkCallingPermission(String permission) {
-            if (!Process.supportsProcesses()) {
-                return PackageManager.PERMISSION_GRANTED;
-            }
-
             try {
                 return ActivityManagerNative.getDefault().checkPermission(
                         permission, Binder.getCallingPid(), Binder.getCallingUid());
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e6fdb17..752fd5a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4999,15 +4999,15 @@
     }
 
     @Override
-    protected void resetLayoutDirectionResolution() {
-        super.resetLayoutDirectionResolution();
+    protected void resetResolvedLayoutDirection() {
+        super.resetResolvedLayoutDirection();
 
         // Take care of resetting the children resolution too
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             final View child = getChildAt(i);
             if (child.getLayoutDirection() == LAYOUT_DIRECTION_INHERIT) {
-                child.resetLayoutDirectionResolution();
+                child.resetResolvedLayoutDirection();
             }
         }
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1e63e26..e350ec4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5571,8 +5571,8 @@
     }
 
     @Override
-    protected void resetLayoutDirectionResolution() {
-        super.resetLayoutDirectionResolution();
+    protected void resetResolvedLayoutDirection() {
+        super.resetResolvedLayoutDirection();
 
         if (mLayoutAlignment != null &&
                 (mTextAlign == TextAlign.VIEW_START ||
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index f13e770..53516c0 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -252,9 +252,10 @@
      *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
      * </ul>
      *
+     * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    public static final void zygoteInit(String[] argv)
+    public static final void zygoteInit(int targetSdkVersion, String[] argv)
             throws ZygoteInit.MethodAndArgsCaller {
         if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
 
@@ -263,7 +264,7 @@
         commonInit();
         zygoteInitNative();
 
-        applicationInit(argv);
+        applicationInit(targetSdkVersion, argv);
     }
 
     /**
@@ -274,20 +275,22 @@
      * which calls {@link WrapperInit#main} which then calls this method.
      * So we don't need to call commonInit() here.
      *
+     * @param targetSdkVersion target SDK version
      * @param argv arg strings
      */
-    public static void wrapperInit(String[] argv)
+    public static void wrapperInit(int targetSdkVersion, String[] argv)
             throws ZygoteInit.MethodAndArgsCaller {
         if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper");
 
-        applicationInit(argv);
+        applicationInit(targetSdkVersion, argv);
     }
 
-    private static void applicationInit(String[] argv)
+    private static void applicationInit(int targetSdkVersion, String[] argv)
             throws ZygoteInit.MethodAndArgsCaller {
         // We want to be fairly aggressive about heap utilization, to avoid
         // holding on to a lot of memory that isn't needed.
         VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
+        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
 
         final Arguments args;
         try {
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 860a08c..c6b3e7c 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -47,16 +47,22 @@
      * wrapper process instead of by forking Zygote.
      *
      * The first argument specifies the file descriptor for a pipe that should receive
-     * the pid of this process, or 0 if none.  The remaining arguments are passed to
-     * the runtime.
+     * the pid of this process, or 0 if none.
+     *
+     * The second argument is the target SDK version for the app.
+     *
+     * The remaining arguments are passed to the runtime.
      *
      * @param args The command-line arguments.
      */
     public static void main(String[] args) {
         try {
+            // Parse our mandatory arguments.
+            int fdNum = Integer.parseInt(args[0], 10);
+            int targetSdkVersion = Integer.parseInt(args[1], 10);
+
             // Tell the Zygote what our actual PID is (since it only knows about the
             // wrapper that it directly forked).
-            int fdNum = Integer.parseInt(args[0], 10);
             if (fdNum != 0) {
                 try {
                     FileDescriptor fd = ZygoteInit.createFileDescriptor(fdNum);
@@ -73,9 +79,9 @@
             ZygoteInit.preload();
 
             // Launch the application.
-            String[] runtimeArgs = new String[args.length - 1];
-            System.arraycopy(args, 1, runtimeArgs, 0, runtimeArgs.length);
-            RuntimeInit.wrapperInit(runtimeArgs);
+            String[] runtimeArgs = new String[args.length - 2];
+            System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length);
+            RuntimeInit.wrapperInit(targetSdkVersion, runtimeArgs);
         } catch (ZygoteInit.MethodAndArgsCaller caller) {
             caller.run();
         }
@@ -87,11 +93,12 @@
      *
      * @param invokeWith The wrapper command.
      * @param niceName The nice name for the application, or null if none.
+     * @param targetSdkVersion The target SDK version for the app.
      * @param pipeFd The pipe to which the application's pid should be written, or null if none.
      * @param args Arguments for {@link RuntimeInit.main}.
      */
     public static void execApplication(String invokeWith, String niceName,
-            FileDescriptor pipeFd, String[] args) {
+            int targetSdkVersion, FileDescriptor pipeFd, String[] args) {
         StringBuilder command = new StringBuilder(invokeWith);
         command.append(" /system/bin/app_process /system/bin --application");
         if (niceName != null) {
@@ -99,6 +106,8 @@
         }
         command.append(" com.android.internal.os.WrapperInit ");
         command.append(pipeFd != null ? pipeFd.getInt$() : 0);
+        command.append(' ');
+        command.append(targetSdkVersion);
         Zygote.appendQuotedShellArgs(command, args);
         Zygote.execShell(command.toString());
     }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 7cb002c..a3b7795 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -18,6 +18,7 @@
 
 import android.net.Credentials;
 import android.net.LocalSocket;
+import android.os.Build;
 import android.os.Process;
 import android.os.SystemProperties;
 import android.util.Log;
@@ -333,6 +334,10 @@
          */
         int debugFlags;
 
+        /** from --target-sdk-version. */
+        int targetSdkVersion;
+        boolean targetSdkVersionSpecified;
+
         /** from --classpath */
         String classpath;
 
@@ -402,6 +407,14 @@
                     gidSpecified = true;
                     gid = Integer.parseInt(
                             arg.substring(arg.indexOf('=') + 1));
+                } else if (arg.startsWith("--target-sdk-version=")) {
+                    if (targetSdkVersionSpecified) {
+                        throw new IllegalArgumentException(
+                                "Duplicate target-sdk-version specified");
+                    }
+                    targetSdkVersionSpecified = true;
+                    targetSdkVersion = Integer.parseInt(
+                            arg.substring(arg.indexOf('=') + 1));
                 } else if (arg.equals("--enable-debugger")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
                 } else if (arg.equals("--enable-safemode")) {
@@ -821,9 +834,11 @@
         if (parsedArgs.runtimeInit) {
             if (parsedArgs.invokeWith != null) {
                 WrapperInit.execApplication(parsedArgs.invokeWith,
-                        parsedArgs.niceName, pipeFd, parsedArgs.remainingArgs);
+                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
+                        pipeFd, parsedArgs.remainingArgs);
             } else {
-                RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
+                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
+                        parsedArgs.remainingArgs);
             }
         } else {
             String className;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index b4a7e52..6ec186d 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -48,7 +48,7 @@
  * Startup class for the zygote process.
  *
  * Pre-initializes some classes, and then waits for commands on a UNIX domain
- * socket. Based on these commands, forks of child processes that inherit
+ * socket. Based on these commands, forks off child processes that inherit
  * the initial state of the VM.
  *
  * Please see {@link ZygoteConnection.Arguments} for documentation on the
@@ -453,12 +453,13 @@
 
         if (parsedArgs.invokeWith != null) {
             WrapperInit.execApplication(parsedArgs.invokeWith,
-                    parsedArgs.niceName, null, parsedArgs.remainingArgs);
+                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
+                    null, parsedArgs.remainingArgs);
         } else {
             /*
              * Pass the remaining arguments to SystemServer.
              */
-            RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
+            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
         }
 
         /* should never reach here */
@@ -491,7 +492,9 @@
             /* Request to fork the system server process */
             pid = Zygote.forkSystemServer(
                     parsedArgs.uid, parsedArgs.gid,
-                    parsedArgs.gids, parsedArgs.debugFlags, null,
+                    parsedArgs.gids,
+                    parsedArgs.debugFlags,
+                    null,
                     parsedArgs.permittedCapabilities,
                     parsedArgs.effectiveCapabilities);
         } catch (IllegalArgumentException ex) {
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index ddae505..d9bd50e 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -26,7 +26,7 @@
 extern "C" {
 int ifc_enable(const char *ifname);
 int ifc_disable(const char *ifname);
-int ifc_reset_connections(const char *ifname);
+int ifc_reset_connections(const char *ifname, int reset_mask);
 
 int dhcp_do_request(const char *ifname,
                     const char *ipaddr,
@@ -90,12 +90,17 @@
     return (jint)result;
 }
 
-static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
+static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
+      jstring ifname, jint mask)
 {
     int result;
 
     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
-    result = ::ifc_reset_connections(nameStr);
+
+    LOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
+          env, clazz, nameStr, mask);
+
+    result = ::ifc_reset_connections(nameStr, mask);
     env->ReleaseStringUTFChars(ifname, nameStr);
     return (jint)result;
 }
@@ -206,7 +211,7 @@
 
     { "enableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_enableInterface },
     { "disableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_disableInterface },
-    { "resetConnections", "(Ljava/lang/String;)I",  (void *)android_net_utils_resetConnections },
+    { "resetConnections", "(Ljava/lang/String;I)I",  (void *)android_net_utils_resetConnections },
     { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcp },
     { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcpRenew },
     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 1166ae4..86e7cc0 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -1396,7 +1396,6 @@
                 LOG_AND_FREE_DBUS_ERROR(&err);
             }
         } else {
-            LOGE("--_Call made getting the patch...");
             if (!dbus_message_get_args(reply, &err,
                                       DBUS_TYPE_OBJECT_PATH, &c_path,
                                       DBUS_TYPE_INVALID)) {
@@ -1405,7 +1404,6 @@
                 }
             } else {
                 path = env->NewStringUTF(c_path);
-                LOGE("----Path is %s", c_path);
             }
             dbus_message_unref(reply);
         }
@@ -1459,7 +1457,6 @@
         const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
         const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
         const char *c_config = env->GetStringUTFChars(config, NULL);
-        LOGE("Params...%s, %s, %s \n", c_device_path, c_app_path, c_config);
 
         DBusMessage *reply  = dbus_func_args(env, nat->conn,
                                              c_device_path,
@@ -1531,7 +1528,6 @@
         DBusError err;
         dbus_error_init(&err);
 
-        LOGE("---Args %s", c_device_path);
         DBusMessage *reply = dbus_func_args(env, nat->conn,
                            c_device_path,
                            DBUS_HEALTH_DEVICE_IFACE, "GetProperties",
@@ -1566,8 +1562,6 @@
         DBusError err;
         dbus_error_init(&err);
 
-        LOGE("---Args %s", c_channel_path);
-
         DBusMessage *reply = dbus_func_args(env, nat->conn,
                                             c_channel_path,
                                             DBUS_HEALTH_CHANNEL_IFACE, "GetProperties",
@@ -1596,7 +1590,6 @@
 
                 if (!strcmp(c_name, "Application")) {
                     path = (jstring) env->GetObjectArrayElement(str_array, i+1);
-                    LOGE("----Path is %s", env->GetStringUTFChars(path, NULL));
                     env->ReleaseStringUTFChars(name, c_name);
                     return path;
                 }
@@ -1655,13 +1648,11 @@
         fd = dbus_returns_unixfd(env, reply);
         if (fd == -1) return NULL;
 
-        LOGE("---got fd %d\n", fd);
         // Create FileDescriptor object
         jobject fileDesc = jniCreateFileDescriptor(env, fd);
         if (fileDesc == NULL) {
             // FileDescriptor constructor has thrown an exception
             releaseChannelFdNative(env, object, channelPath);
-            LOGE("---File Desc is null");
             return NULL;
         }
 
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 0960b25..d1ba2d1 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -318,17 +318,15 @@
                                       jint pid, jint adj)
 {
 #ifdef HAVE_OOM_ADJ
-    if (ProcessState::self()->supportsProcesses()) {
-        char text[64];
-        sprintf(text, "/proc/%d/oom_adj", pid);
-        int fd = open(text, O_WRONLY);
-        if (fd >= 0) {
-            sprintf(text, "%d", adj);
-            write(fd, text, strlen(text));
-            close(fd);
-        }
-        return true;
+    char text[64];
+    sprintf(text, "/proc/%d/oom_adj", pid);
+    int fd = open(text, O_WRONLY);
+    if (fd >= 0) {
+        sprintf(text, "%d", adj);
+        write(fd, text, strlen(text));
+        close(fd);
     }
+    return true;
 #endif
     return false;
 }
@@ -370,11 +368,6 @@
     #endif
 }
 
-jboolean android_os_Process_supportsProcesses(JNIEnv* env, jobject clazz)
-{
-    return ProcessState::self()->supportsProcesses();
-}
-
 static int pid_compare(const void* v1, const void* v2)
 {
     //LOGI("Compare %d vs %d\n", *((const jint*)v1), *((const jint*)v2));
@@ -878,7 +871,6 @@
     {"setGid", "(I)I", (void*)android_os_Process_setGid},
     {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
     {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
-    {"supportsProcesses", "()Z", (void*)android_os_Process_supportsProcesses},
     {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
     {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines},
     {"getPids", "(Ljava/lang/String;[I)[I", (void*)android_os_Process_getPids},
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
index 5225a81..acbbb38 100644
--- a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
index 2e7e973..6009528 100644
--- a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
index 4591627..30727d7 100644
--- a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
index 9cf1826..7cea5e1 100644
--- a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
index a47ef40..ba0d612 100644
--- a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
index 9b50c73..e8646b9 100644
--- a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
index a0d36de..14cb4c9 100644
--- a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
index 805b9567..80fd218 100644
--- a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_back.png b/core/res/res/drawable-hdpi/ic_btn_back.png
deleted file mode 100644
index f8b3285..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_back.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_next.png b/core/res/res/drawable-hdpi/ic_btn_next.png
deleted file mode 100644
index b2c6e1b..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_next.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png
index b0fba52..1014d8a 100644
--- a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png
index 3ef8935..18cd171 100644
--- a/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_frame.9.png b/core/res/res/drawable-hdpi/toast_frame.9.png
index 9769bbb..ad2cb5a 100644
--- a/core/res/res/drawable-hdpi/toast_frame.9.png
+++ b/core/res/res/drawable-hdpi/toast_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_frame_holo.9.png b/core/res/res/drawable-hdpi/toast_frame_holo.9.png
index 9769bbb..ad2cb5a 100644
--- a/core/res/res/drawable-hdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-hdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
index a0bd4e3..4836da1 100644
--- a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
index 12abcd2..c299931 100644
--- a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
index adb8104..86edad7 100644
--- a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
index d7c6bbf..53ee68b 100644
--- a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
index 42cfc52..606adaf 100644
--- a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
index 9a08e15..14d2e5e 100644
--- a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
index 5d86b2a..2646332 100644
--- a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
index ad22f5b..48ec0a4 100644
--- a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_back.png b/core/res/res/drawable-mdpi/ic_btn_back.png
deleted file mode 100644
index c9bff4c..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_back.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_next.png b/core/res/res/drawable-mdpi/ic_btn_next.png
deleted file mode 100755
index c6cf436..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_next.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png
index 923f92d..dd5dd39 100644
--- a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png
index afada39..12d65be 100644
--- a/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_frame.9.png b/core/res/res/drawable-mdpi/toast_frame.9.png
index 06cfc70..b9105de 100755
--- a/core/res/res/drawable-mdpi/toast_frame.9.png
+++ b/core/res/res/drawable-mdpi/toast_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_frame_holo.9.png b/core/res/res/drawable-mdpi/toast_frame_holo.9.png
index 06cfc70..b9105de 100755
--- a/core/res/res/drawable-mdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-mdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-xhdpi/dialog_bottom_holo_dark.9.png
index b33e117..077e4d3 100644
--- a/core/res/res/drawable-xhdpi/dialog_bottom_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-xhdpi/dialog_bottom_holo_light.9.png
index d84d427..357c17f 100644
--- a/core/res/res/drawable-xhdpi/dialog_bottom_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-xhdpi/dialog_full_holo_dark.9.png
index 9c0ff47..5b510721 100644
--- a/core/res/res/drawable-xhdpi/dialog_full_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-xhdpi/dialog_full_holo_light.9.png
index 331a4f2..2705a39 100644
--- a/core/res/res/drawable-xhdpi/dialog_full_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-xhdpi/dialog_middle_holo_dark.9.png
index cdc887d..101876f 100644
--- a/core/res/res/drawable-xhdpi/dialog_middle_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-xhdpi/dialog_middle_holo_light.9.png
index bdb6824..0df1503 100644
--- a/core/res/res/drawable-xhdpi/dialog_middle_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-xhdpi/dialog_top_holo_dark.9.png
index 600efb3..344a4e2 100644
--- a/core/res/res/drawable-xhdpi/dialog_top_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-xhdpi/dialog_top_holo_light.9.png
index aa8401d..249848f 100644
--- a/core/res/res/drawable-xhdpi/dialog_top_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_dark.9.png
new file mode 100644
index 0000000..92acc47
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_light.9.png
new file mode 100644
index 0000000..4e54b4b6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_frame.9.png b/core/res/res/drawable-xhdpi/toast_frame.9.png
index f7debee..9f39a77 100644
--- a/core/res/res/drawable-xhdpi/toast_frame.9.png
+++ b/core/res/res/drawable-xhdpi/toast_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_frame_holo.9.png b/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
index f7debee..9f39a77 100644
--- a/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
+++ b/core/res/res/drawable-xhdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/layout-sw600dp/preference_list_content.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
index 5a345c6..a5320a7 100644
--- a/core/res/res/layout-sw600dp/preference_list_content.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content.xml
@@ -87,7 +87,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
         android:visibility="gone">
 
         <Button android:id="@+id/back_button"
@@ -95,8 +94,6 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
             android:text="@string/back_button_label"
         />
         <LinearLayout
@@ -117,8 +114,6 @@
                 android:layout_width="150dip"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
                 android:text="@string/next_button_label"
             />
         </LinearLayout>
diff --git a/core/res/res/layout-w600dp/preference_list_content_single.xml b/core/res/res/layout-w600dp/preference_list_content_single.xml
index 6725996..bbad296 100644
--- a/core/res/res/layout-w600dp/preference_list_content_single.xml
+++ b/core/res/res/layout-w600dp/preference_list_content_single.xml
@@ -61,7 +61,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
         android:visibility="gone">
 
         <Button android:id="@+id/back_button"
@@ -69,8 +68,6 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
             android:text="@string/back_button_label"
         />
         <LinearLayout
@@ -91,8 +88,6 @@
                 android:layout_width="150dip"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
                 android:text="@string/next_button_label"
             />
         </LinearLayout>
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 82b3a4c..fb898ee 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -85,7 +85,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
         android:visibility="gone">
 
         <Button android:id="@+id/back_button"
@@ -93,8 +92,6 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
             android:text="@string/back_button_label"
         />
         <LinearLayout
@@ -115,8 +112,6 @@
                 android:layout_width="150dip"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
                 android:text="@string/next_button_label"
             />
         </LinearLayout>
diff --git a/core/res/res/layout/preference_list_content_single.xml b/core/res/res/layout/preference_list_content_single.xml
index a015761..6902ffd 100644
--- a/core/res/res/layout/preference_list_content_single.xml
+++ b/core/res/res/layout/preference_list_content_single.xml
@@ -56,7 +56,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
         android:visibility="gone">
 
         <Button android:id="@+id/back_button"
@@ -64,8 +63,6 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
             android:text="@string/back_button_label"
         />
         <LinearLayout
@@ -86,8 +83,6 @@
                 android:layout_width="150dip"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
                 android:text="@string/next_button_label"
             />
         </LinearLayout>
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 986536e..315f708 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* 
+/*
 ** Copyright 2010, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,7 +41,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_weight="0"
-        android:background="@android:drawable/bottom_bar"
         android:visibility="gone">
 
         <Button android:id="@+id/back_button"
@@ -49,8 +48,6 @@
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:layout_alignParentLeft="true"
-            android:drawableLeft="@drawable/ic_btn_back"
-            android:drawablePadding="3dip"
             android:text="@string/back_button_label"
         />
         <LinearLayout
@@ -71,8 +68,6 @@
                 android:layout_width="150dip"
                 android:layout_height="wrap_content"
                 android:layout_margin="5dip"
-                android:drawableRight="@drawable/ic_btn_next"
-                android:drawablePadding="3dip"
                 android:text="@string/next_button_label"
             />
         </LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4bc59e4..9c2133f 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5318,6 +5318,8 @@
         <attr name="mtpReserve" format="integer" />
         <!-- true if the storage can be shared via USB mass storage -->
         <attr name="allowMassStorage" format="boolean" />
+        <!-- maximum file size for the volume in megabytes, zero or unspecified if it is unbounded -->
+        <attr name="maxFileSize" format="integer" />
     </declare-styleable>
 
     <declare-styleable name="SwitchPreference">
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9f05cbc..1f2b7fb 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -660,4 +660,9 @@
          extremely limited. -->
     <bool name="config_allowActionMenuItemTextWithIcon">false</bool>
 
+    <!-- Remote server that can provide NTP responses. -->
+    <string translatable="false" name="config_ntpServer">pool.ntp.org</string>
+    <!-- Timeout to wait for NTP server response. -->
+    <integer name="config_ntpTimeout">20000</integer>
+
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 8e2d925..40fa552 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1051,6 +1051,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.TextViewTestActivity" android:label="TextViewTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
 
 
         <!-- Activity-level metadata -->
diff --git a/core/tests/coretests/res/layout/textview_test.xml b/core/tests/coretests/res/layout/textview_test.xml
new file mode 100644
index 0000000..f0c7b9e
--- /dev/null
+++ b/core/tests/coretests/res/layout/textview_test.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/textviewtest_layout"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+
+    <TextView android:id="@+id/textviewtest_textview"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:text="@string/textview_hebrew_text"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/tests/coretests/res/values/strings.xml b/core/tests/coretests/res/values/strings.xml
index f51b08e..71f3520 100644
--- a/core/tests/coretests/res/values/strings.xml
+++ b/core/tests/coretests/res/values/strings.xml
@@ -129,4 +129,6 @@
     <string name="button8">Button8</string>
     <string name="button9">Button9</string>
 
+    <string name="textview_hebrew_text">&#x05DD;&#x05DE;ab?!</string>
+
 </resources>
diff --git a/core/tests/coretests/src/android/pim/EventRecurrenceTest.java b/core/tests/coretests/src/android/pim/EventRecurrenceTest.java
deleted file mode 100644
index 05000f1..0000000
--- a/core/tests/coretests/src/android/pim/EventRecurrenceTest.java
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * 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.
- */
-
-package android.pim;
-
-import android.pim.EventRecurrence.InvalidFormatException;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-
-/**
- * Test android.pim.EventRecurrence.
- *
- * adb shell am instrument -w -e class android.pim.EventRecurrenceTest \
- *   com.android.frameworks.coretests/android.test.InstrumentationTestRunner
- */
-public class EventRecurrenceTest extends TestCase {
-
-    @SmallTest
-    public void test0() throws Exception {
-        verifyRecurType("FREQ=SECONDLY",
-                /* int freq */         EventRecurrence.SECONDLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test1() throws Exception {
-        verifyRecurType("FREQ=MINUTELY",
-                /* int freq */         EventRecurrence.MINUTELY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test2() throws Exception {
-        verifyRecurType("FREQ=HOURLY",
-                /* int freq */         EventRecurrence.HOURLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test3() throws Exception {
-        verifyRecurType("FREQ=DAILY",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test4() throws Exception {
-        verifyRecurType("FREQ=WEEKLY",
-                /* int freq */         EventRecurrence.WEEKLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test5() throws Exception {
-        verifyRecurType("FREQ=MONTHLY",
-                /* int freq */         EventRecurrence.MONTHLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test6() throws Exception {
-        verifyRecurType("FREQ=YEARLY",
-                /* int freq */         EventRecurrence.YEARLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test7() throws Exception {
-        // with an until
-        verifyRecurType("FREQ=DAILY;UNTIL=112233T223344Z",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     "112233T223344Z",
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test8() throws Exception {
-        // with a count
-        verifyRecurType("FREQ=DAILY;COUNT=334",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        334,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test9() throws Exception {
-        // with a count
-        verifyRecurType("FREQ=DAILY;INTERVAL=5000",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     5000,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @SmallTest
-    public void test10() throws Exception {
-        // verifyRecurType all of the BY* ones with one element
-        verifyRecurType("FREQ=DAILY"
-                + ";BYSECOND=0"
-                + ";BYMINUTE=1"
-                + ";BYHOUR=2"
-                + ";BYMONTHDAY=30"
-                + ";BYYEARDAY=300"
-                + ";BYWEEKNO=53"
-                + ";BYMONTH=12"
-                + ";BYSETPOS=-15"
-                + ";WKST=SU",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   new int[]{0},
-                /* int[] byminute */   new int[]{1},
-                /* int[] byhour */     new int[]{2},
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ new int[]{30},
-                /* int[] byyearday */  new int[]{300},
-                /* int[] byweekno */   new int[]{53},
-                /* int[] bymonth */    new int[]{12},
-                /* int[] bysetpos */   new int[]{-15},
-                /* int wkst */         EventRecurrence.SU
-        );
-    }
-
-    @SmallTest
-    public void test11() throws Exception {
-        // verifyRecurType all of the BY* ones with one element
-        verifyRecurType("FREQ=DAILY"
-                + ";BYSECOND=0,30,59"
-                + ";BYMINUTE=0,41,59"
-                + ";BYHOUR=0,4,23"
-                + ";BYMONTHDAY=-31,-1,1,31"
-                + ";BYYEARDAY=-366,-1,1,366"
-                + ";BYWEEKNO=-53,-1,1,53"
-                + ";BYMONTH=1,12"
-                + ";BYSETPOS=1,2,3,4,500,10000"
-                + ";WKST=SU",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   new int[]{0, 30, 59},
-                /* int[] byminute */   new int[]{0, 41, 59},
-                /* int[] byhour */     new int[]{0, 4, 23},
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ new int[]{-31, -1, 1, 31},
-                /* int[] byyearday */  new int[]{-366, -1, 1, 366},
-                /* int[] byweekno */   new int[]{-53, -1, 1, 53},
-                /* int[] bymonth */    new int[]{1, 12},
-                /* int[] bysetpos */   new int[]{1, 2, 3, 4, 500, 10000},
-                /* int wkst */         EventRecurrence.SU
-        );
-    }
-
-    private static class Check {
-        Check(String k, int... v) {
-            key = k;
-            values = v;
-        }
-
-        String key;
-        int[] values;
-    }
-
-    // this is a negative verifyRecurType case to verifyRecurType the range of the numbers accepted
-    @SmallTest
-    public void test12() throws Exception {
-        Check[] checks = new Check[]{
-                new Check("BYSECOND", -100, -1, 60, 100),
-                new Check("BYMINUTE", -100, -1, 60, 100),
-                new Check("BYHOUR", -100, -1, 24, 100),
-                new Check("BYMONTHDAY", -100, -32, 0, 32, 100),
-                new Check("BYYEARDAY", -400, -367, 0, 367, 400),
-                new Check("BYWEEKNO", -100, -54, 0, 54, 100),
-                new Check("BYMONTH", -100, -5, 0, 13, 100)
-        };
-
-        for (Check ck : checks) {
-            for (int n : ck.values) {
-                String recur = "FREQ=DAILY;" + ck.key + "=" + n;
-                try {
-                    EventRecurrence er = new EventRecurrence();
-                    er.parse(recur);
-                    fail("Negative verifyRecurType failed. "
-                            + " parse failed to throw an exception for '"
-                            + recur + "'");
-                } catch (EventRecurrence.InvalidFormatException e) {
-                    // expected
-                }
-            }
-        }
-    }
-
-    // verifyRecurType BYDAY
-    @SmallTest
-    public void test13() throws Exception {
-        verifyRecurType("FREQ=DAILY;BYDAY=1SU,-2MO,+33TU,WE,TH,FR,SA",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.SU,
-                        EventRecurrence.MO,
-                        EventRecurrence.TU,
-                        EventRecurrence.WE,
-                        EventRecurrence.TH,
-                        EventRecurrence.FR,
-                        EventRecurrence.SA
-                },
-                /* int[] bydayNum */   new int[]{1, -2, 33, 0, 0, 0, 0},
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    @Suppress
-    // Repro bug #2331761 - this should fail because of the last comma into BYDAY
-    public void test14() throws Exception {
-        verifyRecurType("FREQ=WEEKLY;WKST=MO;UNTIL=20100129T130000Z;INTERVAL=1;BYDAY=MO,TU,WE,",
-                /* int freq */         EventRecurrence.WEEKLY,
-                /* String until */     "20100129T130000Z",
-                /* int count */        0,
-                /* int interval */     1,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.MO,
-                        EventRecurrence.TU,
-                        EventRecurrence.WE,
-                },
-                /* int[] bydayNum */   new int[]{0, 0, 0},
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // This test should pass
-    public void test15() throws Exception {
-        verifyRecurType("FREQ=WEEKLY;WKST=MO;UNTIL=20100129T130000Z;INTERVAL=1;"
-                + "BYDAY=MO,TU,WE,TH,FR,SA,SU",
-                /* int freq */         EventRecurrence.WEEKLY,
-                /* String until */     "20100129T130000Z",
-                /* int count */        0,
-                /* int interval */     1,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.MO,
-                        EventRecurrence.TU,
-                        EventRecurrence.WE,
-                        EventRecurrence.TH,
-                        EventRecurrence.FR,
-                        EventRecurrence.SA,
-                        EventRecurrence.SU
-                },
-                /* int[] bydayNum */   new int[]{0, 0, 0, 0, 0, 0, 0},
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // Sample coming from RFC2445
-    public void test16() throws Exception {
-        verifyRecurType("FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1",
-                /* int freq */         EventRecurrence.MONTHLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.MO,
-                        EventRecurrence.TU,
-                        EventRecurrence.WE,
-                        EventRecurrence.TH,
-                        EventRecurrence.FR
-                },
-                /* int[] bydayNum */   new int[] {0, 0, 0, 0, 0},
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   new int[] { -1 },
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // Sample coming from RFC2445
-    public void test17() throws Exception {
-        verifyRecurType("FREQ=DAILY;COUNT=10;INTERVAL=2",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        10,
-                /* int interval */     2,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // Sample coming from RFC2445
-    public void test18() throws Exception {
-        verifyRecurType("FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10",
-                /* int freq */         EventRecurrence.YEARLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.SU
-                },
-                /* int[] bydayNum */   new int[] { -1 },
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    new int[] { 10 },
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // Sample coming from bug #1640517
-    public void test19() throws Exception {
-        verifyRecurType("FREQ=YEARLY;BYMONTH=3;BYDAY=TH",
-                /* int freq */         EventRecurrence.YEARLY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      new int[] {
-                        EventRecurrence.TH
-                },
-                /* int[] bydayNum */   new int[] { 0 },
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    new int[] { 3 },
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    // for your copying pleasure
-    public void fakeTestXX() throws Exception {
-        verifyRecurType("FREQ=DAILY;",
-                /* int freq */         EventRecurrence.DAILY,
-                /* String until */     null,
-                /* int count */        0,
-                /* int interval */     0,
-                /* int[] bysecond */   null,
-                /* int[] byminute */   null,
-                /* int[] byhour */     null,
-                /* int[] byday */      null,
-                /* int[] bydayNum */   null,
-                /* int[] bymonthday */ null,
-                /* int[] byyearday */  null,
-                /* int[] byweekno */   null,
-                /* int[] bymonth */    null,
-                /* int[] bysetpos */   null,
-                /* int wkst */         EventRecurrence.MO
-        );
-    }
-
-    private static void cmp(int vlen, int[] v, int[] correct, String name) {
-        if ((correct == null && v != null)
-                || (correct != null && v == null)) {
-            throw new RuntimeException("One is null, one isn't for " + name
-                    + ": correct=" + Arrays.toString(correct)
-                    + " actual=" + Arrays.toString(v));
-        }
-        if ((correct == null && vlen != 0)
-                || (vlen != (correct == null ? 0 : correct.length))) {
-            throw new RuntimeException("Reported length mismatch for " + name
-                    + ": correct=" + ((correct == null) ? "null" : correct.length)
-                    + " actual=" + vlen);
-        }
-        if (correct == null) {
-            return;
-        }
-        if (v.length < correct.length) {
-            throw new RuntimeException("Array length mismatch for " + name
-                    + ": correct=" + Arrays.toString(correct)
-                    + " actual=" + Arrays.toString(v));
-        }
-        for (int i = 0; i < correct.length; i++) {
-            if (v[i] != correct[i]) {
-                throw new RuntimeException("Array value mismatch for " + name
-                        + ": correct=" + Arrays.toString(correct)
-                        + " actual=" + Arrays.toString(v));
-            }
-        }
-    }
-
-    private static boolean eq(String a, String b) {
-        if ((a == null && b != null) || (a != null && b == null)) {
-            return false;
-        } else {
-            return a == b || a.equals(b);
-        }
-    }
-
-    private static void verifyRecurType(String recur,
-            int freq, String until, int count, int interval,
-            int[] bysecond, int[] byminute, int[] byhour,
-            int[] byday, int[] bydayNum, int[] bymonthday,
-            int[] byyearday, int[] byweekno, int[] bymonth,
-            int[] bysetpos, int wkst) {
-        EventRecurrence eventRecurrence = new EventRecurrence();
-        eventRecurrence.parse(recur);
-        if (eventRecurrence.freq != freq
-                || !eq(eventRecurrence.until, until)
-                || eventRecurrence.count != count
-                || eventRecurrence.interval != interval
-                || eventRecurrence.wkst != wkst) {
-            System.out.println("Error... got:");
-            print(eventRecurrence);
-            System.out.println("expected:");
-            System.out.println("{");
-            System.out.println("    freq=" + freq);
-            System.out.println("    until=" + until);
-            System.out.println("    count=" + count);
-            System.out.println("    interval=" + interval);
-            System.out.println("    wkst=" + wkst);
-            System.out.println("    bysecond=" + Arrays.toString(bysecond));
-            System.out.println("    byminute=" + Arrays.toString(byminute));
-            System.out.println("    byhour=" + Arrays.toString(byhour));
-            System.out.println("    byday=" + Arrays.toString(byday));
-            System.out.println("    bydayNum=" + Arrays.toString(bydayNum));
-            System.out.println("    bymonthday=" + Arrays.toString(bymonthday));
-            System.out.println("    byyearday=" + Arrays.toString(byyearday));
-            System.out.println("    byweekno=" + Arrays.toString(byweekno));
-            System.out.println("    bymonth=" + Arrays.toString(bymonth));
-            System.out.println("    bysetpos=" + Arrays.toString(bysetpos));
-            System.out.println("}");
-            throw new RuntimeException("Mismatch in fields");
-        }
-        cmp(eventRecurrence.bysecondCount, eventRecurrence.bysecond, bysecond, "bysecond");
-        cmp(eventRecurrence.byminuteCount, eventRecurrence.byminute, byminute, "byminute");
-        cmp(eventRecurrence.byhourCount, eventRecurrence.byhour, byhour, "byhour");
-        cmp(eventRecurrence.bydayCount, eventRecurrence.byday, byday, "byday");
-        cmp(eventRecurrence.bydayCount, eventRecurrence.bydayNum, bydayNum, "bydayNum");
-        cmp(eventRecurrence.bymonthdayCount, eventRecurrence.bymonthday, bymonthday, "bymonthday");
-        cmp(eventRecurrence.byyeardayCount, eventRecurrence.byyearday, byyearday, "byyearday");
-        cmp(eventRecurrence.byweeknoCount, eventRecurrence.byweekno, byweekno, "byweekno");
-        cmp(eventRecurrence.bymonthCount, eventRecurrence.bymonth, bymonth, "bymonth");
-        cmp(eventRecurrence.bysetposCount, eventRecurrence.bysetpos, bysetpos, "bysetpos");
-    }
-
-    private static void print(EventRecurrence er) {
-        System.out.println("{");
-        System.out.println("    freq=" + er.freq);
-        System.out.println("    until=" + er.until);
-        System.out.println("    count=" + er.count);
-        System.out.println("    interval=" + er.interval);
-        System.out.println("    wkst=" + er.wkst);
-        System.out.println("    bysecond=" + Arrays.toString(er.bysecond));
-        System.out.println("    bysecondCount=" + er.bysecondCount);
-        System.out.println("    byminute=" + Arrays.toString(er.byminute));
-        System.out.println("    byminuteCount=" + er.byminuteCount);
-        System.out.println("    byhour=" + Arrays.toString(er.byhour));
-        System.out.println("    byhourCount=" + er.byhourCount);
-        System.out.println("    byday=" + Arrays.toString(er.byday));
-        System.out.println("    bydayNum=" + Arrays.toString(er.bydayNum));
-        System.out.println("    bydayCount=" + er.bydayCount);
-        System.out.println("    bymonthday=" + Arrays.toString(er.bymonthday));
-        System.out.println("    bymonthdayCount=" + er.bymonthdayCount);
-        System.out.println("    byyearday=" + Arrays.toString(er.byyearday));
-        System.out.println("    byyeardayCount=" + er.byyeardayCount);
-        System.out.println("    byweekno=" + Arrays.toString(er.byweekno));
-        System.out.println("    byweeknoCount=" + er.byweeknoCount);
-        System.out.println("    bymonth=" + Arrays.toString(er.bymonth));
-        System.out.println("    bymonthCount=" + er.bymonthCount);
-        System.out.println("    bysetpos=" + Arrays.toString(er.bysetpos));
-        System.out.println("    bysetposCount=" + er.bysetposCount);
-        System.out.println("}");
-    }
-
-
-    /** A list of valid rules.  The parser must accept these. */
-    private static final String[] GOOD_RRULES = {
-        /* extracted wholesale from from RFC 2445 section 4.8.5.4 */
-        "FREQ=DAILY;COUNT=10",
-        "FREQ=DAILY;UNTIL=19971224T000000Z",
-        "FREQ=DAILY;INTERVAL=2",
-        "FREQ=DAILY;INTERVAL=10;COUNT=5",
-        "FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA",
-        "FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1",
-        "FREQ=WEEKLY;COUNT=10",
-        "FREQ=WEEKLY;UNTIL=19971224T000000Z",
-        "FREQ=WEEKLY;INTERVAL=2;WKST=SU",
-        "FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH",
-        "FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH",
-        "FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR",
-        "FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH",
-        "FREQ=MONTHLY;COUNT=10;BYDAY=1FR",
-        "FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR",
-        "FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU",
-        "FREQ=MONTHLY;COUNT=6;BYDAY=-2MO",
-        "FREQ=MONTHLY;BYMONTHDAY=-3",
-        "FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15",
-        "FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1",
-        "FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,15",
-        "FREQ=MONTHLY;INTERVAL=2;BYDAY=TU",
-        "FREQ=YEARLY;COUNT=10;BYMONTH=6,7",
-        "FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3",
-        "FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200",
-        "FREQ=YEARLY;BYDAY=20MO",
-        "FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO",
-        "FREQ=YEARLY;BYMONTH=3;BYDAY=TH",
-        "FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8",
-        "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13",
-        "FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13",
-        "FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8",
-        "FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3",
-        "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2",
-        "FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z",
-        "FREQ=MINUTELY;INTERVAL=15;COUNT=6",
-        "FREQ=MINUTELY;INTERVAL=90;COUNT=4",
-        "FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40",
-        "FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16",
-        "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO",
-        "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU",
-        /* a few more */
-        "FREQ=SECONDLY;BYSECOND=0,15,59",
-        "FREQ=MINUTELY;BYMINUTE=0,15,59",
-        "FREQ=HOURLY;BYHOUR=+0,+15,+23",
-        "FREQ=DAILY;X-WHATEVER=blah",                       // fails on old parser
-        //"freq=daily;wkst=su",                               // fails on old parser
-    };
-
-    /** The parser must reject these. */
-    private static final String[] BAD_RRULES = {
-        "INTERVAL=4;FREQ=YEARLY",                           // FREQ must come first
-        "FREQ=MONTHLY;FREQ=MONTHLY",                        // can't specify twice
-        "FREQ=MONTHLY;COUNT=1;COUNT=1",                     // can't specify twice
-        "FREQ=SECONDLY;BYSECOND=60",                        // range
-        "FREQ=MINUTELY;BYMINUTE=-1",                        // range
-        "FREQ=HOURLY;BYHOUR=24",                            // range
-        "FREQ=YEARLY;BYMONTHDAY=0",                         // zero not valid
-        //"FREQ=YEARLY;COUNT=1;UNTIL=12345",                  // can't have both COUNT and UNTIL
-        //"FREQ=DAILY;UNTIL=19970829T021400e",                // invalid date
-    };
-
-    /**
-     * Simple test of good/bad rules.
-     */
-    @SmallTest
-    public void testBasicParse() {
-        for (String rule : GOOD_RRULES) {
-            EventRecurrence recur = new EventRecurrence();
-            recur.parse(rule);
-        }
-
-        for (String rule : BAD_RRULES) {
-            EventRecurrence recur = new EventRecurrence();
-            boolean didThrow = false;
-
-            try {
-                recur.parse(rule);
-            } catch (InvalidFormatException ife) {
-                didThrow = true;
-            }
-
-            assertTrue("Expected throw on " + rule, didThrow);
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/pim/RecurrenceSetTest.java b/core/tests/coretests/src/android/pim/RecurrenceSetTest.java
deleted file mode 100644
index e5ab179..0000000
--- a/core/tests/coretests/src/android/pim/RecurrenceSetTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.pim;
-
-import android.content.ContentValues;
-import android.pim.ICalendar;
-import android.pim.RecurrenceSet;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-import android.provider.CalendarContract;
-import junit.framework.TestCase;
-
-/**
- * Test some pim.RecurrenceSet functionality.
- */
-public class RecurrenceSetTest extends TestCase {
-
-    // Test a recurrence
-    @SmallTest
-    public void testRecurrenceSet0() throws Exception {
-        String recurrence = "DTSTART;TZID=America/New_York:20080221T070000\n"
-                + "DTEND;TZID=America/New_York:20080221T190000\n"
-                + "RRULE:FREQ=DAILY;UNTIL=20080222T000000Z\n"
-                + "EXDATE:20080222T120000Z";
-        verifyPopulateContentValues(recurrence, "FREQ=DAILY;UNTIL=20080222T000000Z", null,
-                null, "20080222T120000Z", 1203595200000L, "America/New_York", "P43200S", 0);
-    }
-
-    // Test 1 day all-day event
-    @SmallTest
-    public void testRecurrenceSet1() throws Exception {
-        String recurrence = "DTSTART;VALUE=DATE:20090821\nDTEND;VALUE=DATE:20090822\n"
-                + "RRULE:FREQ=YEARLY;WKST=SU";
-        verifyPopulateContentValues(recurrence, "FREQ=YEARLY;WKST=SU", null,
-                null, null, 1250812800000L, "UTC", "P1D", 1);
-    }
-
-    // Test 2 day all-day event
-    @SmallTest
-    public void testRecurrenceSet2() throws Exception {
-        String recurrence = "DTSTART;VALUE=DATE:20090821\nDTEND;VALUE=DATE:20090823\n"
-                + "RRULE:FREQ=YEARLY;WKST=SU";
-        verifyPopulateContentValues(recurrence, "FREQ=YEARLY;WKST=SU", null,
-                null, null, 1250812800000L, "UTC",  "P2D", 1);
-    }
-
-    // run populateContentValues and verify the results
-    private void verifyPopulateContentValues(String recurrence, String rrule, String rdate,
-            String exrule, String exdate, long dtstart, String tzid, String duration, int allDay)
-            throws ICalendar.FormatException {
-        ICalendar.Component recurrenceComponent =
-                new ICalendar.Component("DUMMY", null /* parent */);
-        ICalendar.parseComponent(recurrenceComponent, recurrence);
-        ContentValues values = new ContentValues();
-        RecurrenceSet.populateContentValues(recurrenceComponent, values);
-        Log.d("KS", "values " + values);
-
-        assertEquals(rrule, values.get(android.provider.CalendarContract.Events.RRULE));
-        assertEquals(rdate, values.get(android.provider.CalendarContract.Events.RDATE));
-        assertEquals(exrule, values.get(android.provider.CalendarContract.Events.EXRULE));
-        assertEquals(exdate, values.get(android.provider.CalendarContract.Events.EXDATE));
-        assertEquals(dtstart, (long) values.getAsLong(CalendarContract.Events.DTSTART));
-        assertEquals(tzid, values.get(android.provider.CalendarContract.Events.EVENT_TIMEZONE));
-        assertEquals(duration, values.get(android.provider.CalendarContract.Events.DURATION));
-        assertEquals(allDay,
-                (int) values.getAsInteger(android.provider.CalendarContract.Events.ALL_DAY));
-    }
-}
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 6db67c0..c54e4a1 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -16,23 +16,25 @@
 
 package android.widget;
 
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
+import com.android.frameworks.coretests.R;
 
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.GetChars;
 import android.view.View;
-import android.widget.TextView;
 
 /**
  * TextViewTest tests {@link TextView}.
  */
-public class TextViewTest extends AndroidTestCase {
+public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewTestActivity> {
+
+    public TextViewTest() {
+        super(TextViewTestActivity.class);
+    }
 
     @SmallTest
     public void testArray() throws Exception {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
 
         char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ',
                                 'W', 'o', 'r', 'l', 'd', '!' };
@@ -62,13 +64,13 @@
 
     @SmallTest
     public void testTextDirectionDefault() {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
     }
 
     @SmallTest
     public void testSetGetTextDirection() {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
 
         tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
         assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
@@ -88,7 +90,7 @@
 
     @SmallTest
     public void testGetResolvedTextDirectionLtr() {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         tv.setText("this is a test");
 
         tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
@@ -109,10 +111,10 @@
 
     @SmallTest
     public void testGetResolvedTextDirectionLtrWithInheritance() {
-        LinearLayout ll = new LinearLayout(mContext);
+        LinearLayout ll = new LinearLayout(getActivity());
         ll.setTextDirection(View.TEXT_DIRECTION_RTL);
 
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         tv.setText("this is a test");
         ll.addView(tv);
 
@@ -134,7 +136,7 @@
 
     @SmallTest
     public void testGetResolvedTextDirectionRtl() {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         tv.setText("\u05DD\u05DE"); // hebrew
 
         tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
@@ -155,10 +157,9 @@
 
     @SmallTest
     public void testGetResolvedTextDirectionRtlWithInheritance() {
-        LinearLayout ll = new LinearLayout(mContext);
-        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+        LinearLayout ll = new LinearLayout(getActivity());
 
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         tv.setText("\u05DD\u05DE"); // hebrew
         ll.addView(tv);
 
@@ -169,6 +170,24 @@
         assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
 
         tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        // Force to RTL text direction on the layout
+        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
         assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
 
         tv.setTextDirection(View.TEXT_DIRECTION_LTR);
@@ -180,10 +199,10 @@
 
     @SmallTest
     public void testCharCountHeuristic() {
-        LinearLayout ll = new LinearLayout(mContext);
+        LinearLayout ll = new LinearLayout(getActivity());
         ll.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
 
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
         ll.addView(tv);
 
         tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
@@ -211,4 +230,23 @@
         tv.setText("ab \u05DD\u05DE"); // latin + hebrew at 50% each
         assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
     }
+
+    @SmallTest
+    public void testResetTextDirection() {
+        final TextViewTestActivity activity = getActivity();
+
+        final LinearLayout ll = (LinearLayout) activity.findViewById(R.id.textviewtest_layout);
+        final TextView tv = (TextView) activity.findViewById(R.id.textviewtest_textview);
+
+        getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+                assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+                assertEquals(true, tv.isResolvedTextDirection());
+
+                ll.removeView(tv);
+                assertEquals(false, tv.isResolvedTextDirection());
+            }
+        });
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewTestActivity.java b/core/tests/coretests/src/android/widget/TextViewTestActivity.java
new file mode 100644
index 0000000..1bb4d24
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/TextViewTestActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.widget;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.frameworks.coretests.R;
+
+public class TextViewTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.textview_test);
+    }
+}
diff --git a/docs/html/index.jd b/docs/html/index.jd
index eeeedd0..dce46f9 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -148,19 +148,18 @@
 
     'tv': {
       'layout':"imgLeft",
-      'icon':"tv_s.png",
+      'icon':"GTV_icon_small.png",
       'name':"Google TV",
-      'img':"tv_l.png",
-      'title':"Announcing Google TV!",
-      'desc': "<p><a href='http://www.google.com/tv/'>Google TV</a> is a new platform "
-               + "for television built on Android. Google "
-               + "has partnered with Sony and Logitech to integrate "
-               + "this platform into TVs, blu-ray players, and companion "
-               + "boxes. </p>"
-               + "<p><a href='http://www.google.com/tv/'>Learn more about "
-               + "Google TV &raquo;</a></p>"
+      'img':"GTV_icon_large.png",
+      'title':"Google TV!",
+      'desc': "<p>Build something big. By big, we mean <em>worthy-of-the-living-room</em> big.</p>"
+	        +  " <p>Use <a href='http://code.google.com/tv'>Google TV</a> to bring the power of Android" 
+	        +  " and Google Chrome to television."
+			+  " The average American watches five hours of TV per day. Give them the web and apps"
+			+  " to update their status, listen to music, watch web videos, and much more...</p>"
     },
 
+
     'devphone': {
       'layout':"imgLeft",
       'icon':"devphone-small.png",
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index b4f1b27..18f47a6 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -99,7 +99,7 @@
   <a href="#" onclick="return toggleDiv(this)">
         <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
 width="9px" />
-ADT 12.0.0</a> <em>(June 2011)</em>
+ADT 12.0.0</a> <em>(July 2011)</em>
   <div class="toggleme">
 <dl>
 
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index d4ebf8a..8c4d037 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -66,7 +66,7 @@
 <div class="toggleable opened">
   <a href="#" onclick="return toggleDiv(this)">
         <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
-SDK Tools, Revision 12</a> <em>(June 2011)</em>
+SDK Tools, Revision 12</a> <em>(July 2011)</em>
   <div class="toggleme">
   <dl>
 <dt>Dependencies:</dt>
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index f865753..90f959f 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -95,7 +95,7 @@
         // E.g, /system/apps/Fountain.apk
         //String packageName = rs.getApplicationContext().getPackageResourcePath();
         // For res/raw/fountain.bc, it wil be /com.android.fountain:raw/fountain
-        String resName = resources.getResourceName(resourceID);
+        String resName = resources.getResourceEntryName(resourceID);
         String cacheDir = rs.getApplicationContext().getCacheDir().toString();
 
         Log.v(TAG, "Create script for resource = " + resName);
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index feeb3c3..9725822 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -39,8 +39,6 @@
 public:
     static  sp<ProcessState>    self();
 
-    static  void                setSingleProcess(bool singleProcess);
-
             void                setContextObject(const sp<IBinder>& object);
             sp<IBinder>         getContextObject(const sp<IBinder>& caller);
         
@@ -48,8 +46,6 @@
                                                  const String16& name);
             sp<IBinder>         getContextObject(const String16& name,
                                                  const sp<IBinder>& caller);
-                                                 
-            bool                supportsProcesses() const;
 
             void                startThreadPool();
                         
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 80b7c1c..8c1c593 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -197,6 +197,12 @@
     status_t init(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
                   int32_t cameraId, Size videoSize, int32_t frameRate,
                   bool storeMetaDataInVideoBuffers);
+
+    status_t initWithCameraAccess(
+                  const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+                  int32_t cameraId, Size videoSize, int32_t frameRate,
+                  bool storeMetaDataInVideoBuffers);
+
     status_t isCameraAvailable(const sp<ICamera>& camera,
                                const sp<ICameraRecordingProxy>& proxy,
                                int32_t cameraId);
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 904ce2a..77166ed 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -71,7 +71,8 @@
     bool mUse32BitOffset;
     bool mIsFileSizeLimitExplicitlyRequested;
     bool mPaused;
-    bool mStarted;
+    bool mStarted;  // Writer thread + track threads started successfully
+    bool mWriterThreadStarted;  // Only writer thread started successfully
     off64_t mOffset;
     off_t mMdatOffset;
     uint8_t *mMoovBoxBuffer;
@@ -182,6 +183,7 @@
     void writeLatitude(int degreex10000);
     void writeLongitude(int degreex10000);
     void sendSessionSummary();
+    void release();
 
     MPEG4Writer(const MPEG4Writer &);
     MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 2d4e10d..7264ac4 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -43,8 +43,6 @@
 
 #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
 
-static bool gSingleProcess = false;
-
 
 // ---------------------------------------------------------------------------
 
@@ -82,12 +80,6 @@
     return gProcess;
 }
 
-void ProcessState::setSingleProcess(bool singleProcess)
-{
-    gSingleProcess = singleProcess;
-}
-
-
 void ProcessState::setContextObject(const sp<IBinder>& object)
 {
     setContextObject(object, String16("default"));
@@ -95,11 +87,7 @@
 
 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
 {
-    if (supportsProcesses()) {
-        return getStrongProxyForHandle(0);
-    } else {
-        return getContextObject(String16("default"), caller);
-    }
+    return getStrongProxyForHandle(0);
 }
 
 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
@@ -144,11 +132,6 @@
     return object;
 }
 
-bool ProcessState::supportsProcesses() const
-{
-    return mDriverFD >= 0;
-}
-
 void ProcessState::startThreadPool()
 {
     AutoMutex _l(mLock);
@@ -169,24 +152,19 @@
         AutoMutex _l(mLock);
         mBinderContextCheckFunc = checkFunc;
         mBinderContextUserData = userData;
-        if (mDriverFD >= 0) {
-            int dummy = 0;
+
+        int dummy = 0;
 #if defined(HAVE_ANDROID_OS)
-            status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+        status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
 #else
-            status_t result = INVALID_OPERATION;
+        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.
+        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));
         }
     }
     return mManagesContexts;
@@ -322,10 +300,6 @@
 
 static int open_driver()
 {
-    if (gSingleProcess) {
-        return -1;
-    }
-
     int fd = open("/dev/binder", O_RDWR);
     if (fd >= 0) {
         fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -386,9 +360,8 @@
         mDriverFD = -1;
 #endif
     }
-    if (mDriverFD < 0) {
-        // Need to run without the driver, starting our own thread pool.
-    }
+
+    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
 }
 
 ProcessState::~ProcessState()
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 8120864..62eb24e 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -66,65 +66,6 @@
 }
 
 
-// Input: cacheDir
-// Input: resName
-// Input: extName
-//
-// Note: cacheFile = resName + extName
-//
-// Output: Returns cachePath == cacheDir + cacheFile
-static char *genCacheFileName(const char *cacheDir,
-                              const char *resName,
-                              const char *extName) {
-    char cachePath[512];
-    char cacheFile[sizeof(cachePath)];
-    const size_t kBufLen = sizeof(cachePath) - 1;
-
-    cacheFile[0] = '\0';
-    // Note: resName today is usually something like
-    //       "/com.android.fountain:raw/fountain"
-    if (resName[0] != '/') {
-        // Get the absolute path of the raw/***.bc file.
-
-        // Generate the absolute path.  This doesn't do everything it
-        // should, e.g. if resName is "./out/whatever" it doesn't crunch
-        // the leading "./" out because this if-block is not triggered,
-        // but it'll make do.
-        //
-        if (getcwd(cacheFile, kBufLen) == NULL) {
-            LOGE("Can't get CWD while opening raw/***.bc file\n");
-            return NULL;
-        }
-        // Append "/" at the end of cacheFile so far.
-        strncat(cacheFile, "/", kBufLen);
-    }
-
-    // cacheFile = resName + extName
-    //
-    strncat(cacheFile, resName, kBufLen);
-    if (extName != NULL) {
-        // TODO(srhines): strncat() is a bit dangerous
-        strncat(cacheFile, extName, kBufLen);
-    }
-
-    // Turn the path into a flat filename by replacing
-    // any slashes after the first one with '@' characters.
-    char *cp = cacheFile + 1;
-    while (*cp != '\0') {
-        if (*cp == '/') {
-            *cp = '@';
-        }
-        cp++;
-    }
-
-    // Tack on the file name for the actual cache file path.
-    strncpy(cachePath, cacheDir, kBufLen);
-    strncat(cachePath, cacheFile, kBufLen);
-
-    LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
-    return strdup(cachePath);
-}
-
 bool rsdScriptInit(const Context *rsc,
                      ScriptC *script,
                      char const *resName,
@@ -164,15 +105,12 @@
         goto error;
     }
 
-#if 1
     if (bccLinkFile(drv->mBccScript, "/system/lib/libclcore.bc", 0) != 0) {
         LOGE("bcc: FAILS to link bitcode");
         goto error;
     }
-#endif
-    cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
 
-    if (bccPrepareExecutable(drv->mBccScript, cachePath, 0) != 0) {
+    if (bccPrepareExecutableEx(drv->mBccScript, cacheDir, resName, 0) != 0) {
         LOGE("bcc: FAILS to prepare executable");
         goto error;
     }
@@ -214,14 +152,13 @@
     const char ** mPragmaKeys;
     const char ** mPragmaValues;
 
-    const static int pragmaMax = 16;
     drv->mPragmaCount = bccGetPragmaCount(drv->mBccScript);
     if (drv->mPragmaCount <= 0) {
         drv->mPragmaKeys = NULL;
         drv->mPragmaValues = NULL;
     } else {
-        drv->mPragmaKeys = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
-        drv->mPragmaValues = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
+        drv->mPragmaKeys = (const char **) calloc(drv->mPragmaCount, sizeof(const char *));
+        drv->mPragmaValues = (const char **) calloc(drv->mPragmaCount, sizeof(const char *));
         bccGetPragmaList(drv->mBccScript, drv->mPragmaCount, drv->mPragmaKeys, drv->mPragmaValues);
     }
 
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 6df2f73..816d215 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -104,10 +104,9 @@
     public static final int FILE_TYPE_MS_POWERPOINT = 106;
     public static final int FILE_TYPE_ZIP           = 107;
     
-    static class MediaFileType {
-    
-        int fileType;
-        String mimeType;
+    public static class MediaFileType {
+        public final int fileType;
+        public final String mimeType;
         
         MediaFileType(int fileType, String mimeType) {
             this.fileType = fileType;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index c55338a..e8ddd2d 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -101,6 +101,8 @@
  * Java MyMediaScanner handleStringTag.
  * Once MediaScanner processFile returns, an entry is inserted in to the database.
  *
+ * The MediaScanner class is not thread-safe, so it should only be used in a single threaded manner.
+ *
  * {@hide}
  */
 public class MediaScanner
@@ -368,6 +370,34 @@
         }
     }
 
+    private class FileInserter {
+
+        ContentValues[] mValues = new ContentValues[1000];
+        int mIndex = 0;
+
+        public Uri insert(ContentValues values) {
+            if (mIndex == mValues.length) {
+                flush();
+            }
+            mValues[mIndex++] = values;
+            // URI not needed when doing bulk inserts
+            return null;
+        }
+
+        public void flush() {
+            while (mIndex < mValues.length) {
+                mValues[mIndex++] = null;
+            }
+            try {
+                mMediaProvider.bulkInsert(mFilesUri, mValues);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException in FileInserter.flush()", e);
+            }
+            mIndex = 0;
+        }
+    }
+    private FileInserter mFileInserter;
+
     // hashes file path to FileCacheEntry.
     // path should be lower case if mCaseInsensitivePaths is true
     private HashMap<String, FileCacheEntry> mFileCache;
@@ -805,37 +835,31 @@
                 }
             }
 
-            Uri tableUri = mFilesUri;
-            if (!mNoMedia) {
-                if (MediaFile.isVideoFileType(mFileType)) {
-                    tableUri = mVideoUri;
-                } else if (MediaFile.isImageFileType(mFileType)) {
-                    tableUri = mImagesUri;
-                } else if (MediaFile.isAudioFileType(mFileType)) {
-                    tableUri = mAudioUri;
-                }
-            }
             Uri result = null;
             if (rowId == 0) {
                 if (mMtpObjectHandle != 0) {
                     values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
                 }
-                if (tableUri == mFilesUri) {
-                    int format = entry.mFormat;
-                    if (format == 0) {
-                        format = MediaFile.getFormatCode(entry.mPath, mMimeType);
-                    }
-                    values.put(Files.FileColumns.FORMAT, format);
+                int format = entry.mFormat;
+                if (format == 0) {
+                    format = MediaFile.getFormatCode(entry.mPath, mMimeType);
                 }
+                values.put(Files.FileColumns.FORMAT, format);
+
                 // new file, insert it
-                result = mMediaProvider.insert(tableUri, values);
+                if (mFileInserter != null) {
+                    result = mFileInserter.insert(values);
+                } else {
+                    result = mMediaProvider.insert(mFilesUri, values);
+                }
+
                 if (result != null) {
                     rowId = ContentUris.parseId(result);
                     entry.mRowId = rowId;
                 }
             } else {
                 // updated file
-                result = ContentUris.withAppendedId(tableUri, rowId);
+                result = ContentUris.withAppendedId(mFilesUri, rowId);
                 // path should never change, and we want to avoid replacing mixed cased paths
                 // with squashed lower case paths
                 values.remove(MediaStore.MediaColumns.DATA);
@@ -854,7 +878,7 @@
                                         new String[] { genre }, null);
                         if (cursor == null || cursor.getCount() == 0) {
                             // genre does not exist, so create the genre in the genre table
-                            values.clear();
+                            values = new ContentValues();
                             values.put(MediaStore.Audio.Genres.NAME, genre);
                             uri = mMediaProvider.insert(mGenresUri, values);
                         } else {
@@ -876,7 +900,7 @@
 
                 if (uri != null) {
                     // add entry to audio_genre_map
-                    values.clear();
+                    values = new ContentValues();
                     values.put(MediaStore.Audio.Genres.Members.AUDIO_ID, Long.valueOf(rowId));
                     mMediaProvider.insert(uri, values);
                 }
@@ -885,19 +909,19 @@
             if (notifications && !mDefaultNotificationSet) {
                 if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
                         doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
-                    setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, tableUri, rowId);
+                    setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, mFilesUri, rowId);
                     mDefaultNotificationSet = true;
                 }
             } else if (ringtones && !mDefaultRingtoneSet) {
                 if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
                         doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
-                    setSettingIfNotSet(Settings.System.RINGTONE, tableUri, rowId);
+                    setSettingIfNotSet(Settings.System.RINGTONE, mFilesUri, rowId);
                     mDefaultRingtoneSet = true;
                 }
             } else if (alarms && !mDefaultAlarmSet) {
                 if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
                         doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
-                    setSettingIfNotSet(Settings.System.ALARM_ALERT, tableUri, rowId);
+                    setSettingIfNotSet(Settings.System.ALARM_ALERT, mFilesUri, rowId);
                     mDefaultAlarmSet = true;
                 }
             }
@@ -1152,10 +1176,6 @@
             mPlaylistsUri = Playlists.getContentUri(volumeName);
 
             mCaseInsensitivePaths = true;
-            if (!Process.supportsProcesses()) {
-                // Simulator uses host file system, so it should be case sensitive.
-                mCaseInsensitivePaths = false;
-            }
         }
     }
 
@@ -1165,10 +1185,14 @@
             initialize(volumeName);
             prescan(null, true);
             long prescan = System.currentTimeMillis();
+            mFileInserter = new FileInserter();
 
             for (int i = 0; i < directories.length; i++) {
                 processDirectory(directories[i], mClient);
             }
+            mFileInserter.flush();
+            mFileInserter = null;
+
             long scan = System.currentTimeMillis();
             postscan(directories);
             long end = System.currentTimeMillis();
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index b75b11a..76c8569 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -330,7 +330,6 @@
             }
 
             int count = (c == null ? 1 : c.getCount());
-            Log.d(TAG, "count: " + count);
             MtpPropertyList result = new MtpPropertyList(count * mProperties.length,
                     MtpConstants.RESPONSE_OK);
 
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index 7932d34..da190a6 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -32,6 +32,7 @@
     private final String mDescription;
     private final long mReserveSpace;
     private final boolean mRemovable;
+    private final long mMaxFileSize;
 
     public MtpStorage(StorageVolume volume) {
         mStorageId = volume.getStorageId();
@@ -39,6 +40,7 @@
         mDescription = volume.getDescription();
         mReserveSpace = volume.getMtpReserveSpace();
         mRemovable = volume.isRemovable();
+        mMaxFileSize = volume.getMaxFileSize();
     }
 
     /**
@@ -98,4 +100,13 @@
     public final boolean isRemovable() {
         return mRemovable;
     }
+
+   /**
+     * Returns maximum file size for the storage, or zero if it is unbounded.
+     *
+     * @return maximum file size
+     */
+    public long getMaxFileSize() {
+        return mMaxFileSize;
+    }
 }
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 9151799..d0d2d1e 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -45,7 +45,6 @@
     jfieldID    context;
 };
 static fields_t fields;
-static Mutex sLock;
 
 class MyMediaScannerClient : public MediaScannerClient
 {
@@ -159,13 +158,11 @@
     return ((JNIEnv *)env)->ExceptionCheck();
 }
 
-// Call this method with sLock hold
 static MediaScanner *getNativeScanner_l(JNIEnv* env, jobject thiz)
 {
     return (MediaScanner *) env->GetIntField(thiz, fields.context);
 }
 
-// Call this method with sLock hold
 static void setNativeScanner_l(JNIEnv* env, jobject thiz, MediaScanner *s)
 {
     env->SetIntField(thiz, fields.context, (int)s);
@@ -176,7 +173,6 @@
         JNIEnv *env, jobject thiz, jstring path, jobject client)
 {
     LOGV("processDirectory");
-    Mutex::Autolock l(sLock);
     MediaScanner *mp = getNativeScanner_l(env, thiz);
     if (mp == NULL) {
         jniThrowException(env, kRunTimeException, "No scanner available");
@@ -243,7 +239,6 @@
         JNIEnv *env, jobject thiz, jstring locale)
 {
     LOGV("setLocale");
-    Mutex::Autolock l(sLock);
     MediaScanner *mp = getNativeScanner_l(env, thiz);
     if (mp == NULL) {
         jniThrowException(env, kRunTimeException, "No scanner available");
@@ -268,7 +263,6 @@
         JNIEnv *env, jobject thiz, jobject fileDescriptor)
 {
     LOGV("extractAlbumArt");
-    Mutex::Autolock l(sLock);
     MediaScanner *mp = getNativeScanner_l(env, thiz);
     if (mp == NULL) {
         jniThrowException(env, kRunTimeException, "No scanner available");
@@ -339,7 +333,6 @@
 android_media_MediaScanner_native_finalize(JNIEnv *env, jobject thiz)
 {
     LOGV("native_finalize");
-    Mutex::Autolock l(sLock);
     MediaScanner *mp = getNativeScanner_l(env, thiz);
     if (mp == 0) {
         return;
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index aaf85c3..446b630 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -48,6 +48,7 @@
 static jfieldID field_MtpStorage_description;
 static jfieldID field_MtpStorage_reserveSpace;
 static jfieldID field_MtpStorage_removable;
+static jfieldID field_MtpStorage_maxFileSize;
 
 static Mutex sMutex;
 
@@ -228,12 +229,14 @@
         jstring description = (jstring)env->GetObjectField(jstorage, field_MtpStorage_description);
         jlong reserveSpace = env->GetLongField(jstorage, field_MtpStorage_reserveSpace);
         jboolean removable = env->GetBooleanField(jstorage, field_MtpStorage_removable);
+        jlong maxFileSize = env->GetLongField(jstorage, field_MtpStorage_maxFileSize);
 
         const char *pathStr = env->GetStringUTFChars(path, NULL);
         if (pathStr != NULL) {
             const char *descriptionStr = env->GetStringUTFChars(description, NULL);
             if (descriptionStr != NULL) {
-                MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr, reserveSpace, removable);
+                MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr,
+                        reserveSpace, removable, maxFileSize);
                 thread->addStorage(storage);
                 env->ReleaseStringUTFChars(path, pathStr);
                 env->ReleaseStringUTFChars(description, descriptionStr);
@@ -312,6 +315,11 @@
         LOGE("Can't find MtpStorage.mRemovable");
         return -1;
     }
+    field_MtpStorage_maxFileSize = env->GetFieldID(clazz, "mMaxFileSize", "J");
+    if (field_MtpStorage_maxFileSize == NULL) {
+        LOGE("Can't find MtpStorage.mMaxFileSize");
+        return -1;
+    }
     clazz_MtpStorage = (jclass)env->NewGlobalRef(clazz);
 
     clazz = env->FindClass("android/mtp/MtpServer");
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ed8149a..c7e7ced 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -158,12 +158,10 @@
     mVideoSize.width  = -1;
     mVideoSize.height = -1;
 
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
     mInitCheck = init(camera, proxy, cameraId,
                     videoSize, frameRate,
                     storeMetaDataInVideoBuffers);
     if (mInitCheck != OK) releaseCamera();
-    IPCThreadState::self()->restoreCallingIdentity(token);
 }
 
 status_t CameraSource::initCheck() const {
@@ -463,6 +461,22 @@
         bool storeMetaDataInVideoBuffers) {
 
     status_t err = OK;
+    int64_t token = IPCThreadState::self()->clearCallingIdentity();
+    err = initWithCameraAccess(camera, proxy, cameraId,
+                               videoSize, frameRate,
+                               storeMetaDataInVideoBuffers);
+    IPCThreadState::self()->restoreCallingIdentity(token);
+    return err;
+}
+
+status_t CameraSource::initWithCameraAccess(
+        const sp<ICamera>& camera,
+        const sp<ICameraRecordingProxy>& proxy,
+        int32_t cameraId,
+        Size videoSize,
+        int32_t frameRate,
+        bool storeMetaDataInVideoBuffers) {
+    status_t err = OK;
 
     if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) {
         LOGE("Camera connection could not be established.");
@@ -525,6 +539,11 @@
 CameraSource::~CameraSource() {
     if (mStarted) {
         stop();
+    } else if (mInitCheck == OK) {
+        // Camera is initialized but because start() is never called,
+        // the lock on Camera is never released(). This makes sure
+        // Camera's lock is released in this case.
+        releaseCamera();
     }
 }
 
@@ -571,6 +590,7 @@
 void CameraSource::releaseCamera() {
     LOGV("releaseCamera");
     if (mCamera != 0) {
+        int64_t token = IPCThreadState::self()->clearCallingIdentity();
         if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
             LOGV("Camera was cold when we started, stopping preview");
             mCamera->stopPreview();
@@ -580,6 +600,7 @@
             mCamera->unlock();
         }
         mCamera.clear();
+        IPCThreadState::self()->restoreCallingIdentity(token);
     }
     if (mCameraRecordingProxy != 0) {
         mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index f075699..eaad2c3 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -246,6 +246,7 @@
       mIsFileSizeLimitExplicitlyRequested(false),
       mPaused(false),
       mStarted(false),
+      mWriterThreadStarted(false),
       mOffset(0),
       mMdatOffset(0),
       mEstimatedMoovBoxSize(0),
@@ -269,6 +270,7 @@
       mIsFileSizeLimitExplicitlyRequested(false),
       mPaused(false),
       mStarted(false),
+      mWriterThreadStarted(false),
       mOffset(0),
       mMdatOffset(0),
       mEstimatedMoovBoxSize(0),
@@ -538,6 +540,9 @@
 
 void MPEG4Writer::stopWriterThread() {
     LOGD("Stopping writer thread");
+    if (!mWriterThreadStarted) {
+        return;
+    }
 
     {
         Mutex::Autolock autolock(mLock);
@@ -548,6 +553,7 @@
 
     void *dummy;
     pthread_join(mThread, &dummy);
+    mWriterThreadStarted = false;
     LOGD("Writer thread stopped");
 }
 
@@ -603,10 +609,25 @@
     writeInt32(0x40000000);  // w
 }
 
+void MPEG4Writer::release() {
+    close(mFd);
+    mFd = -1;
+    mInitCheck = NO_INIT;
+    mStarted = false;
+}
 
 status_t MPEG4Writer::stop() {
     if (mInitCheck != OK) {
         return OK;
+    } else {
+        if (!mWriterThreadStarted ||
+            !mStarted) {
+            if (mWriterThreadStarted) {
+                stopWriterThread();
+            }
+            release();
+            return OK;
+        }
     }
 
     status_t err = OK;
@@ -637,10 +658,7 @@
 
     // Do not write out movie header on error.
     if (err != OK) {
-        close(mFd);
-        mFd = -1;
-        mInitCheck = NO_INIT;
-        mStarted = false;
+        release();
         return err;
     }
 
@@ -688,11 +706,7 @@
 
     CHECK(mBoxes.empty());
 
-    close(mFd);
-    mFd = -1;
-    mInitCheck = NO_INIT;
-    mStarted = false;
-
+    release();
     return err;
 }
 
@@ -1415,6 +1429,7 @@
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
     pthread_create(&mThread, &attr, ThreadWrapper, this);
     pthread_attr_destroy(&attr);
+    mWriterThreadStarted = true;
     return OK;
 }
 
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index bc04e8c..9085f10 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -871,6 +871,14 @@
     // check space first
     if (mSendObjectFileSize > storage->getFreeSpace())
         return MTP_RESPONSE_STORAGE_FULL;
+    uint64_t maxFileSize = storage->getMaxFileSize();
+    // check storage max file size
+    if (maxFileSize != 0) {
+        // if mSendObjectFileSize is 0xFFFFFFFF, then all we know is the file size
+        // is >= 0xFFFFFFFF
+        if (mSendObjectFileSize > maxFileSize || mSendObjectFileSize == 0xFFFFFFFF)
+            return MTP_RESPONSE_OBJECT_TOO_LARGE;
+    }
 
 LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
     MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp
index fef8066..941e303 100644
--- a/media/mtp/MtpStorage.cpp
+++ b/media/mtp/MtpStorage.cpp
@@ -33,11 +33,13 @@
 namespace android {
 
 MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
-        const char* description, uint64_t reserveSpace, bool removable)
+        const char* description, uint64_t reserveSpace,
+        bool removable, uint64_t maxFileSize)
     :   mStorageID(id),
         mFilePath(filePath),
         mDescription(description),
         mMaxCapacity(0),
+        mMaxFileSize(maxFileSize),
         mReserveSpace(reserveSpace),
         mRemovable(removable)
 {
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index 3e4f40d..e5a2e57 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -31,6 +31,7 @@
     MtpString               mFilePath;
     MtpString               mDescription;
     uint64_t                mMaxCapacity;
+    uint64_t                mMaxFileSize;
     // amount of free space to leave unallocated
     uint64_t                mReserveSpace;
     bool                    mRemovable;
@@ -38,7 +39,7 @@
 public:
                             MtpStorage(MtpStorageID id, const char* filePath,
                                     const char* description, uint64_t reserveSpace,
-                                    bool removable);
+                                    bool removable, uint64_t maxFileSize);
     virtual                 ~MtpStorage();
 
     inline MtpStorageID     getStorageID() const { return mStorageID; }
@@ -50,6 +51,7 @@
     const char*             getDescription() const;
     inline const char*      getPath() const { return (const char *)mFilePath; }
     inline bool             isRemovable() const { return mRemovable; }
+    inline uint64_t         getMaxFileSize() const { return mMaxFileSize; }
 };
 
 }; // namespace android
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index 386182d..28ef239 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -29,21 +29,17 @@
         android:background="@drawable/status_bar_recents_background"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_alignParentBottom="true"
-        android:paddingBottom="@*android:dimen/status_bar_height"
-        android:clipToPadding="false"
-        android:clipChildren="false">
+        android:layout_alignParentBottom="true">
 
         <LinearLayout android:id="@+id/recents_glow"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="0dp"
             android:layout_gravity="bottom"
             android:orientation="horizontal"
-            android:clipToPadding="false"
             android:clipChildren="false"
-            >
-            <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
+            android:layout_marginTop="@*android:dimen/status_bar_height">
+            <com.android.systemui.recent.RecentsVerticalScrollView
+                android:id="@+id/recents_container"
                 android:layout_width="@dimen/status_bar_recents_width"
                 android:layout_height="wrap_content"
                 android:layout_marginRight="0dp"
@@ -51,7 +47,7 @@
                 android:stackFromBottom="true"
                 android:fadingEdge="vertical"
                 android:scrollbars="none"
-                android:fadingEdgeLength="20dip"
+                android:fadingEdgeLength="@*android:dimen/status_bar_height"
                 android:listSelector="@drawable/recents_thumbnail_bg_selector"
                 android:layout_gravity="bottom|left"
                 android:clipToPadding="false"
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Constants.java b/packages/SystemUI/src/com/android/systemui/recent/Constants.java
index 66f9292..8252a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Constants.java
@@ -18,7 +18,8 @@
 
 public class Constants {
     static final int MAX_ESCAPE_ANIMATION_DURATION = 500; // in ms
-    static final float FADE_CONSTANT = 0.5f; // unitless
     static final int SNAP_BACK_DURATION = 250; // in ms
     static final int ESCAPE_VELOCITY = 100; // speed of item required to "curate" it in dp/s
+    public static float ALPHA_FADE_START = 0.8f; // fraction of thumbnail width where fade starts
+    static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width beyond which alpha->0
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index fb7a0a7..f984aac 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -118,12 +118,12 @@
     }
 
     private float getAlphaForOffset(View view, float thumbHeight) {
-        final float fadeHeight = Constants.FADE_CONSTANT * thumbHeight;
+        final float fadeHeight = Constants.ALPHA_FADE_END * thumbHeight;
         float result = 1.0f;
-        if (view.getY() >= thumbHeight) {
-            result = 1.0f - (view.getY() - thumbHeight) / fadeHeight;
-        } else if (view.getY() < 0.0f) {
-            result = 1.0f + (thumbHeight + view.getY()) / fadeHeight;
+        if (view.getY() >= thumbHeight * Constants.ALPHA_FADE_START) {
+            result = 1.0f - (view.getY() - thumbHeight * Constants.ALPHA_FADE_START) / fadeHeight;
+        } else if (view.getY() < thumbHeight * (1.0f - Constants.ALPHA_FADE_START)) {
+            result = 1.0f + (thumbHeight * Constants.ALPHA_FADE_START + view.getY()) / fadeHeight;
         }
         if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
         return result;
@@ -269,7 +269,7 @@
         // This has to happen post-layout, so run it "in the future"
         post(new Runnable() {
             public void run() {
-                scrollTo(0, mLastScrollPosition);
+                scrollTo(mLastScrollPosition, 0);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 711ffa3..27bb0b5 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -118,12 +118,12 @@
     }
 
     private float getAlphaForOffset(View view, float thumbWidth) {
-        final float fadeWidth = Constants.FADE_CONSTANT * thumbWidth;
+        final float fadeWidth = Constants.ALPHA_FADE_END * thumbWidth;
         float result = 1.0f;
-        if (view.getX() >= thumbWidth) {
-            result = 1.0f - (view.getX() - thumbWidth) / fadeWidth;
-        } else if (view.getX() < 0.0f) {
-            result = 1.0f + (thumbWidth + view.getX()) / fadeWidth;
+        if (view.getX() >= thumbWidth*Constants.ALPHA_FADE_START) {
+            result = 1.0f - (view.getX() - thumbWidth*Constants.ALPHA_FADE_START) / fadeWidth;
+        } else if (view.getX() < thumbWidth* (1.0f - Constants.ALPHA_FADE_START)) {
+            result = 1.0f + (thumbWidth*Constants.ALPHA_FADE_START + view.getX()) / fadeWidth;
         }
         if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
         return result;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 5eacad7..b50fd81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -307,7 +307,7 @@
         mDateView.setVisibility(View.INVISIBLE);
 
         // Recents Panel
-        initializeRecentsPanel();
+        updateRecentsPanel();
 
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
@@ -338,7 +338,7 @@
         return lp;
     }
 
-    protected void initializeRecentsPanel() {
+    protected void updateRecentsPanel() {
         // Recents Panel
         boolean visible = false;
         if (mRecentsPanel != null) {
@@ -385,9 +385,9 @@
     // For small-screen devices (read: phones) that lack hardware navigation buttons
     private void addNavigationBar() {
         if (mNavigationBarView == null) return;
-        
+
         mNavigationBarView.reorient();
- 
+
         mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
 
         WindowManagerImpl.getDefault().addView(
@@ -396,7 +396,7 @@
 
     private void repositionNavigationBar() {
         if (mNavigationBarView == null) return;
-        
+
         mNavigationBarView.reorient();
 
         mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
@@ -656,7 +656,7 @@
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
-        initializeRecentsPanel();
+        updateRecentsPanel();
     }
 
 
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index f862d01..75e799c 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -29,7 +29,9 @@
 import android.os.SystemClock;
 import android.security.KeyStore;
 import android.telephony.TelephonyManager;
+import android.text.Editable;
 import android.text.InputType;
+import android.text.TextWatcher;
 import android.text.method.DigitsKeyListener;
 import android.text.method.TextKeyListener;
 import android.util.Log;
@@ -120,15 +122,6 @@
             }
         });
 
-        // We don't currently use the IME for PIN mode, but this will make it work if we ever do...
-        if (!mIsAlpha) {
-            mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                    | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-        } else {
-            mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
-                    | InputType.TYPE_TEXT_VARIATION_PASSWORD);
-        }
-
         mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
         mEmergencyCallButton.setOnClickListener(this);
         mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
@@ -151,14 +144,17 @@
 
         mPasswordEntry.requestFocus();
 
-        // This allows keyboards with overlapping qwerty/numeric keys to choose just the
-        // numeric keys.
+        // This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys.
         if (mIsAlpha) {
             mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
+            mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
+                    | InputType.TYPE_TEXT_VARIATION_PASSWORD);
             // mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
             //      StatusView.LOCK_ICON);
         } else {
             mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+            mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+                    | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
             //mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
             //      StatusView.LOCK_ICON);
         }
@@ -179,6 +175,19 @@
         //mUpdateMonitor.registerSimStateCallback(this);
 
         resetStatusInfo();
+
+        // Poke the wakelock any time the text is modified
+        mPasswordEntry.addTextChangedListener(new TextWatcher() {
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            public void afterTextChanged(Editable s) {
+                mCallback.pokeWakelock();
+            }
+        });
     }
 
     @Override
diff --git a/services/camera/libcameraservice/CameraHardwareStub.h b/services/camera/libcameraservice/CameraHardwareStub.h
index 9b66a76..c6d8756 100644
--- a/services/camera/libcameraservice/CameraHardwareStub.h
+++ b/services/camera/libcameraservice/CameraHardwareStub.h
@@ -73,14 +73,7 @@
         CameraHardwareStub* mHardware;
     public:
         PreviewThread(CameraHardwareStub* hw) :
-#ifdef SINGLE_PROCESS
-            // In single process mode this thread needs to be a java thread,
-            // since we won't be calling through the binder.
-            Thread(true),
-#else
-            Thread(false),
-#endif
-              mHardware(hw) { }
+                Thread(false), mHardware(hw) { }
         virtual void onFirstRef() {
             run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
         }
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 158c778..0b15221 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -1072,7 +1072,7 @@
             throw new IllegalArgumentException("packageName and uid don't match packageName="
                     + packageName);
         }
-        if (callingUid != packageUid && Process.supportsProcesses()) {
+        if (callingUid != packageUid) {
             throw new IllegalArgumentException("packageName and uid don't match packageName="
                     + packageName);
         }
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index b98d2a2..41450d2 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1602,8 +1602,10 @@
             if (linkProperties != null) {
                 String iface = linkProperties.getInterfaceName();
                 if (TextUtils.isEmpty(iface) == false) {
-                    if (DBG) log("resetConnections(" + iface + ")");
-                    NetworkUtils.resetConnections(iface);
+                    if (DBG) {
+                        log("resetConnections(" + iface + ", NetworkUtils.RESET_ALL_ADDRESSES)");
+                    }
+                    NetworkUtils.resetConnections(iface, NetworkUtils.RESET_ALL_ADDRESSES);
                 }
             }
         }
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 54e5432..2e54c99 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1075,18 +1075,22 @@
                             com.android.internal.R.styleable.Storage_mtpReserve, 0);
                     boolean allowMassStorage = a.getBoolean(
                             com.android.internal.R.styleable.Storage_allowMassStorage, false);
+                    // resource parser does not support longs, so XML value is in megabytes
+                    long maxFileSize = a.getInt(
+                            com.android.internal.R.styleable.Storage_maxFileSize, 0) * 1024L * 1024L;
 
                     Slog.d(TAG, "got storage path: " + path + " description: " + description +
                             " primary: " + primary + " removable: " + removable +
                             " emulated: " + emulated +  " mtpReserve: " + mtpReserve +
-                            " allowMassStorage: " + allowMassStorage);
+                            " allowMassStorage: " + allowMassStorage +
+                            " maxFileSize: " + maxFileSize);
                     if (path == null || description == null) {
                         Slog.e(TAG, "path or description is null in readStorageList");
                     } else {
                         String pathString = path.toString();
                         StorageVolume volume = new StorageVolume(pathString,
                                 description.toString(), removable, emulated,
-                                mtpReserve, allowMassStorage);
+                                mtpReserve, allowMassStorage, maxFileSize);
                         if (primary) {
                             if (mPrimaryVolume == null) {
                                 mPrimaryVolume = volume;
diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java
index 15f22c0..f7fe39e 100644
--- a/services/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,8 +16,6 @@
 
 package com.android.server;
 
-import com.android.internal.telephony.TelephonyIntents;
-
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -28,7 +26,6 @@
 import android.database.ContentObserver;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.SntpClient;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -36,12 +33,10 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
-import android.util.Slog;
+import android.util.NtpTrustedTime;
+import android.util.TrustedTime;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Properties;
+import com.android.internal.telephony.TelephonyIntents;
 
 /**
  * Monitors the network time and updates the system time if it is out of sync
@@ -68,14 +63,11 @@
     private static final long POLLING_INTERVAL_SHORTER_MS = 60 * 1000L; // 60 seconds
     /** Number of times to try again */
     private static final int TRY_AGAIN_TIMES_MAX = 3;
-    /** How long to wait for the NTP server to respond. */
-    private static final int MAX_NTP_FETCH_WAIT_MS = 20 * 1000;
     /** If the time difference is greater than this threshold, then update the time. */
     private static final int TIME_ERROR_THRESHOLD_MS = 5 * 1000;
 
     private static final String ACTION_POLL =
             "com.android.server.NetworkTimeUpdateService.action.POLL";
-    private static final String PROPERTIES_FILE = "/etc/gps.conf";
     private static int POLL_REQUEST = 0;
 
     private static final long NOT_SET = -1;
@@ -84,14 +76,14 @@
     private long mNitzZoneSetTime = NOT_SET;
 
     private Context mContext;
+    private TrustedTime mTime;
+
     // NTP lookup is done on this thread and handler
     private Handler mHandler;
     private HandlerThread mThread;
     private AlarmManager mAlarmManager;
     private PendingIntent mPendingPollIntent;
     private SettingsObserver mSettingsObserver;
-    // Address of the NTP server
-    private String mNtpServer;
     // The last time that we successfully fetched the NTP time.
     private long mLastNtpFetchTime = NOT_SET;
     // Keeps track of how many quick attempts were made to fetch NTP time.
@@ -101,6 +93,7 @@
 
     public NetworkTimeUpdateService(Context context) {
         mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         Intent pollIntent = new Intent(ACTION_POLL, null);
         mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
@@ -108,12 +101,6 @@
 
     /** Initialize the receivers and initiate the first NTP request */
     public void systemReady() {
-        mNtpServer = getNtpServerAddress();
-        if (mNtpServer == null) {
-            Slog.e(TAG, "NTP server address not found, not syncing to NTP time");
-            return;
-        }
-
         registerForTelephonyIntents();
         registerForAlarms();
         registerForConnectivityIntents();
@@ -128,27 +115,6 @@
         mSettingsObserver.observe(mContext);
     }
 
-    private String getNtpServerAddress() {
-        String serverAddress = null;
-        FileInputStream stream = null;
-        try {
-            Properties properties = new Properties();
-            File file = new File(PROPERTIES_FILE);
-            stream = new FileInputStream(file);
-            properties.load(stream);
-            serverAddress = properties.getProperty("NTP_SERVER", null);
-        } catch (IOException e) {
-            Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
-        } finally {
-            if (stream != null) {
-                try {
-                    stream.close();
-                } catch (Exception e) {}
-            }
-        }
-        return serverAddress;
-    }
-
     private void registerForTelephonyIntents() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
@@ -189,9 +155,15 @@
         if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + POLLING_INTERVAL_MS
                 || event == EVENT_AUTO_TIME_CHANGED) {
             if (DBG) Log.d(TAG, "Before Ntp fetch");
-            long ntp = getNtpTime();
-            if (DBG) Log.d(TAG, "Ntp = " + ntp);
-            if (ntp > 0) {
+
+            // force refresh NTP cache when outdated
+            if (mTime.getCacheAge() >= POLLING_INTERVAL_MS) {
+                mTime.forceRefresh();
+            }
+
+            // only update when NTP time is fresh
+            if (mTime.getCacheAge() < POLLING_INTERVAL_MS) {
+                final long ntp = mTime.currentTimeMillis();
                 mTryAgainCounter = 0;
                 mLastNtpFetchTime = SystemClock.elapsedRealtime();
                 if (Math.abs(ntp - currentTime) > TIME_ERROR_THRESHOLD_MS) {
@@ -232,15 +204,6 @@
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
     }
 
-    private long getNtpTime() {
-        SntpClient client = new SntpClient();
-        if (client.requestTime(mNtpServer, MAX_NTP_FETCH_WAIT_MS)) {
-            return client.getNtpTime();
-        } else {
-            return 0;
-        }
-    }
-
     /**
      * Checks if the user prefers to automatically set the time.
      */
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index d81dfdb..24d4dd3 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -16,9 +16,6 @@
 
 package com.android.server;
 
-import com.android.internal.R;
-import com.android.internal.telephony.TelephonyProperties;
-
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -54,6 +51,9 @@
 import android.util.Slog;
 import android.util.TrustedTime;
 
+import com.android.internal.R;
+import com.android.internal.telephony.TelephonyProperties;
+
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -63,7 +63,6 @@
 import java.io.PrintWriter;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
-import java.util.Properties;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
@@ -87,7 +86,6 @@
     private static final long TESTING_THRESHOLD = 1 * 1024 * 1024;
 
     private static final long MAX_NTP_CACHE_AGE = 24 * 60 * 60 * 1000;
-    private static final long MAX_NTP_FETCH_WAIT = 20 * 1000;
 
     private long mMaxNtpCacheAge = MAX_NTP_CACHE_AGE;
 
@@ -127,8 +125,6 @@
     private static final int THROTTLE_INDEX_UNINITIALIZED = -1;
     private static final int THROTTLE_INDEX_UNTHROTTLED   =  0;
 
-    private static final String PROPERTIES_FILE = "/etc/gps.conf";
-
     private Intent mPollStickyBroadcast;
 
     private TrustedTime mTime;
@@ -139,8 +135,7 @@
     }
 
     public ThrottleService(Context context) {
-        // TODO: move to using cached NtpTrustedTime
-        this(context, getNetworkManagementService(), new NtpTrustedTime(),
+        this(context, getNetworkManagementService(), NtpTrustedTime.getInstance(context),
                 context.getResources().getString(R.string.config_datause_iface));
     }
 
@@ -341,26 +336,6 @@
                 }
             }, new IntentFilter(ACTION_RESET));
 
-        FileInputStream stream = null;
-        try {
-            Properties properties = new Properties();
-            File file = new File(PROPERTIES_FILE);
-            stream = new FileInputStream(file);
-            properties.load(stream);
-            final String ntpServer = properties.getProperty("NTP_SERVER", null);
-            if (mTime instanceof NtpTrustedTime) {
-                ((NtpTrustedTime) mTime).setNtpServer(ntpServer, MAX_NTP_FETCH_WAIT);
-            }
-        } catch (IOException e) {
-            Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
-        } finally {
-            if (stream != null) {
-                try {
-                    stream.close();
-                } catch (Exception e) {}
-            }
-        }
-
         // use a new thread as we don't want to stall the system for file writes
         mThread = new HandlerThread(TAG);
         mThread.start();
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 29cccb6..d5e8730 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -502,15 +502,6 @@
             = new ArrayList<ProcessRecord>();
 
     /**
-     * List of records for processes that we have started and are waiting
-     * for them to call back.  This is really only needed when running in
-     * single processes mode, in which case we do not have a unique pid for
-     * each process.
-     */
-    final ArrayList<ProcessRecord> mStartingProcesses
-            = new ArrayList<ProcessRecord>();
-
-    /**
      * List of persistent applications that are in the process
      * of being started.
      */
@@ -1960,7 +1951,8 @@
                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
             }
             int pid = Process.start("android.app.ActivityThread",
-                    app.processName, uid, uid, gids, debugFlags, null);
+                    app.processName, uid, uid, gids, debugFlags,
+                    app.info.targetSdkVersion, null);
             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
             synchronized (bs) {
                 if (bs.isOnBattery()) {
@@ -2000,12 +1992,7 @@
             }
             buf.append("}");
             Slog.i(TAG, buf.toString());
-            if (pid == 0 || pid == MY_PID) {
-                // Processes are being emulated with threads.
-                app.pid = MY_PID;
-                app.removed = false;
-                mStartingProcesses.add(app);
-            } else if (pid > 0) {
+            if (pid > 0) {
                 app.pid = pid;
                 app.removed = false;
                 synchronized (mPidsSelfLocked) {
@@ -3605,9 +3592,6 @@
             synchronized (mPidsSelfLocked) {
                 app = mPidsSelfLocked.get(pid);
             }
-        } else if (mStartingProcesses.size() > 0) {
-            app = mStartingProcesses.remove(0);
-            app.setPid(pid);
         } else {
             app = null;
         }
@@ -4041,8 +4025,7 @@
         synchronized(this) {
             int callingUid = Binder.getCallingUid();
             try {
-                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
-                        Process.supportsProcesses()) {
+                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
                     int uid = AppGlobals.getPackageManager()
                             .getPackageUid(packageName);
                     if (uid != Binder.getCallingUid()) {
@@ -4301,8 +4284,7 @@
         }
 
         // Root, system server and our own process get to do everything.
-        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
-            !Process.supportsProcesses()) {
+        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
         }
         // If there is a uid that owns whatever is being accessed, it has
@@ -4446,7 +4428,7 @@
     private final boolean checkUriPermissionLocked(Uri uri, int uid,
             int modeFlags) {
         // Root gets to do everything.
-        if (uid == 0 || !Process.supportsProcesses()) {
+        if (uid == 0) {
             return true;
         }
         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
@@ -5527,8 +5509,8 @@
     // CONTENT PROVIDERS
     // =========================================================
 
-    private final List generateApplicationProvidersLocked(ProcessRecord app) {
-        List providers = null;
+    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
+        List<ProviderInfo> providers = null;
         try {
             providers = AppGlobals.getPackageManager().
                 queryContentProviders(app.processName, app.info.uid,
@@ -5966,7 +5948,7 @@
     }
 
     public static final void installSystemProviders() {
-        List providers;
+        List<ProviderInfo> providers;
         synchronized (mSelf) {
             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
             providers = mSelf.generateApplicationProvidersLocked(app);
@@ -6584,13 +6566,6 @@
     }
     
     public void systemReady(final Runnable goingCallback) {
-        // In the simulator, startRunning will never have been called, which
-        // normally sets a few crucial variables. Do it here instead.
-        if (!Process.supportsProcesses()) {
-            mStartRunning = true;
-            mTopAction = Intent.ACTION_MAIN;
-        }
-
         synchronized(this) {
             if (mSystemReady) {
                 if (goingCallback != null) goingCallback.run();
@@ -7954,14 +7929,6 @@
                     "Starting Norm", "Restarting PERS");
         }
 
-        if (mStartingProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Processes that are starting:");
-            dumpProcessList(pw, this, mStartingProcesses, "    ",
-                    "Starting Norm", "Starting PERS");
-        }
-
         if (mRemovedProcesses.size() > 0) {
             if (needSep) pw.println(" ");
             needSep = true;
@@ -13127,74 +13094,72 @@
 
         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
 
-        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
-            if (app.curRawAdj != app.setRawAdj) {
-                if (app.curRawAdj > FOREGROUND_APP_ADJ
-                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
-                    // If this app is transitioning from foreground to
-                    // non-foreground, have it do a gc.
-                    scheduleAppGcLocked(app);
-                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
-                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
-                    // Likewise do a gc when an app is moving in to the
-                    // background (such as a service stopping).
-                    scheduleAppGcLocked(app);
-                }
+        if (app.curRawAdj != app.setRawAdj) {
+            if (app.curRawAdj > FOREGROUND_APP_ADJ
+                    && app.setRawAdj <= FOREGROUND_APP_ADJ) {
+                // If this app is transitioning from foreground to
+                // non-foreground, have it do a gc.
+                scheduleAppGcLocked(app);
+            } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
+                    && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
+                // Likewise do a gc when an app is moving in to the
+                // background (such as a service stopping).
+                scheduleAppGcLocked(app);
+            }
 
-                if (wasKeeping && !app.keeping) {
-                    // This app is no longer something we want to keep.  Note
-                    // its current wake lock time to later know to kill it if
-                    // it is not behaving well.
-                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
-                    synchronized (stats) {
-                        app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
-                                app.pid, SystemClock.elapsedRealtime());
+            if (wasKeeping && !app.keeping) {
+                // This app is no longer something we want to keep.  Note
+                // its current wake lock time to later know to kill it if
+                // it is not behaving well.
+                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
+                synchronized (stats) {
+                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
+                            app.pid, SystemClock.elapsedRealtime());
+                }
+                app.lastCpuTime = app.curCpuTime;
+            }
+
+            app.setRawAdj = app.curRawAdj;
+        }
+        if (adj != app.setAdj) {
+            if (Process.setOomAdj(app.pid, adj)) {
+                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
+                    TAG, "Set app " + app.processName +
+                    " oom adj to " + adj);
+                app.setAdj = adj;
+            } else {
+                success = false;
+            }
+        }
+        if (app.setSchedGroup != app.curSchedGroup) {
+            app.setSchedGroup = app.curSchedGroup;
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                    "Setting process group of " + app.processName
+                    + " to " + app.curSchedGroup);
+            if (app.waitingToKill != null &&
+                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
+                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+                        app.processName, app.setAdj, app.waitingToKill);
+                Process.killProcessQuiet(app.pid);
+            } else {
+                if (true) {
+                    long oldId = Binder.clearCallingIdentity();
+                    try {
+                        Process.setProcessGroup(app.pid, app.curSchedGroup);
+                    } catch (Exception e) {
+                        Slog.w(TAG, "Failed setting process group of " + app.pid
+                                + " to " + app.curSchedGroup);
+                        e.printStackTrace();
+                    } finally {
+                        Binder.restoreCallingIdentity(oldId);
                     }
-                    app.lastCpuTime = app.curCpuTime;
                 }
-
-                app.setRawAdj = app.curRawAdj;
-            }
-            if (adj != app.setAdj) {
-                if (Process.setOomAdj(app.pid, adj)) {
-                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
-                        TAG, "Set app " + app.processName +
-                        " oom adj to " + adj);
-                    app.setAdj = adj;
-                } else {
-                    success = false;
-                }
-            }
-            if (app.setSchedGroup != app.curSchedGroup) {
-                app.setSchedGroup = app.curSchedGroup;
-                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
-                        "Setting process group of " + app.processName
-                        + " to " + app.curSchedGroup);
-                if (app.waitingToKill != null &&
-                        app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
-                    Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
-                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
-                            app.processName, app.setAdj, app.waitingToKill);
-                    Process.killProcessQuiet(app.pid);
-                } else {
-                    if (true) {
-                        long oldId = Binder.clearCallingIdentity();
+                if (false) {
+                    if (app.thread != null) {
                         try {
-                            Process.setProcessGroup(app.pid, app.curSchedGroup);
-                        } catch (Exception e) {
-                            Slog.w(TAG, "Failed setting process group of " + app.pid
-                                    + " to " + app.curSchedGroup);
-                            e.printStackTrace();
-                        } finally {
-                            Binder.restoreCallingIdentity(oldId);
-                        }
-                    }
-                    if (false) {
-                        if (app.thread != null) {
-                            try {
-                                app.thread.setSchedulingGroup(app.curSchedGroup);
-                            } catch (RemoteException e) {
-                            }
+                            app.thread.setSchedulingGroup(app.curSchedGroup);
+                        } catch (RemoteException e) {
                         }
                     }
                 }
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 4fa3bda..c813d37 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -32,7 +32,6 @@
 import android.location.LocationProvider;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.SntpClient;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -51,6 +50,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.gsm.GsmCellLocation;
 import android.util.Log;
+import android.util.NtpTrustedTime;
 import android.util.SparseIntArray;
 
 import com.android.internal.app.IBatteryStats;
@@ -61,7 +61,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.StringBufferInputStream;
+import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Map.Entry;
@@ -235,13 +235,13 @@
 
     // properties loaded from PROPERTIES_FILE
     private Properties mProperties;
-    private String mNtpServer;
     private String mSuplServerHost;
     private int mSuplServerPort;
     private String mC2KServerHost;
     private int mC2KServerPort;
 
     private final Context mContext;
+    private final NtpTrustedTime mNtpTime;
     private final ILocationManager mLocationManager;
     private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
     private Bundle mLocationExtras = new Bundle();
@@ -286,10 +286,6 @@
     // current setting - 5 minutes
     private static final long RETRY_INTERVAL = 5*60*1000;
 
-    // to avoid injecting bad NTP time, we reject any time fixes that differ from system time
-    // by more than 5 minutes.
-    private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000;
-
     private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {
         public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
             if (listener == null) {
@@ -378,6 +374,7 @@
 
     public GpsLocationProvider(Context context, ILocationManager locationManager) {
         mContext = context;
+        mNtpTime = NtpTrustedTime.getInstance(context);
         mLocationManager = locationManager;
         mNIHandler = new GpsNetInitiatedHandler(context);
 
@@ -418,7 +415,6 @@
             FileInputStream stream = new FileInputStream(file);
             mProperties.load(stream);
             stream.close();
-            mNtpServer = mProperties.getProperty("NTP_SERVER", null);
 
             mSuplServerHost = mProperties.getProperty("SUPL_HOST");
             String portString = mProperties.getProperty("SUPL_PORT");
@@ -530,13 +526,18 @@
         }
         mInjectNtpTimePending = false;
 
-        SntpClient client = new SntpClient();
         long delay;
 
-        if (client.requestTime(mNtpServer, 10000)) {
-            long time = client.getNtpTime();
-            long timeReference = client.getNtpTimeReference();
-            int certainty = (int)(client.getRoundTripTime()/2);
+        // force refresh NTP cache when outdated
+        if (mNtpTime.getCacheAge() >= NTP_INTERVAL) {
+            mNtpTime.forceRefresh();
+        }
+
+        // only update when NTP time is fresh
+        if (mNtpTime.getCacheAge() < NTP_INTERVAL) {
+            long time = mNtpTime.getCachedNtpTime();
+            long timeReference = mNtpTime.getCachedNtpTimeReference();
+            long certainty = mNtpTime.getCacheCertainty();
             long now = System.currentTimeMillis();
 
             Log.d(TAG, "NTP server returned: "
@@ -545,7 +546,7 @@
                     + " certainty: " + certainty
                     + " system time offset: " + (time - now));
 
-            native_inject_time(time, timeReference, certainty);
+            native_inject_time(time, timeReference, (int) certainty);
             delay = NTP_INTERVAL;
         } else {
             if (DEBUG) Log.d(TAG, "requestTime failed");
@@ -1395,7 +1396,7 @@
         Properties extraProp = new Properties();
 
         try {
-            extraProp.load(new StringBufferInputStream(extras));
+            extraProp.load(new StringReader(extras));
         }
         catch (IOException e)
         {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 2a17cbe..d23d0f4 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -204,9 +204,8 @@
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
             IPowerManager powerManager, INetworkStatsService networkStats,
             INetworkManagementService networkManagement) {
-        // TODO: move to using cached NtpTrustedTime
         this(context, activityManager, powerManager, networkStats, networkManagement,
-                new NtpTrustedTime(), getSystemDir());
+                NtpTrustedTime.getInstance(context), getSystemDir());
     }
 
     private static File getSystemDir() {
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index b4bd176..b6834f6 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -27,7 +27,6 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_REMOVED;
-import static android.provider.Settings.Secure.NETSTATS_ENABLED;
 import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
 import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
 import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
@@ -71,7 +70,6 @@
 import android.util.TrustedTime;
 
 import com.android.internal.os.AtomicFile;
-import com.android.server.NativeDaemonConnectorException;
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
 
@@ -175,9 +173,8 @@
 
     public NetworkStatsService(
             Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
-        // TODO: move to using cached NtpTrustedTime
-        this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir(),
-                new DefaultNetworkStatsSettings(context));
+        this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
+                getSystemDir(), new DefaultNetworkStatsSettings(context));
     }
 
     private static File getSystemDir() {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index ea5d26b..d6a15e6 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -778,16 +778,7 @@
             mSeparateProcesses = null;
         }
 
-        Installer installer = new Installer();
-        // Little hacky thing to check if installd is here, to determine
-        // whether we are running on the simulator and thus need to take
-        // care of building the /data file structure ourself.
-        // (apparently the sim now has a working installer)
-        if (installer.ping() && Process.supportsProcesses()) {
-            mInstaller = installer;
-        } else {
-            mInstaller = null;
-        }
+        mInstaller = new Installer();
 
         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
         Display d = wm.getDefaultDisplay();
@@ -806,17 +797,6 @@
 
             mUserManager = new UserManager(mInstaller, mUserAppDataDir);
 
-            if (mInstaller == null) {
-                // Make sure these dirs exist, when we are running in
-                // the simulator.
-                // Make a wide-open directory for random misc stuff.
-                File miscDir = new File(dataDir, "misc");
-                miscDir.mkdirs();
-                mAppDataDir.mkdirs();
-                mUserAppDataDir.mkdirs();
-                mDrmAppPrivateInstallDir.mkdirs();
-            }
-
             readPermissions();
 
             mRestoredSettings = mSettings.readLPw();
@@ -838,104 +818,102 @@
             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
             mDalvikCacheDir = new File(dataDir, "dalvik-cache");
 
-            if (mInstaller != null) {
-                boolean didDexOpt = false;
+            boolean didDexOpt = false;
 
-                /**
-                 * Out of paranoia, ensure that everything in the boot class
-                 * path has been dexed.
-                 */
-                String bootClassPath = System.getProperty("java.boot.class.path");
-                if (bootClassPath != null) {
-                    String[] paths = splitString(bootClassPath, ':');
-                    for (int i=0; i<paths.length; i++) {
-                        try {
-                            if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
-                                libFiles.add(paths[i]);
-                                mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
-                                didDexOpt = true;
-                            }
-                        } catch (FileNotFoundException e) {
-                            Slog.w(TAG, "Boot class path not found: " + paths[i]);
-                        } catch (IOException e) {
-                            Slog.w(TAG, "Exception reading boot class path: " + paths[i], e);
+            /**
+             * Out of paranoia, ensure that everything in the boot class
+             * path has been dexed.
+             */
+            String bootClassPath = System.getProperty("java.boot.class.path");
+            if (bootClassPath != null) {
+                String[] paths = splitString(bootClassPath, ':');
+                for (int i=0; i<paths.length; i++) {
+                    try {
+                        if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
+                            libFiles.add(paths[i]);
+                            mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
+                            didDexOpt = true;
                         }
-                    }
-                } else {
-                    Slog.w(TAG, "No BOOTCLASSPATH found!");
-                }
-
-                /**
-                 * Also ensure all external libraries have had dexopt run on them.
-                 */
-                if (mSharedLibraries.size() > 0) {
-                    Iterator<String> libs = mSharedLibraries.values().iterator();
-                    while (libs.hasNext()) {
-                        String lib = libs.next();
-                        try {
-                            if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
-                                libFiles.add(lib);
-                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
-                                didDexOpt = true;
-                            }
-                        } catch (FileNotFoundException e) {
-                            Slog.w(TAG, "Library not found: " + lib);
-                        } catch (IOException e) {
-                            Slog.w(TAG, "Exception reading library: " + lib, e);
-                        }
+                    } catch (FileNotFoundException e) {
+                        Slog.w(TAG, "Boot class path not found: " + paths[i]);
+                    } catch (IOException e) {
+                        Slog.w(TAG, "Exception reading boot class path: " + paths[i], e);
                     }
                 }
+            } else {
+                Slog.w(TAG, "No BOOTCLASSPATH found!");
+            }
 
-                // Gross hack for now: we know this file doesn't contain any
-                // code, so don't dexopt it to avoid the resulting log spew.
-                libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
-
-                /**
-                 * And there are a number of commands implemented in Java, which
-                 * we currently need to do the dexopt on so that they can be
-                 * run from a non-root shell.
-                 */
-                String[] frameworkFiles = mFrameworkDir.list();
-                if (frameworkFiles != null) {
-                    for (int i=0; i<frameworkFiles.length; i++) {
-                        File libPath = new File(mFrameworkDir, frameworkFiles[i]);
-                        String path = libPath.getPath();
-                        // Skip the file if we alrady did it.
-                        if (libFiles.contains(path)) {
-                            continue;
+            /**
+             * Also ensure all external libraries have had dexopt run on them.
+             */
+            if (mSharedLibraries.size() > 0) {
+                Iterator<String> libs = mSharedLibraries.values().iterator();
+                while (libs.hasNext()) {
+                    String lib = libs.next();
+                    try {
+                        if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
+                            libFiles.add(lib);
+                            mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
+                            didDexOpt = true;
                         }
-                        // Skip the file if it is not a type we want to dexopt.
-                        if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
-                            continue;
-                        }
-                        try {
-                            if (dalvik.system.DexFile.isDexOptNeeded(path)) {
-                                mInstaller.dexopt(path, Process.SYSTEM_UID, true);
-                                didDexOpt = true;
-                            }
-                        } catch (FileNotFoundException e) {
-                            Slog.w(TAG, "Jar not found: " + path);
-                        } catch (IOException e) {
-                            Slog.w(TAG, "Exception reading jar: " + path, e);
-                        }
+                    } catch (FileNotFoundException e) {
+                        Slog.w(TAG, "Library not found: " + lib);
+                    } catch (IOException e) {
+                        Slog.w(TAG, "Exception reading library: " + lib, e);
                     }
                 }
+            }
 
-                if (didDexOpt) {
-                    // If we had to do a dexopt of one of the previous
-                    // things, then something on the system has changed.
-                    // Consider this significant, and wipe away all other
-                    // existing dexopt files to ensure we don't leave any
-                    // dangling around.
-                    String[] files = mDalvikCacheDir.list();
-                    if (files != null) {
-                        for (int i=0; i<files.length; i++) {
-                            String fn = files[i];
-                            if (fn.startsWith("data@app@")
-                                    || fn.startsWith("data@app-private@")) {
-                                Slog.i(TAG, "Pruning dalvik file: " + fn);
-                                (new File(mDalvikCacheDir, fn)).delete();
-                            }
+            // Gross hack for now: we know this file doesn't contain any
+            // code, so don't dexopt it to avoid the resulting log spew.
+            libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
+
+            /**
+             * And there are a number of commands implemented in Java, which
+             * we currently need to do the dexopt on so that they can be
+             * run from a non-root shell.
+             */
+            String[] frameworkFiles = mFrameworkDir.list();
+            if (frameworkFiles != null) {
+                for (int i=0; i<frameworkFiles.length; i++) {
+                    File libPath = new File(mFrameworkDir, frameworkFiles[i]);
+                    String path = libPath.getPath();
+                    // Skip the file if we alrady did it.
+                    if (libFiles.contains(path)) {
+                        continue;
+                    }
+                    // Skip the file if it is not a type we want to dexopt.
+                    if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
+                        continue;
+                    }
+                    try {
+                        if (dalvik.system.DexFile.isDexOptNeeded(path)) {
+                            mInstaller.dexopt(path, Process.SYSTEM_UID, true);
+                            didDexOpt = true;
+                        }
+                    } catch (FileNotFoundException e) {
+                        Slog.w(TAG, "Jar not found: " + path);
+                    } catch (IOException e) {
+                        Slog.w(TAG, "Exception reading jar: " + path, e);
+                    }
+                }
+            }
+
+            if (didDexOpt) {
+                // If we had to do a dexopt of one of the previous
+                // things, then something on the system has changed.
+                // Consider this significant, and wipe away all other
+                // existing dexopt files to ensure we don't leave any
+                // dangling around.
+                String[] files = mDalvikCacheDir.list();
+                if (files != null) {
+                    for (int i=0; i<files.length; i++) {
+                        String fn = files[i];
+                        if (fn.startsWith("data@app@")
+                                || fn.startsWith("data@app-private@")) {
+                            Slog.i(TAG, "Pruning dalvik file: " + fn);
+                            (new File(mDalvikCacheDir, fn)).delete();
                         }
                     }
                 }
@@ -965,11 +943,9 @@
             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
 
-            if (mInstaller != null) {
-                if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
-                mInstaller.moveFiles();
-            }
-            
+            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
+            mInstaller.moveFiles();
+
             // Prune any system packages that no longer exist.
             Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
             while (psit.hasNext()) {
@@ -981,19 +957,12 @@
                     String msg = "System package " + ps.name
                             + " no longer exists; wiping its data";
                     reportSettingsProblem(Log.WARN, msg);
-                    if (mInstaller != null) {
-                        mInstaller.remove(ps.name, 0);
-                        mUserManager.removePackageForAllUsers(ps.name);
-                    }
+                    mInstaller.remove(ps.name, 0);
+                    mUserManager.removePackageForAllUsers(ps.name);
                 }
             }
             
             mAppInstallDir = new File(dataDir, "app");
-            if (mInstaller == null) {
-                // Make sure these dirs exist, when we are running in
-                // the simulator.
-                mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists
-            }
             //look for any incomplete package installations
             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
             //clean up list
@@ -1067,19 +1036,12 @@
 
     void cleanupInstallFailedPackage(PackageSetting ps) {
         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
-        if (mInstaller != null) {
-            int retCode = mInstaller.remove(ps.name, 0);
-            if (retCode < 0) {
-                Slog.w(TAG, "Couldn't remove app data directory for package: "
-                           + ps.name + ", retcode=" + retCode);
-            } else {
-                mUserManager.removePackageForAllUsers(ps.name);
-            }
+        int retCode = mInstaller.remove(ps.name, 0);
+        if (retCode < 0) {
+            Slog.w(TAG, "Couldn't remove app data directory for package: "
+                       + ps.name + ", retcode=" + retCode);
         } else {
-            //for emulator
-            PackageParser.Package pkg = mPackages.get(ps.name);
-            File dataDir = new File(pkg.applicationInfo.dataDir);
-            dataDir.delete();
+            mUserManager.removePackageForAllUsers(ps.name);
         }
         if (ps.codePath != null) {
             if (!ps.codePath.delete()) {
@@ -1562,12 +1524,10 @@
             public void run() {
                 mHandler.removeCallbacks(this);
                 int retCode = -1;
-                if (mInstaller != null) {
-                    retCode = mInstaller.freeCache(freeStorageSize);
-                    if (retCode < 0) {
-                        Slog.w(TAG, "Couldn't clear application caches");
-                    }
-                } //end if mInstaller
+                retCode = mInstaller.freeCache(freeStorageSize);
+                if (retCode < 0) {
+                    Slog.w(TAG, "Couldn't clear application caches");
+                }
                 if (observer != null) {
                     try {
                         observer.onRemoveCompleted(null, (retCode >= 0));
@@ -1587,11 +1547,9 @@
             public void run() {
                 mHandler.removeCallbacks(this);
                 int retCode = -1;
-                if (mInstaller != null) {
-                    retCode = mInstaller.freeCache(freeStorageSize);
-                    if (retCode < 0) {
-                        Slog.w(TAG, "Couldn't clear application caches");
-                    }
+                retCode = mInstaller.freeCache(freeStorageSize);
+                if (retCode < 0) {
+                    Slog.w(TAG, "Couldn't clear application caches");
                 }
                 if(pi != null) {
                     try {
@@ -2850,7 +2808,7 @@
 
     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) {
         boolean performed = false;
-        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0 && mInstaller != null) {
+        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
             String path = pkg.mScanPath;
             int ret = 0;
             try {
@@ -3235,42 +3193,39 @@
                 mOutPermissions[1] = 0;
                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
 
-                // If we have mismatched owners for the data path, we have a
-                // problem (unless we're running in the simulator.)
-                if (mOutPermissions[1] != pkg.applicationInfo.uid && Process.supportsProcesses()) {
+                // If we have mismatched owners for the data path, we have a problem.
+                if (mOutPermissions[1] != pkg.applicationInfo.uid) {
                     boolean recovered = false;
                     if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
                         // If this is a system app, we can at least delete its
                         // current data so the application will still work.
-                        if (mInstaller != null) {
-                            int ret = mInstaller.remove(pkgName, 0);
-                            if (ret >= 0) {
-                                // TODO: Kill the processes first
-                                // Remove the data directories for all users
-                                mUserManager.removePackageForAllUsers(pkgName);
-                                // Old data gone!
-                                String msg = "System package " + pkg.packageName
-                                        + " has changed from uid: "
-                                        + mOutPermissions[1] + " to "
-                                        + pkg.applicationInfo.uid + "; old data erased";
-                                reportSettingsProblem(Log.WARN, msg);
-                                recovered = true;
+                        int ret = mInstaller.remove(pkgName, 0);
+                        if (ret >= 0) {
+                            // TODO: Kill the processes first
+                            // Remove the data directories for all users
+                            mUserManager.removePackageForAllUsers(pkgName);
+                            // Old data gone!
+                            String msg = "System package " + pkg.packageName
+                                    + " has changed from uid: "
+                                    + mOutPermissions[1] + " to "
+                                    + pkg.applicationInfo.uid + "; old data erased";
+                            reportSettingsProblem(Log.WARN, msg);
+                            recovered = true;
 
-                                // And now re-install the app.
-                                ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
-                                        pkg.applicationInfo.uid);
-                                if (ret == -1) {
-                                    // Ack should not happen!
-                                    msg = "System package " + pkg.packageName
-                                            + " could not have data directory re-created after delete.";
-                                    reportSettingsProblem(Log.WARN, msg);
-                                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                                    return null;
-                                }
-                                // Create data directories for all users
-                                mUserManager.installPackageForAllUsers(pkgName,
-                                        pkg.applicationInfo.uid);
+                            // And now re-install the app.
+                            ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+                                    pkg.applicationInfo.uid);
+                            if (ret == -1) {
+                                // Ack should not happen!
+                                msg = "System package " + pkg.packageName
+                                        + " could not have data directory re-created after delete.";
+                                reportSettingsProblem(Log.WARN, msg);
+                                mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+                                return null;
                             }
+                            // Create data directories for all users
+                            mUserManager.installPackageForAllUsers(pkgName,
+                                    pkg.applicationInfo.uid);
                         }
                         if (!recovered) {
                             mHasSystemUidErrors = true;
@@ -3303,25 +3258,16 @@
                         Log.v(TAG, "Want this data dir: " + dataPath);
                 }
                 //invoke installer to do the actual installation
-                if (mInstaller != null) {
-                    int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
-                            pkg.applicationInfo.uid);
-                    if (ret < 0) {
-                        // Error from installer
-                        mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                        return null;
-                    }
-                    // Create data directories for all users
-                    mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
-                } else {
-                    dataPath.mkdirs();
-                    if (dataPath.exists()) {
-                        FileUtils.setPermissions(
-                            dataPath.toString(),
-                            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-                            pkg.applicationInfo.uid, pkg.applicationInfo.uid);
-                    }
+                int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+                        pkg.applicationInfo.uid);
+                if (ret < 0) {
+                    // Error from installer
+                    mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+                    return null;
                 }
+                // Create data directories for all users
+                mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
+
                 if (dataPath.exists()) {
                     pkg.applicationInfo.dataDir = dataPath.getPath();
                 } else {
@@ -3352,65 +3298,62 @@
             pkgSetting.uidError = uidError;
         }
 
-        // If we're running in the simulator, we don't need to unpack anything.
-        if (mInstaller != null) {
-            String path = scanFile.getPath();
-            /* Note: We don't want to unpack the native binaries for
-             *        system applications, unless they have been updated
-             *        (the binaries are already under /system/lib).
-             *        Also, don't unpack libs for apps on the external card
-             *        since they should have their libraries in the ASEC
-             *        container already.
-             *
-             *        In other words, we're going to unpack the binaries
-             *        only for non-system apps and system app upgrades.
-             */
-            if (pkg.applicationInfo.nativeLibraryDir != null) {
-                try {
-                    final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
-                    final String dataPathString = dataPath.getCanonicalFile().getPath();
+        String path = scanFile.getPath();
+        /* Note: We don't want to unpack the native binaries for
+         *        system applications, unless they have been updated
+         *        (the binaries are already under /system/lib).
+         *        Also, don't unpack libs for apps on the external card
+         *        since they should have their libraries in the ASEC
+         *        container already.
+         *
+         *        In other words, we're going to unpack the binaries
+         *        only for non-system apps and system app upgrades.
+         */
+        if (pkg.applicationInfo.nativeLibraryDir != null) {
+            try {
+                final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
+                final String dataPathString = dataPath.getCanonicalFile().getPath();
 
-                    if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
-                        /*
-                         * Upgrading from a previous version of the OS sometimes
-                         * leaves native libraries in the /data/data/<app>/lib
-                         * directory for system apps even when they shouldn't be.
-                         * Recent changes in the JNI library search path
-                         * necessitates we remove those to match previous behavior.
-                         */
-                        if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
-                            Log.i(TAG, "removed obsolete native libraries for system package "
-                                    + path);
-                        }
-                    } else if (nativeLibraryDir.getCanonicalFile().getParent()
-                            .equals(dataPathString)) {
-                        /*
-                         * If this is an internal application or our
-                         * nativeLibraryPath points to our data directory, unpack
-                         * the libraries. The native library path pointing to the
-                         * data directory for an application in an ASEC container
-                         * can happen for older apps that existed before an OTA to
-                         * Gingerbread.
-                         */
-                        Slog.i(TAG, "Unpacking native libraries for " + path);
-                        mInstaller.unlinkNativeLibraryDirectory(dataPathString);
-                        NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir);
-                    } else {
-                        Slog.i(TAG, "Linking native library dir for " + path);
-                        mInstaller.linkNativeLibraryDirectory(dataPathString,
-                                pkg.applicationInfo.nativeLibraryDir);
+                if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+                    /*
+                     * Upgrading from a previous version of the OS sometimes
+                     * leaves native libraries in the /data/data/<app>/lib
+                     * directory for system apps even when they shouldn't be.
+                     * Recent changes in the JNI library search path
+                     * necessitates we remove those to match previous behavior.
+                     */
+                    if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
+                        Log.i(TAG, "removed obsolete native libraries for system package "
+                                + path);
                     }
-                } catch (IOException ioe) {
-                    Log.e(TAG, "Unable to get canonical file " + ioe.toString());
+                } else if (nativeLibraryDir.getCanonicalFile().getParent()
+                        .equals(dataPathString)) {
+                    /*
+                     * If this is an internal application or our
+                     * nativeLibraryPath points to our data directory, unpack
+                     * the libraries. The native library path pointing to the
+                     * data directory for an application in an ASEC container
+                     * can happen for older apps that existed before an OTA to
+                     * Gingerbread.
+                     */
+                    Slog.i(TAG, "Unpacking native libraries for " + path);
+                    mInstaller.unlinkNativeLibraryDirectory(dataPathString);
+                    NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir);
+                } else {
+                    Slog.i(TAG, "Linking native library dir for " + path);
+                    mInstaller.linkNativeLibraryDirectory(dataPathString,
+                            pkg.applicationInfo.nativeLibraryDir);
                 }
+            } catch (IOException ioe) {
+                Log.e(TAG, "Unable to get canonical file " + ioe.toString());
             }
-            pkg.mScanPath = path;
+        }
+        pkg.mScanPath = path;
 
-            if ((scanMode&SCAN_NO_DEX) == 0) {
-                if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) {
-                    mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
-                    return null;
-                }
+        if ((scanMode&SCAN_NO_DEX) == 0) {
+            if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) {
+                mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
+                return null;
             }
         }
 
@@ -5434,7 +5377,7 @@
 
         void cleanUpResourcesLI() {
             String sourceDir = getCodePath();
-            if (cleanUp() && mInstaller != null) {
+            if (cleanUp()) {
                 int retCode = mInstaller.rmdex(sourceDir);
                 if (retCode < 0) {
                     Slog.w(TAG, "Couldn't remove dex file for package: "
@@ -5662,14 +5605,12 @@
         void cleanUpResourcesLI() {
             String sourceFile = getCodePath();
             // Remove dex file
-            if (mInstaller != null) {
-                int retCode = mInstaller.rmdex(sourceFile);
-                if (retCode < 0) {
-                    Slog.w(TAG, "Couldn't remove dex file for package: "
-                            + " at location "
-                            + sourceFile.toString() + ", retcode=" + retCode);
-                    // we don't consider this to be a failure of the core package deletion
-                }
+            int retCode = mInstaller.rmdex(sourceFile);
+            if (retCode < 0) {
+                Slog.w(TAG, "Couldn't remove dex file for package: "
+                        + " at location "
+                        + sourceFile.toString() + ", retcode=" + retCode);
+                // we don't consider this to be a failure of the core package deletion
             }
             cleanUp();
         }
@@ -6077,9 +6018,7 @@
         }
         if((res.returnCode = setPermissionsLI(newPackage))
                 != PackageManager.INSTALL_SUCCEEDED) {
-            if (mInstaller != null) {
-                mInstaller.rmdex(newPackage.mScanPath);
-            }
+            mInstaller.rmdex(newPackage.mScanPath);
             return;
         } else {
             Log.d(TAG, "New package installed in " + newPackage.mPath);
@@ -6207,15 +6146,8 @@
             } finally {
                 //TODO clean up the extracted public files
             }
-            if (mInstaller != null) {
-                retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
-                        newPackage.applicationInfo.uid);
-            } else {
-                final int filePermissions =
-                        FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP;
-                retCode = FileUtils.setPermissions(newPackage.mPath, filePermissions, -1,
-                                                   newPackage.applicationInfo.uid);
-            }
+            retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
+                    newPackage.applicationInfo.uid);
         } else {
             // The permissions on the resource file was set when it was copied for
             // non forward locked apps and apps on sdcard
@@ -6478,25 +6410,14 @@
             deletedPs = mSettings.mPackages.get(packageName);
         }
         if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
-            if (mInstaller != null) {
-                int retCode = mInstaller.remove(packageName, 0);
-                if (retCode < 0) {
-                    Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
-                               + packageName + ", retcode=" + retCode);
-                    // we don't consider this to be a failure of the core package deletion
-                } else {
-                    // TODO: Kill the processes first
-                    mUserManager.removePackageForAllUsers(packageName);
-                }
+            int retCode = mInstaller.remove(packageName, 0);
+            if (retCode < 0) {
+                Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
+                           + packageName + ", retcode=" + retCode);
+                // we don't consider this to be a failure of the core package deletion
             } else {
-                // for simulator
-                File dataDir;
-                // reader
-                synchronized (mPackages) {
-                    PackageParser.Package pkg = mPackages.get(packageName);
-                    dataDir = new File(pkg.applicationInfo.dataDir);
-                }
-                dataDir.delete();
+                // TODO: Kill the processes first
+                mUserManager.removePackageForAllUsers(packageName);
             }
             schedulePackageCleaning(packageName);
         }
@@ -6745,13 +6666,11 @@
                 return false;
             }
         }
-        if (mInstaller != null) {
-            int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId
-            if (retCode < 0) {
-                Slog.w(TAG, "Couldn't remove cache files for package: "
-                        + packageName);
-                return false;
-            }
+        int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId
+        if (retCode < 0) {
+            Slog.w(TAG, "Couldn't remove cache files for package: "
+                    + packageName);
+            return false;
         }
         return true;
     }
@@ -6797,13 +6716,11 @@
             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
             return false;
         }
-        if (mInstaller != null) {
-            int retCode = mInstaller.deleteCacheFiles(packageName);
-            if (retCode < 0) {
-                Slog.w(TAG, "Couldn't remove cache files for package: "
-                           + packageName);
-                return false;
-            }
+        int retCode = mInstaller.deleteCacheFiles(packageName);
+        if (retCode < 0) {
+            Slog.w(TAG, "Couldn't remove cache files for package: "
+                       + packageName);
+            return false;
         }
         return true;
     }
@@ -6867,14 +6784,10 @@
                 publicSrcDir = applicationInfo.publicSourceDir;
             }
         }
-        if (mInstaller != null) {
-            int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir,
-                    asecPath, pStats);
-            if (res < 0) {
-                return false;
-            } else {
-                return true;
-            }
+        int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir,
+                asecPath, pStats);
+        if (res < 0) {
+            return false;
         }
         return true;
     }
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index d645160..1ab570a 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -630,20 +630,20 @@
     }
 
     /* opens the currently attached USB accessory */
-        public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
-            UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
-            if (currentAccessory == null) {
-                throw new IllegalArgumentException("no accessory attached");
-            }
-            if (!currentAccessory.equals(accessory)) {
-                String error = accessory.toString()
-                        + " does not match current accessory "
-                        + currentAccessory;
-                throw new IllegalArgumentException(error);
-            }
-            mSettingsManager.checkPermission(accessory);
-            return nativeOpenAccessory();
+    public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
+        UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
+        if (currentAccessory == null) {
+            throw new IllegalArgumentException("no accessory attached");
         }
+        if (!currentAccessory.equals(accessory)) {
+            String error = accessory.toString()
+                    + " does not match current accessory "
+                    + currentAccessory;
+            throw new IllegalArgumentException(error);
+        }
+        mSettingsManager.checkPermission(accessory);
+        return nativeOpenAccessory();
+    }
 
     public void setCurrentFunction(String function, boolean makeDefault) {
         if (DEBUG) Slog.d(TAG, "setCurrentFunction(" + function + ") default: " + makeDefault);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index fe57d0d..df5898b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1055,10 +1055,16 @@
                     }
                 }
                 if (!found) {
-                    // ApnContext does not have dcan reorted in data call list.
+                    // ApnContext does not have dcac reported in data call list.
+                    // Fetch all the ApnContexts that map to this dcac which are in
+                    // INITING state too.
                     if (DBG) log("onDataStateChanged(ar): Connected apn not found in the list (" +
                                  apnContext.toString() + ")");
-                    list.add(apnContext);
+                    if (apnContext.getDataConnectionAc() != null) {
+                        list.addAll(apnContext.getDataConnectionAc().getApnListSync());
+                    } else {
+                        list.add(apnContext);
+                    }
                 }
             }
         }
@@ -1110,10 +1116,12 @@
 
             Collection<ApnContext> apns = dcac.getApnListSync();
 
-            // filter out ApnContext with "Connected" state.
+            // filter out ApnContext with "Connected/Connecting" state.
             ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
             for (ApnContext apnContext : apns) {
-                if (apnContext.getState() == State.CONNECTED) {
+                if (apnContext.getState() == State.CONNECTED ||
+                       apnContext.getState() == State.CONNECTING ||
+                       apnContext.getState() == State.INITING) {
                     connectedApns.add(apnContext);
                 }
             }