Reconcile with ics-factoryrom-2-release

Change-Id: Idf18e15df810885a373fb4057f0db064771afc8e
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 30aed33..ca66a4e 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -209,6 +209,8 @@
 
     run_command("LIST OF OPEN FILES", 10, "su", "root", "lsof", NULL);
 
+    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
+
 #ifdef BOARD_HAS_DUMPSTATE
     printf("========================================================\n");
     printf("== Board\n");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 597ab1f..6d66b1b 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -45,6 +45,9 @@
 /* Displays a blocked processes in-kernel wait channel */
 void show_wchan(int pid, const char *name);
 
+/* Runs "showmap" for a process */
+void do_showmap(int pid, const char *name);
+
 /* Play a sound via Stagefright */
 void play_sound(const char* path);
 
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index b2f9e80..14984ec 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -96,6 +96,15 @@
     return;
 }
 
+void do_showmap(int pid, const char *name) {
+    char title[255];
+    char arg[255];
+
+    sprintf(title, "SHOW MAP %d (%s)", pid, name);
+    sprintf(arg, "%d", pid);
+    run_command(title, 10, "su", "root", "showmap", arg, NULL);
+}
+
 /* prints the contents of a file */
 int dump_file(const char *title, const char* path) {
     char buffer[32768];
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index f383af9..7f0ea99 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -657,6 +657,15 @@
      */
     private void setupChangeAnimation(final ViewGroup parent, final int changeReason,
             Animator baseAnimator, final long duration, final View child) {
+
+        // If we already have a listener for this child, then we've already set up the
+        // changing animation we need. Multiple calls for a child may occur when several
+        // add/remove operations are run at once on a container; each one will trigger
+        // changes for the existing children in the container.
+        if (layoutChangeListenerMap.get(child) != null) {
+            return;
+        }
+
         // Make a copy of the appropriate animation
         final Animator anim = baseAnimator.clone();
 
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 380236b4..a1be121 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -55,6 +55,7 @@
     public int mWindowPtr;
 
     private int mStartPos;
+    private final String mName;
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
@@ -85,6 +86,8 @@
     private static native boolean nativePutDouble(int windowPtr, double value, int row, int column);
     private static native boolean nativePutNull(int windowPtr, int row, int column);
 
+    private static native String nativeGetName(int windowPtr);
+
     /**
      * Creates a new empty cursor window and gives it a name.
      * <p>
@@ -100,6 +103,7 @@
      */
     public CursorWindow(String name, boolean localWindow) {
         mStartPos = 0;
+        mName = name;
         mWindowPtr = nativeCreate(name, sCursorWindowSize, localWindow);
         if (mWindowPtr == 0) {
             throw new CursorWindowAllocationException("Cursor window allocation of " +
@@ -130,6 +134,7 @@
             throw new CursorWindowAllocationException("Cursor window could not be "
                     + "created from binder.");
         }
+        mName = nativeGetName(mWindowPtr);
         mCloseGuard.open("close");
     }
 
@@ -157,6 +162,14 @@
     }
 
     /**
+     * Gets the name of this cursor window.
+     * @hide
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
      * Closes the cursor window and frees its underlying resources when all other
      * remaining references have been released.
      */
@@ -778,4 +791,9 @@
         String s = (buff.length() > 980) ? buff.substring(0, 980) : buff.toString();
         return "# Open Cursors=" + total + s;
     }
+
+    @Override
+    public String toString() {
+        return getName() + " {" + Integer.toHexString(mWindowPtr) + "}";
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 00d7ce8..f990be6 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -306,10 +306,6 @@
     /** Used to find out where this object was created in case it never got closed. */
     private final Throwable mStackTrace;
 
-    // System property that enables logging of slow queries. Specify the threshold in ms.
-    private static final String LOG_SLOW_QUERIES_PROPERTY = "db.log.slow_query_threshold";
-    private final int mSlowQueryThreshold;
-
     /** stores the list of statement ids that need to be finalized by sqlite */
     private final ArrayList<Integer> mClosedStatementIds = new ArrayList<Integer>();
 
@@ -1559,11 +1555,6 @@
             String editTable) {
         verifyDbIsOpen();
         BlockGuard.getThreadPolicy().onReadFromDisk();
-        long timeStart = 0;
-
-        if (false || mSlowQueryThreshold != -1) {
-            timeStart = System.currentTimeMillis();
-        }
 
         SQLiteDatabase db = getDbConnection(sql);
         SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(db, sql, editTable);
@@ -1574,24 +1565,6 @@
                     cursorFactory != null ? cursorFactory : mFactory,
                     selectionArgs);
         } finally {
-            if (false || mSlowQueryThreshold != -1) {
-
-                // Force query execution
-                int count = -1;
-                if (cursor != null) {
-                    count = cursor.getCount();
-                }
-
-                long duration = System.currentTimeMillis() - timeStart;
-
-                if (false || duration >= mSlowQueryThreshold) {
-                    Log.v(SQLiteCursor.TAG,
-                          "query (" + duration + " ms): " + driver.toString() + ", args are "
-                                  + (selectionArgs != null
-                                  ? TextUtils.join(",", selectionArgs)
-                                  : "<null>")  + ", count is " + count);
-                }
-            }
             releaseDbConnection(db);
         }
         return cursor;
@@ -1967,7 +1940,6 @@
         setMaxSqlCacheSize(DEFAULT_SQL_CACHE_SIZE);
         mFlags = flags;
         mPath = path;
-        mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1);
         mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         mFactory = factory;
         mPrograms = new WeakHashMap<SQLiteClosable,Object>();
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 94960791..cc057e0 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -18,6 +18,8 @@
 
 import java.util.ArrayList;
 
+import android.os.Build;
+import android.os.SystemProperties;
 import android.util.Log;
 
 /**
@@ -65,6 +67,28 @@
             Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE);
 
     /**
+     * True to enable database performance testing instrumentation.
+     * @hide
+     */
+    public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;
+
+    /**
+     * Determines whether a query should be logged.
+     *
+     * Reads the "db.log.slow_query_threshold" system property, which can be changed
+     * by the user at any time.  If the value is zero, then all queries will
+     * be considered slow.  If the value does not exist, then no queries will
+     * be considered slow.
+     *
+     * This value can be changed dynamically while the system is running.
+     * @hide
+     */
+    public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) {
+        int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1);
+        return slowQueryMillis >= 0 && elapsedTimeMillis > slowQueryMillis;
+    }
+
+    /**
      * Contains statistics about the active pagers in the current process.
      *
      * @see #getPagerStats(PagerStats)
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 7db0914..faf6cba 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -18,6 +18,7 @@
 
 import android.database.CursorWindow;
 import android.os.SystemClock;
+import android.text.TextUtils;
 import android.util.Log;
 
 /**
@@ -32,6 +33,7 @@
 
     private static native int nativeFillWindow(int databasePtr, int statementPtr, int windowPtr,
             int startPos, int offsetParam);
+
     private static native int nativeColumnCount(int statementPtr);
     private static native String nativeColumnName(int statementPtr, int columnIndex);
 
@@ -80,8 +82,24 @@
             acquireReference();
             try {
                 window.acquireReference();
+                int startPos = window.getStartPosition();
                 int numRows = nativeFillWindow(nHandle, nStatement, window.mWindowPtr,
-                        window.getStartPosition(), mOffsetIndex);
+                        startPos, mOffsetIndex);
+                if (SQLiteDebug.DEBUG_LOG_SLOW_QUERIES) {
+                    long elapsed = SystemClock.uptimeMillis() - timeStart;
+                    if (SQLiteDebug.shouldLogSlowQuery(elapsed)) {
+                        Log.d(TAG, "fillWindow took " + elapsed
+                                + " ms: window=\"" + window
+                                + "\", startPos=" + startPos
+                                + ", offset=" + mOffsetIndex
+                                + ", filledRows=" + window.getNumRows()
+                                + ", countedRows=" + numRows
+                                + ", query=\"" + mSql + "\""
+                                + ", args=[" + (mBindArgs != null ?
+                                        TextUtils.join(", ", mBindArgs.values()) : "")
+                                + "]");
+                    }
+                }
                 mDatabase.logTimeStat(mSql, timeStart);
                 return numRows;
             } catch (IllegalStateException e){
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index caad6fd..68f0247 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1687,15 +1687,18 @@
          * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus
          * starts when the parameter is set.
          *
-         * <p>If applications call {@link #autoFocus(AutoFocusCallback)} in this
-         * mode, the focus callback will immediately return with a boolean that
-         * indicates whether the focus is sharp or not. The apps can then decide
-         * if they want to take a picture immediately or to change the focus
-         * mode to auto, and run a full autofocus cycle. The focus position is
-         * locked after autoFocus call. If applications want to resume the
-         * continuous focus, cancelAutoFocus must be called. Restarting the
-         * preview will not resume the continuous autofocus. To stop continuous
-         * focus, applications should change the focus mode to other modes.
+         * <p>Applications can call {@link #autoFocus(AutoFocusCallback)} in
+         * this mode. If the autofocus is in the middle of scanning, the focus
+         * callback will return when it completes. If the autofocus is not
+         * scanning, the focus callback will immediately return with a boolean
+         * that indicates whether the focus is sharp or not. The apps can then
+         * decide if they want to take a picture immediately or to change the
+         * focus mode to auto, and run a full autofocus cycle. The focus
+         * position is locked after autoFocus call. If applications want to
+         * resume the continuous focus, cancelAutoFocus must be called.
+         * Restarting the preview will not resume the continuous autofocus. To
+         * stop continuous focus, applications should change the focus mode to
+         * other modes.
          *
          * @see #FOCUS_MODE_CONTINUOUS_VIDEO
          */
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 5faab36..17a882d 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -326,6 +326,13 @@
     public static final String HOST = getString("ro.build.host");
 
     /**
+     * Returns true if we are running a debug build such as "user-debug" or "eng".
+     * @hide
+     */
+    public static final boolean IS_DEBUGGABLE =
+            SystemProperties.getInt("ro.debuggable", 0) == 1;
+
+    /**
      * Returns the version string for the radio firmware.  May return
      * null (if, for instance, the radio is not currently on).
      */
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index be87946..6ecc640 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -105,6 +105,18 @@
     void removeRoute(String iface, in RouteInfo route);
 
     /**
+     * Add the specified route to a secondary interface
+     * This will go into a special route table to be accessed
+     * via ip rules
+     */
+    void addSecondaryRoute(String iface, in RouteInfo route);
+
+    /**
+     * Remove the specified secondary route.
+     */
+    void removeSecondaryRoute(String iface, in RouteInfo route);
+
+    /**
      * Shuts down the service
      */
     void shutdown();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5754e60..a0652f7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3620,6 +3620,13 @@
                 "pdp_watchdog_max_pdp_reset_fail_count";
 
         /**
+         * The number of milliseconds to delay when checking for data stalls
+         * @hide
+         */
+        public static final String DATA_STALL_ALARM_DELAY_IN_MS =
+                "data_stall_alarm_delay_in_ms";
+
+        /**
          * The interval in milliseconds at which to check gprs registration
          * after the first registration mismatch of gprs and voice service,
          * to detect possible data network registration problems.
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 8ba7bee..5fa4ad0 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1248,6 +1248,8 @@
      */
     public void dismiss() {
         if (isShowing() && mPopupView != null) {
+            mIsShowing = false;
+
             unregisterForScrollChanged();
 
             try {
@@ -1257,7 +1259,6 @@
                     ((ViewGroup) mPopupView).removeView(mContentView);
                 }
                 mPopupView = null;
-                mIsShowing = false;
     
                 if (mOnDismissListener != null) {
                     mOnDismissListener.onDismiss();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index f25d65f..530809b 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -300,6 +300,7 @@
     public boolean hideOverflowMenu() {
         if (mPostedOpenRunnable != null && mMenuView != null) {
             ((View) mMenuView).removeCallbacks(mPostedOpenRunnable);
+            mPostedOpenRunnable = null;
             return true;
         }
 
@@ -653,10 +654,11 @@
 
         public void run() {
             mMenu.changeMenuMode();
-            if (mPopup.tryShow()) {
+            final View menuView = (View) mMenuView;
+            if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) {
                 mOverflowPopup = mPopup;
-                mPostedOpenRunnable = null;
             }
+            mPostedOpenRunnable = null;
         }
     }
 }
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 18d45f7..ed02636 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -216,6 +216,9 @@
         });
 
         final MenuBuilder menu = (MenuBuilder) mode.getMenu();
+        if (mActionMenuPresenter != null) {
+            mActionMenuPresenter.dismissPopupMenus();
+        }
         mActionMenuPresenter = new ActionMenuPresenter(mContext);
         mActionMenuPresenter.setReserveOverflow(true);
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d5450e4..17b8acf 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -439,17 +439,6 @@
     }
 
     /**
-     * Calls back SetupFaceLock to save the temporary gallery file if this is the backup lock.
-     * This doesn't have to verify that biometric is enabled because it's only called in that case
-    */
-    void moveTempGallery() {
-        Intent intent = new Intent().setClassName("com.android.facelock",
-                "com.android.facelock.SetupFaceLock");
-        intent.putExtra("moveTempGallery", true);
-        mContext.startActivity(intent);
-    }
-
-    /**
      * Calls back SetupFaceLock to delete the temporary gallery file
      */
     public void deleteTempGallery() {
@@ -501,8 +490,7 @@
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY,
                             DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
-                    setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
-                    moveTempGallery();
+                    finishBiometricWeak();
                 }
                 dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
                         .size(), 0, 0, 0, 0, 0, 0);
@@ -619,8 +607,7 @@
                 } else {
                     setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
                     setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
-                    setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
-                    moveTempGallery();
+                    finishBiometricWeak();
                 }
                 if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                     int letters = 0;
@@ -1087,4 +1074,16 @@
         }
         return false;
     }
+
+    private void finishBiometricWeak() {
+        setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
+
+        // Launch intent to show final screen, this also
+        // moves the temporary gallery to the actual gallery
+        Intent intent = new Intent();
+        intent.setClassName("com.android.facelock",
+                "com.android.facelock.SetupEndScreen");
+        mContext.startActivity(intent);
+    }
+
 }
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 722aeea..9725c9ff 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -104,6 +104,11 @@
     }
 }
 
+static jstring nativeGetName(JNIEnv* env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    return env->NewStringUTF(window->name().string());
+}
+
 static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jint windowPtr,
         jobject parcelObj) {
     CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
@@ -485,6 +490,8 @@
             (void*)nativeDispose },
     { "nativeWriteToParcel", "(ILandroid/os/Parcel;)V",
             (void*)nativeWriteToParcel },
+    { "nativeGetName", "(I)Ljava/lang/String;",
+            (void*)nativeGetName },
     { "nativeClear", "(I)V",
             (void*)nativeClear },
     { "nativeGetNumRows", "(I)I",
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3ad01a5..f08d105 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -171,7 +171,7 @@
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kry toegang tot beskikbare rekeninge."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardewarekontroles"</string>
     <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkte toegang tot hardeware op die selfoon."</string>
-    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"foonoproepe"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Foonoproepe"</string>
     <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Monitor, neem op, en verwerk foonoproepe."</string>
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Stelselhulpmiddels"</string>
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Laervlak-toegang en -beheer van die stelsel."</string>
@@ -991,8 +991,8 @@
     <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Kon nie jou SD-kaart vir USB-massaberging gebruik nie."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB gekoppel"</string>
     <string name="usb_storage_notification_message" msgid="7380082404288219341">"Kies om lêers na/van jou rekenaar te kopieer."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-geheue af"</string>
-    <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-geheue af te skakel."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-berging af"</string>
+    <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-berging af te skakel."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB-berging in gebruik"</string>
     <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Voordat jy USB-berging afskakel, maak seker dat jy jou Android se USB-berging van jou rekenaar ontheg (\"uitgestoot\") het."</string>
     <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Voordat jy die USB-berging afskakel, maak seker dat jy jou Android se SD-kaart uit die rekenaar ontheg (uitgeskiet) het."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 56b24bb..24f44b2 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -159,7 +159,7 @@
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjenester, der koster dig penge"</string>
     <string name="permgroupdesc_costMoney" msgid="8193824940620517189">"Tillader, at en applikation kan gøre ting, som kan koste penge."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Dine beskeder"</string>
-    <string name="permgroupdesc_messages" msgid="7045736972019211994">"Læs og skriv dine sms-, e-mail- og andre beskeder."</string>
+    <string name="permgroupdesc_messages" msgid="7045736972019211994">"Læs og skriv dine sms-, e-mail og andre beskeder."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Dine personlige oplysninger"</string>
     <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Få direkte adgang til dine kontakter og din kalender, der er gemt på tabletcomputeren."</string>
     <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Få direkte adgang til dine kontakter og din kalender, der er gemt på telefonen."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 22d750b..320c331 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -282,7 +282,7 @@
     <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"Linux-Signale an Apps senden"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Ermöglicht der App, das Senden des gelieferten Signals an alle anhaltenden Prozesse zu fordern"</string>
     <string name="permlab_persistentActivity" msgid="8659652042401085862">"Apps permanent ausführen"</string>
-    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten persistent zu machen, damit das System diese nicht für andere Anwendungen nutzen kann"</string>
+    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten permanent zu machen, damit das System diese nicht für andere Apps nutzen kann"</string>
     <string name="permlab_deletePackages" msgid="3343439331576348805">"Apps löschen"</string>
     <string name="permdesc_deletePackages" msgid="3634943677518723314">"Ermöglicht einer App, Android-Pakete zu löschen. Schädliche Anwendungen können so wichtige Anwendungen löschen."</string>
     <string name="permlab_clearAppUserData" msgid="2192134353540277878">"Daten anderer Apps löschen"</string>
@@ -340,11 +340,11 @@
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"Ohne das Wissen der Eigentümer Kalendertermine hinzufügen oder ändern und E-Mails an Gäste senden"</string>
     <string name="permdesc_writeCalendar" msgid="5368129321997977226">"Ermöglicht einer App das Senden von Termineinladungen als Kalendereigentümer und das Hinzufügen, Entfernen und Ändern von Terminen, die Sie auf Ihrem Gerät bearbeiten können, einschließlich der Termine von Freunden oder Kollegen. Schädliche Apps mit dieser Berechtigung können Spam-E-Mails senden, die von Kalendereigentümern zu kommen scheinen, Termine ohne das Wissen der Eigentümer ändern oder falsche Termine hinzufügen."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Simulierte Standortquellen für Testzwecke"</string>
-    <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt falsche Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string>
+    <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt simulierte Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"Zugriff auf zusätzliche Dienstanbieterbefehle für Standort. Schädliche Anwendungen könnten so die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Berechtigung zur Installation eines Standortanbieters"</string>
-    <string name="permdesc_installLocationProvider" msgid="5449175116732002106">"Erstellt falsche Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben oder Ihren Standort überwachen und an eine externe Quelle weitergeben."</string>
+    <string name="permdesc_installLocationProvider" msgid="5449175116732002106">"Erstellt simulierte Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben oder Ihren Standort überwachen und an eine externe Quelle weitergeben."</string>
     <string name="permlab_accessFineLocation" msgid="8116127007541369477">"Genauer (GPS-) Standort"</string>
     <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Zugriff auf genaue Standortquellen wie GPS auf dem Tablet (falls verfügbar). Schädliche Anwendungen können damit bestimmen, wo Sie sich befinden und so Ihren Akku zusätzlich belasten."</string>
     <string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"Zugriff auf genaue Standortquellen wie GPS auf dem Telefon (falls verfügbar). Schädliche Anwendungen können damit bestimmen, so Sie sich befinden und so Ihren Akku zusätzlich belasten."</string>
@@ -889,7 +889,7 @@
     <string name="capital_on" msgid="1544682755514494298">"AN"</string>
     <string name="capital_off" msgid="6815870386972805832">"AUS"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Aktion durchführen mit"</string>
-    <string name="alwaysUse" msgid="4583018368000610438">"Standardmäßig für diese Aktion verwenden"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Immer für diese Aktion verwenden"</string>
     <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Standardeinstellung zurücksetzen unter \"Einstellungen &gt; Apps &gt; Apps verwalten\""</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Aktion auswählen"</string>
     <string name="chooseUsbActivity" msgid="7892597146032121735">"App für das USB-Gerät auswählen"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 9609c1a..0187413 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1024,7 +1024,7 @@
     <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Verificando errores"</string>
     <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Almacenamiento USB en blanco"</string>
     <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tarjeta SD vacía"</string>
-    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB en blanco o sistema de archivos no compatible."</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB vacío o sistema de archivos no compatible"</string>
     <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"Tarjeta SD en blanco o el sistema de archivos no es compatible."</string>
     <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Almacenamiento USB dañado"</string>
     <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Tarjeta SD dañada"</string>
@@ -1032,7 +1032,7 @@
     <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"Tarjeta SD dañada. Es posible que debas reformatearla."</string>
     <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Almacenamiento USB extraído inesperadamente"</string>
     <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Almacenamiento USB extraído de forma imprevista"</string>
-    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desmontar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desactivar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
     <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Desmontar la tarjeta SD antes de extraerla para evitar la pérdida de datos."</string>
     <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Es seguro extraer el almacenamiento USB"</string>
     <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"Es seguro extraer la tarjeta SD"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 869f971..d956531 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -137,7 +137,7 @@
     <string name="turn_off_radio" msgid="8198784949987062346">"כבה אלחוטי"</string>
     <string name="screen_lock" msgid="799094655496098153">"נעילת מסך"</string>
     <string name="power_off" msgid="4266614107412865048">"כיבוי"</string>
-    <string name="shutdown_progress" msgid="2281079257329981203">"מבצע כיבוי..."</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"מכבה..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"הטבלט שלך יכבה."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"הטלפון שלך יכובה."</string>
     <string name="shutdown_confirm_question" msgid="6656441286856415014">"האם ברצונך לבצע כיבוי?"</string>
@@ -740,7 +740,7 @@
     <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"כתוב את ההיסטוריה והסימניות של הדפדפן"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"מאפשר ליישום לשנות את ההיסטוריה או את הסימניות של הדפדפן המאוחסנות בטבלט. יישומים זדוניים עלולים להשתמש ביכולת זו כדי למחוק או לשנות את הנתונים בדפדפן."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"מאפשר ליישום לשנות את ההיסטוריה או הסימניות של הדפדפן המאוחסנות בטלפון. יישומים זדוניים עלולים להשתמש ביכולת זו כדי למחוק או לשנות את נתוני הדפדפן."</string>
-    <string name="permlab_setAlarm" msgid="5924401328803615165">"הגדר התראה בשעון המעורר"</string>
+    <string name="permlab_setAlarm" msgid="5924401328803615165">"הגדר צלצול בשעון המעורר"</string>
     <string name="permdesc_setAlarm" msgid="5966966598149875082">"מאפשר ליישום להגדיר התראה ביישום מותקן של שעון מעורר. ייתכן שיישומי שעון מעורר מסוימים לא יישמו תכונה זו."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף דואר קולי"</string>
     <string name="permdesc_addVoicemail" msgid="4828507394878206682">"מאפשר ליישום להוסיף הודעות לתיבת הדואר הנכנס של הדואר הקולי."</string>
@@ -895,8 +895,8 @@
     <string name="chooseUsbActivity" msgid="7892597146032121735">"בחר יישום עבור מכשיר ה-USB"</string>
     <string name="noApplications" msgid="1691104391758345586">"אין יישומים שיכולים לבצע פעולה זו."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
-    <string name="aerr_application" msgid="932628488013092776">"למרבה הצער, <xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
-    <string name="aerr_process" msgid="4507058997035697579">"למרבה הצער, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
+    <string name="aerr_application" msgid="932628488013092776">"לצערנו ה<xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n" האם ברצונך לסגור אותו?"</string>
     <string name="anr_activity_process" msgid="7018289416670457797">"פעילות <xliff:g id="ACTIVITY">%1$s</xliff:g> אינה מגיבה."\n\n"האם ברצונך לסגור אותה?"</string>
@@ -940,8 +940,8 @@
     <string name="volume_icon_description_incall" msgid="8890073218154543397">"עוצמת קול של שיחות"</string>
     <string name="volume_icon_description_media" msgid="4217311719665194215">"עוצמת קול של מדיה"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת קול של התראות"</string>
-    <string name="ringtone_default" msgid="3789758980357696936">"רינגטון המוגדר כברירת מחדל"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון המוגדר כברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"רינגטון ברירת מחדל"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון ברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="4440324407807468713">"שקט"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"רינגטונים"</string>
     <string name="ringtone_unknown" msgid="5477919988701784788">"רינגטון לא ידוע"</string>
@@ -982,24 +982,24 @@
     <string name="no_permissions" msgid="7283357728219338112">"לא דרושים אישורים"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"הסתר"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"הצג הכל"</b></string>
-    <string name="usb_storage_activity_title" msgid="2399289999608900443">"אמצעי אחסון גדול מסוג USB"</string>
+    <string name="usb_storage_activity_title" msgid="2399289999608900443">"אחסון USB בנפח גדול"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB מחובר"</string>
-    <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"התחברת למחשב באמצעות USB. גע בלחצן שבהמשך אם ברצונך להעתיק קבצים בין המחשב ואמצעי האחסון מסוג USB של מכשיר Android."</string>
-    <string name="usb_storage_message" product="default" msgid="4510858346516069238">"התחברת למחשב באמצעות USB. גע בלחצן שבהמשך אם ברצונך להעתיק קבצים בין המחשב לבין כרטיס ה-SD של מכשיר ה-Android."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"הפעל אמצעי אחסון מסוג USB"</string>
-    <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"קיימת בעיה בשימוש באמצעי אחסון מסוג USB לאחסון בנפח גדול ב-USB."</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"התחברת למחשב באמצעות USB. גע בלחצן שלמטה אם ברצונך להעתיק קבצים בין המחשב ואמצעי האחסון מסוג USB של מכשיר Android."</string>
+    <string name="usb_storage_message" product="default" msgid="4510858346516069238">"התחברת למחשב באמצעות USB. גע בלחצן שלמטה אם ברצונך להעתיק קבצים בין המחשב לבין כרטיס ה-SD של מכשיר ה-Android."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"הפעל אחסון USB"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"יש בעיה בשימוש ב-USB לאחסון בנפח גדול"</string>
     <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"יש בעיה בשימוש בכרטיס SD לאחסון גדול ב-USB."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB מחובר"</string>
     <string name="usb_storage_notification_message" msgid="7380082404288219341">"בחר כדי להעתיק קבצים למחשב/מהמחשב."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"כבה אמצעי אחסון מסוג USB"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"כבה אחסון USB"</string>
     <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"בחר כאן לכיבוי אחסון USB."</string>
-    <string name="usb_storage_stop_title" msgid="660129851708775853">"אמצעי אחסון מסוג USB שנמצא בשימוש"</string>
-    <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"לפני כיבוי אמצעי אחסון מסוג USB, ודא שביטלת את הטעינה של אמצעי האחסון מסוג USB של Android (\"הוצאת אותו\") מהמחשב."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"לפני הכיבוי של אמצעי אחסון מסוג USB, ודא שהסרת (\"הוצאת\") את כרטיס SD של Android מהמחשב."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"כבה אמצעי אחסון מסוג USB"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"אחסון USB שנמצא בשימוש"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"לפני כיבוי אחסון USB, ודא שביטלת את הטעינה של אמצעי האחסון מסוג USB של Android (\"הוצאת אותו\") מהמחשב."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"לפני הכיבוי של אחסון USB, ודא שהסרת (\"הוצאת\") את כרטיס SD של Android מהמחשב."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"כבה אחסון USB"</string>
     <string name="usb_storage_stop_error_message" msgid="143881914840412108">"היתה בעיה בכיבוי אמצעי האחסון מסוג USB. ודא שביטלת את טעינת מארח ה-USB ולאחר מכן נסה שוב."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"הפעל אמצעי אחסון מסוג USB"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"אם תפעיל אמצעי אחסון מסוג USB, יישומים מסוימים שבהם אתה משתמש יעצרו וייתכן שלא יהיו זמינים עד שתכבה את אמצעי האחסון מסוג USB."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"הפעל אחסון USB"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"אם תפעיל אחסון USB, יישומים מסוימים שבהם אתה משתמש יעצרו וייתכן שלא יהיו זמינים עד שתכבה את אמצעי האחסון מסוג USB."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"פעולת USB נכשלה"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"אישור"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"מחובר כמכשיר מדיה"</string>
@@ -1007,7 +1007,7 @@
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"מחובר כמתקין"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"מחובר לאביזר USB"</string>
     <string name="usb_notification_message" msgid="4447869605109736382">"גע לקבלת אפשרויות USB נוספות"</string>
-    <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"פרמט אמצעי אחסון מסוג USB"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"פרמט אחסון USB"</string>
     <string name="extmedia_format_title" product="default" msgid="8663247929551095854">"פרמוט כרטיס SD"</string>
     <string name="extmedia_format_message" product="nosdcard" msgid="8296908079722897772">"לפרמט את אמצעי האחסון מסוג USB, ולמחוק את כל הקבצים המאוחסנים בו? הפעולה בלתי הפיכה!"</string>
     <string name="extmedia_format_message" product="default" msgid="3621369962433523619">"האם אתה בטוח שברצונך לפרמט את כרטיס ה-SD? כל הנתונים בכרטיס יאבדו."</string>
@@ -1019,7 +1019,7 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string>
-    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"מכין אמצעי אחסון מסוג USB"</string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"מכין אחסון USB"</string>
     <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"מכין את כרטיס SD"</string>
     <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"בודק אם יש שגיאות."</string>
     <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"אמצעי אחסון ריק מסוג USB"</string>
@@ -1030,7 +1030,7 @@
     <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"כרטיס SD פגום"</string>
     <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"אחסון USB נפגם. ייתכן שיהיה עליך לפרמט אותו שוב."</string>
     <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"כרטיס SD פגום. ייתכן שתצטרך לפרמט אותו שוב."</string>
-    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"אמצעי אחסון מסוג USB הוסר באופן בלתי צפוי"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"אחסון USB הוסר באופן בלתי צפוי"</string>
     <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"כרטיס SD הוסר באופן לא צפוי"</string>
     <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"בטל טעינה של אחסון USB לפני הסרתו כדי למנוע אובדן נתונים."</string>
     <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"בטל את טעינת כרטיס SD לפני הסרתו כדי למנוע אובדן נתונים."</string>
@@ -1038,9 +1038,9 @@
     <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"אפשר להסיר את כרטיס SD"</string>
     <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"אתה יכול להסיר בבטחה את אחסון ה-USB."</string>
     <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"ניתן להסיר בבטחה כרטיס SD."</string>
-    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"אמצעי אחסון מסוג USB הוסר"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"אחסון USB הוסר"</string>
     <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"כרטיס SD הוסר"</string>
-    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"אמצעי אחסון מסוג USB הוסר. הכנס מדיה חדשה."</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"אחסון USB הוסר. הכנס מדיה חדשה."</string>
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"כרטיס SD הוסר. הכנס כרטיס חדש."</string>
     <string name="activity_list_empty" msgid="4168820609403385789">"לא נמצאו פעילויות תואמות"</string>
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"עדכן נתונים סטטיסטיים על שימוש ברכיב"</string>
@@ -1096,17 +1096,17 @@
     <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> מתוך <xliff:g id="TOTAL">%d</xliff:g>"</item>
   </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"סיום"</string>
-    <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"מבטל טעינה של אמצעי אחסון מסוג USB..."</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"מבטל טעינה של אחסון USB..."</string>
     <string name="progress_unmounting" product="default" msgid="5556813978958789471">"מבטל טעינה של כרטיס SD..."</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"מוחק אמצעי אחסון מסוג USB..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"מוחק אחסון USB..."</string>
     <string name="progress_erasing" product="default" msgid="2115214724367534095">"מוחק כרטיס SD..."</string>
     <string name="format_error" product="nosdcard" msgid="6299769563624776948">"לא ניתן למחוק את אחסון ה- USB."</string>
     <string name="format_error" product="default" msgid="7315248696644510935">"לא ניתן למחוק את כרטיס ה-SD."</string>
     <string name="media_bad_removal" msgid="7960864061016603281">"כרטיס SD הוסר לפני שטעינתו בוטלה."</string>
-    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"אמצעי אחסון מסוג USB נבדק כעת."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"אחסון USB נבדק כעת."</string>
     <string name="media_checking" product="default" msgid="7334762503904827481">"כרטיס SD נבדק כעת."</string>
     <string name="media_removed" msgid="7001526905057952097">"כרטיס SD הוסר."</string>
-    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"אמצעי אחסון מסוג USB נמצא כעת בשימוש של מחשב."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"אחסון USB נמצא כעת בשימוש של מחשב."</string>
     <string name="media_shared" product="default" msgid="5706130568133540435">"כרטיס SD נמצא כעת בשימוש של מחשב."</string>
     <string name="media_unknown_state" msgid="729192782197290385">"מדיה חיצונית במצב לא ידוע."</string>
     <string name="share" msgid="1778686618230011964">"שתף"</string>
@@ -1176,7 +1176,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
     <string name="storage_internal" msgid="7556050805474115618">"אחסון פנימי"</string>
     <string name="storage_sd_card" msgid="8921771478629812343">"כרטיס SD"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"אמצעי אחסון מסוג USB"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"אחסון USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"ערוך..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"אזהרת שימוש בנתונים"</string>
     <string name="data_usage_warning_body" msgid="7217480745540055170">"גע כדי להציג נתוני שימוש והגדרות"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ea4c6cc..26236d7 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -223,7 +223,7 @@
     <string name="permlab_forceStopPackages" msgid="1447830113260156236">"다른 애플리케이션 강제 종료"</string>
     <string name="permdesc_forceStopPackages" msgid="7263036616161367402">"애플리케이션이 다른 애플리케이션을 강제로 종료할 수 있도록 합니다."</string>
     <string name="permlab_forceBack" msgid="1804196839880393631">"강제로 애플리케이션 닫기"</string>
-    <string name="permdesc_forceBack" msgid="6534109744159919013">"애플리케이션이 포그라운드에 있는 활동을 강제로 닫고 되돌아갈 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
+    <string name="permdesc_forceBack" msgid="6534109744159919013">"애플리케이션이 포그라운드에 있는 작업을 강제로 닫고 되돌아갈 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"시스템 내부 상태 검색"</string>
     <string name="permdesc_dump" msgid="2198776174276275220">"애플리케이션이 시스템의 내부 상태를 검색할 수 있도록 합니다. 단, 악성 애플리케이션이 이 기능을 이용하여 일반적으로 필요하지 않은 다양한 개인정보와 보안정보를 검색할 수 있습니다."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"화면 콘텐츠 검색"</string>
@@ -446,7 +446,7 @@
     <string name="permdesc_useCredentials" msgid="7416570544619546974">"애플리케이션이 인증 토큰을 요청하도록 합니다."</string>
     <string name="permlab_accessNetworkState" msgid="6865575199464405769">"네트워크 상태 보기"</string>
     <string name="permdesc_accessNetworkState" msgid="558721128707712766">"애플리케이션이 모든 네트워크의 상태를 볼 수 있도록 합니다."</string>
-    <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"인터넷에 최대한 액세스"</string>
+    <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"인터넷 액세스"</string>
     <string name="permdesc_createNetworkSockets" msgid="4593339106921772192">"애플리케이션이 네트워크 소켓을 만들 수 있도록 합니다."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"네트워크 설정 및 트래픽 차단/변경"</string>
     <string name="permdesc_writeApnSettings" msgid="2369786339323021771">"애플리케이션이 모든 네트워크 트래픽을 가로채고 검사하거나 네트워크 설정을 변경하도록 허용합니다. 예를 들어 프록시나 APN의 포트를 변경할 수 있습니다. 악성 애플리케이션이 사용자 모르게 네트워크 패킷을 모니터링하고 리디렉션하며 수정할 수도 있습니다."</string>
@@ -899,7 +899,7 @@
     <string name="aerr_process" msgid="4507058997035697579">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 중지되었습니다."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
-    <string name="anr_activity_process" msgid="7018289416670457797">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 활동이 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
+    <string name="anr_activity_process" msgid="7018289416670457797">"<xliff:g id="ACTIVITY">%1$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
     <string name="anr_application_process" msgid="7208175830253210526">"<xliff:g id="APPLICATION">%1$s</xliff:g>이(가) 응답하지 않습니다. 닫으시겠습니까?"</string>
     <string name="anr_process" msgid="306819947562555821">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
     <string name="force_close" msgid="8346072094521265605">"확인"</string>
@@ -1207,7 +1207,7 @@
     <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 지문:"</string>
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 지문:"</string>
     <string name="activity_chooser_view_see_all" msgid="180268188117163072">"전체 보기..."</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"활동 선택"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"작업 선택"</string>
     <string name="share_action_provider_share_with" msgid="1791316789651185229">"공유 대상..."</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"기기가 잠겼습니다."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 9875c9d..919ccad7 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -632,7 +632,7 @@
     <string name="relationTypeSister" msgid="1735983554479076481">"Irmã"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"Cônjuge"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizado"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Residência"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduzir código PIN"</string>
@@ -1014,7 +1014,7 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
-    <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+    <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
     <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 68b94dc..99506c2 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -148,11 +148,11 @@
     <string name="global_action_lock" msgid="2844945191792119712">"Блокировка экрана"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Отключить питание"</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Режим без звука"</string>
-    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звук ВЫКЛ"</string>
-    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звук ВКЛЮЧЕН"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Выключить"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Включить"</string>
     <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Режим полета"</string>
-    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим полета ВКЛЮЧЕН"</string>
-    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим полета ВЫКЛЮЧЕН"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Выключить"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Включить"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -348,7 +348,7 @@
     <string name="permlab_accessFineLocation" msgid="8116127007541369477">"точное местоположение (GPS)"</string>
     <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Получать доступ к источникам точного местоположения, таким как GPS, когда это возможно. Вредоносные приложения могут использовать это разрешение для определения вашего местоположения и расходовать ресурс батареи."</string>
     <string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"Получать доступ к источникам точного местоположения, таким как GPS, если возможно. Вредоносные приложения могут использовать это разрешение для определения вашего местоположения и расходовать ресурс батареи."</string>
-    <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"отслеживать местоположение по сигналам сети"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"примерное местоположение по координатам сети"</string>
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"Получать доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения планшетного ПК, когда это возможно. Вредоносные приложения могут использовать это разрешение для определения вашего приблизительного местоположения."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="8235655958070862293">"Получать доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения телефона, если возможно. Вредоносные приложения могут использовать эту возможность для определения вашего приблизительного местоположения."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"получать доступ к SurfaceFlinger"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6dbdb35..9268dec 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1064,7 +1064,7 @@
     <string name="allow" msgid="7225948811296386551">"允许"</string>
     <string name="deny" msgid="2081879885755434506">"拒绝"</string>
     <string name="permission_request_notification_title" msgid="5390555465778213840">"已请求权限"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"已为帐户<xliff:g id="ACCOUNT">%s</xliff:g>"\n"请求了权限"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"有程序请求获得帐户 <xliff:g id="ACCOUNT">%s</xliff:g>"\n"的访问权限"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"同步"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a61416f..2ddf0f1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -136,7 +136,7 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"Vula okungenantambo"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Vala okungenantambo"</string>
     <string name="screen_lock" msgid="799094655496098153">"Ukuvala isikrini"</string>
-    <string name="power_off" msgid="4266614107412865048">"Amandla avaliwe"</string>
+    <string name="power_off" msgid="4266614107412865048">"Vala amandla"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Ivala shaqa..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ithebhulethi yakho izocima."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ifoni yakho izocima."</string>
@@ -146,7 +146,7 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Okukhethwa konke kwethebhulethi"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Okukhethwa kukho kwefoni"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Ukuvala isikrini"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"Amandla avaliwe"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Vala amandla"</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Imodi ethulile"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Umsindo UVALIWE"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Umsindo UVULIWE"</string>
@@ -838,7 +838,7 @@
     <item quantity="one" msgid="2178576254385739855">"Kusasa"</item>
     <item quantity="other" msgid="2973062968038355991">"ezinsukwini ezing-<xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="preposition_for_date" msgid="9093949757757445117">"Ngomhla ka <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"ngo-<xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"e-<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"phakathi- <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"usuku"</string>
@@ -886,7 +886,7 @@
     <string name="no" msgid="5141531044935541497">"Khansela"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Ukunaka"</string>
     <string name="loading" msgid="1760724998928255250">"Iyalayisha..."</string>
-    <string name="capital_on" msgid="1544682755514494298">"Ngomhla ka"</string>
+    <string name="capital_on" msgid="1544682755514494298">"VULIWE"</string>
     <string name="capital_off" msgid="6815870386972805832">"VALIWE"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Qedela isenzo usebenzisa"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Sebenzisa ngokuzenzakalelayo kulesenzo."</string>
@@ -1146,7 +1146,7 @@
     <string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
     <string name="radiobutton_not_selected" msgid="2908760184307722393">"akukhethiwe"</string>
-    <string name="switch_on" msgid="551417728476977311">"Ngomhla ka-"</string>
+    <string name="switch_on" msgid="551417728476977311">"vuliwe"</string>
     <string name="switch_off" msgid="7249798614327155088">"valiwe"</string>
     <string name="togglebutton_pressed" msgid="4180411746647422233">"kucindezelwe."</string>
     <string name="togglebutton_not_pressed" msgid="4495147725636134425">"akucindezelwe."</string>
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 9eee2f0..a781472 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -89,8 +89,27 @@
      * Ensure that downloading on wifi reports reasonable stats.
      */
     @LargeTest
-    public void testWifiDownload() {
-        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+    public void testWifiDownload() throws Exception {
+        assertTrue("Could not connect to wifi!", setDeviceWifiAndAirplaneMode(mSsid));
+        downloadFile();
+    }
+
+    /**
+     * Ensure that downloading on mobile reports reasonable stats.
+     */
+    @LargeTest
+    public void testMobileDownload() throws Exception {
+        // As part of the setup we disconnected from wifi; make sure we are connected to mobile and
+        // that we have data.
+        assertTrue("Do not have mobile data!", hasMobileData());
+        downloadFile();
+    }
+
+    /**
+     * Helper method that downloads a file using http connection from a test server and reports the
+     * data usage stats to instrumentation out.
+     */
+    protected void downloadFile() throws Exception {
         NetworkStats pre_test_stats = fetchDataFromProc(mUid);
         String ts = Long.toString(System.currentTimeMillis());
 
@@ -120,11 +139,28 @@
     }
 
     /**
-     * Ensure that downloading on wifi reports reasonable stats.
+     * Ensure that uploading on wifi reports reasonable stats.
      */
     @LargeTest
-    public void testWifiUpload() {
+    public void testWifiUpload() throws Exception {
         assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+        uploadFile();
+    }
+
+    /**
+     *  Ensure that uploading on wifi reports reasonable stats.
+     */
+    @LargeTest
+    public void testMobileUpload() throws Exception {
+        assertTrue(hasMobileData());
+        uploadFile();
+    }
+
+    /**
+     * Helper method that downloads a test file to upload. The stats reported to instrumentation out
+     * only include upload stats.
+     */
+    protected void uploadFile() throws Exception {
         // Download a file from the server.
         String ts = Long.toString(System.currentTimeMillis());
         String targetUrl = BandwidthTestUtil.buildDownloadUrl(
@@ -156,12 +192,30 @@
     }
 
     /**
-     * We want to make sure that if we use the Download Manager to download stuff,
+     * We want to make sure that if we use wifi and the  Download Manager to download stuff,
      * accounting still goes to the app making the call and that the numbers still make sense.
      */
     @LargeTest
-    public void testWifiDownloadWithDownloadManager() {
+    public void testWifiDownloadWithDownloadManager() throws Exception {
         assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+        downloadFileUsingDownloadManager();
+    }
+
+    /**
+     * We want to make sure that if we use mobile data and the Download Manager to download stuff,
+     * accounting still goes to the app making the call and that the numbers still make sense.
+     */
+    @LargeTest
+    public void testMobileDownloadWithDownloadManager() throws Exception {
+        assertTrue(hasMobileData());
+        downloadFileUsingDownloadManager();
+    }
+
+    /**
+     * Helper method that downloads a file from a test server using the download manager and reports
+     * the stats to instrumentation out.
+     */
+    protected void downloadFileUsingDownloadManager() throws Exception {
         // If we are using the download manager, then the data that is written to /proc/uid_stat/
         // is accounted against download manager's uid, since it uses pre-ICS API.
         int downloadManagerUid = mConnectionUtil.downloadManagerUid();
@@ -195,6 +249,7 @@
 
     /**
      * Fetch network data from /proc/uid_stat/uid
+     *
      * @return populated {@link NetworkStats}
      */
     public NetworkStats fetchDataFromProc(int uid) {
@@ -210,7 +265,8 @@
     }
 
     /**
-     * Turn on Airplane mode and connect to the wifi
+     * Turn on Airplane mode and connect to the wifi.
+     *
      * @param ssid of the wifi to connect to
      * @return true if we successfully connected to a given network.
      */
@@ -219,12 +275,25 @@
         assertTrue(mConnectionUtil.connectToWifi(ssid));
         assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectionUtil.LONG_TIMEOUT));
-        return mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectionUtil.LONG_TIMEOUT);
+        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
+        return mConnectionUtil.hasData();
+    }
+
+    /**
+     * Helper method to make sure we are connected to mobile data.
+     *
+     * @return true if we successfully connect to mobile data.
+     */
+    public boolean hasMobileData() {
+        assertTrue("Not connected to mobile", mConnectionUtil.isConnectedToMobile());
+        assertFalse("Still connected to wifi.", mConnectionUtil.isConnectedToWifi());
+        return mConnectionUtil.hasData();
     }
 
     /**
      * Output the {@link NetworkStats} to Instrumentation out.
+     *
      * @param label to attach to this given stats.
      * @param stats {@link NetworkStats} to add.
      * @param results {@link Bundle} to be added to.
@@ -281,4 +350,4 @@
         }
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
index d663aad..a5e5ab0e 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -44,6 +44,8 @@
 import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
 import com.android.internal.util.AsyncChannel;
 
+import java.io.IOException;
+import java.net.UnknownHostException;
 import java.util.List;
 
 /*
@@ -257,14 +259,14 @@
         mConnectivityState[networkType].recordState(networkState);
     }
 
-   /**
-    * Set the state transition criteria
-    *
-    * @param networkType
-    * @param initState
-    * @param transitionDir
-    * @param targetState
-    */
+    /**
+     * Set the state transition criteria
+     *
+     * @param networkType
+     * @param initState
+     * @param transitionDir
+     * @param targetState
+     */
     public void setStateTransitionCriteria(int networkType, State initState,
             StateTransitionDirection transitionDir, State targetState) {
         mConnectivityState[networkType].setStateTransitionCriteria(
@@ -495,7 +497,8 @@
      * @return true if connected to a mobile network, false otherwise.
      */
     public boolean isConnectedToMobile() {
-        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        return networkInfo.isConnected();
     }
 
     /**
@@ -503,10 +506,10 @@
      * @return true if connected to wifi, false otherwise.
      */
     public boolean isConnectedToWifi() {
-        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        return networkInfo.isConnected();
     }
 
-
     /**
      * Associate the device to given SSID
      * If the device is already associated with a WiFi, disconnect and forget it,
@@ -681,4 +684,30 @@
         }
         Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
     }
+
+    /**
+     * Helper method used to test data connectivity by pinging a series of popular sites.
+     * @return true if device has data connectivity, false otherwise.
+     */
+    public boolean hasData() {
+        String[] hostList = {"www.google.com", "www.yahoo.com",
+                "www.bing.com", "www.facebook.com", "www.ask.com"};
+        try {
+            for (int i = 0; i < hostList.length; ++i) {
+                String host = hostList[i];
+                Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
+                int status = p.waitFor();
+                if (status == 0) {
+                    return true;
+                }
+            }
+        } catch (UnknownHostException e) {
+            Log.e(LOG_TAG, "Ping test Failed: Unknown Host");
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Ping test Failed: IOException");
+        } catch (InterruptedException e) {
+            Log.e(LOG_TAG, "Ping test Failed: InterruptedException");
+        }
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/docs/html/guide/developing/building/building-cmdline.jd b/docs/html/guide/developing/building/building-cmdline.jd
index d78a4f5..c43962a 100644
--- a/docs/html/guide/developing/building/building-cmdline.jd
+++ b/docs/html/guide/developing/building/building-cmdline.jd
@@ -365,7 +365,7 @@
   <dd>Builds a test project and the tested project, installs both <code>.apk</code> files, and
   runs the tests.</dd>
 
-  <dt><code>ant emma debug installt test</code></dt>
+  <dt><code>ant emma debug install test</code></dt>
   <dd>Builds a test project and the tested project, installs both <code>.apk</code> files, and
   runs the tests with code coverage enabled.</dd>
 
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index a3bb6d4..af379de 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -82,9 +82,17 @@
           </a></li>
         </ul>
       </li>
-      <li><a href="<?cs var:toroot ?>guide/topics/providers/content-providers.html">
+      <li class="toggle-list">
+          <div><a href="<?cs var:toroot ?>guide/topics/providers/content-providers.html">
             <span class="en">Content Providers</span>
-          </a></li>
+          </a><span class="new">updated</span></div>
+          <ul>
+            <li><a href="<?cs var:toroot ?>guide/topics/providers/calendar-provider.html">
+                  <span class="en">Calendar Provider</span></a>
+                  <span class="new">new!</span>
+                </li>
+          </ul>
+      </li>
       <li><a href="<?cs var:toroot ?>guide/topics/intents/intents-filters.html">
             <span class="en">Intents and Intent Filters</span>
           </a></li>
@@ -789,6 +797,10 @@
       <li><a href="<?cs var:toroot ?>guide/practices/design/seamlessness.html">
             <span class="en">Designing for Seamlessness</span>
           </a></li>
+      <li><a href="<?cs var:toroot ?>guide/practices/security.html">
+            <span class="en">Designing for Security</span></a>
+            <span class="new">new!</span><!-- 11/7/10 -->
+          </li>
     </ul>
   </li>
 
diff --git a/docs/html/guide/market/billing/billing_integrate.jd b/docs/html/guide/market/billing/billing_integrate.jd
index 3eebd59..6017583 100755
--- a/docs/html/guide/market/billing/billing_integrate.jd
+++ b/docs/html/guide/market/billing/billing_integrate.jd
@@ -476,7 +476,7 @@
 <ul>
   <li><code>CHECK_BILLING_SUPPORTED</code>&mdash;verifies that the Android Market application
   supports in-app billing.</li>
-  <li><code>REQUEST_PURCHASE</code>&mdash;sends a purchase request for an in-app item.</li> 
+  <li><code>REQUEST_PURCHASE</code>&mdash;sends a purchase request for an in-app item.</li>
   <li><code>GET_PURCHASE_INFORMATION</code>&mdash;retrieves transaction information for a purchase
   or refund.</li>
   <li><code>CONFIRM_NOTIFICATIONS</code>&mdash;acknowledges that you received the transaction
@@ -584,9 +584,9 @@
   // Note that the developer payload is optional.
   if (mDeveloperPayload != null) {
     request.putString(DEVELOPER_PAYLOAD, mDeveloperPayload);
+  }
   Bundle response = mService.sendBillingRequest(request);
   // Do something with this response.
-  }
 </pre>
 <p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the
 three keys that are required for all requests: <code>BILLING_REQUEST</code>,
@@ -930,9 +930,9 @@
 
 <pre>
 public class BillingReceiver extends BroadcastReceiver {
-  
+
   private static final String TAG = "BillingReceiver";
-  
+
   // Intent actions that we receive in the BillingReceiver from Android Market.
   // These are defined by Android Market and cannot be changed.
   // The sample application defines these in the Consts.java file.
@@ -940,7 +940,7 @@
   public static final String ACTION_RESPONSE_CODE = "com.android.vending.billing.RESPONSE_CODE";
   public static final String ACTION_PURCHASE_STATE_CHANGED =
     "com.android.vending.billing.PURCHASE_STATE_CHANGED";
-    
+
   // The intent extras that are passed in an intent from Android Market.
   // These are defined by Android Market and cannot be changed.
   // The sample application defines these in the Consts.java file.
diff --git a/docs/html/guide/practices/security.jd b/docs/html/guide/practices/security.jd
new file mode 100644
index 0000000..5da7e98
--- /dev/null
+++ b/docs/html/guide/practices/security.jd
@@ -0,0 +1,772 @@
+page.title=Designing for Security
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>In this document</h2>
+<ol>
+<li><a href="#Dalvik">Using Davlik Code</a></li>
+<li><a href="#Native">Using Native Code</a></li>
+<li><a href="#Data">Storing Data</a></li>
+<li><a href="#IPC">Using IPC</a></li>
+<li><a href="#Permissions">Using Permissions</a></li>
+<li><a href="#Networking">Using Networking</a></li>
+<li><a href="#DynamicCode">Dynamically Loading Code</a></li>
+<li><a href="#Input">Performing Input Validation</a></li>
+<li><a href="#UserData">Handling User Data</a></li>
+<li><a href="#Crypto">Using Cryptography</a></li>
+</ol>
+<h2>See also</h2>
+<ol>
+<li><a href="http://source.android.com/tech/security/index.html">Android
+Security Overview</a></li>
+<li><a href="{@docRoot}guide/topics/security/security.html">Android Security
+And Permissions</a></li>
+</ol>
+</div></div>
+<p>Android was designed so that most developers will be able to build
+applications using the default settings and not be confronted with difficult
+decisions about security.  Android also has a number of security features built
+into the operating system that significantly reduce the frequency and impact of
+application security issues.</p>
+
+<p>Some of the security features that help developers build secure applications
+include:
+<ul>
+<li>The Android Application Sandbox that isolates data and code execution on a
+per-application basis.</li>
+<li>Android application framework with robust implementations of common
+security functionality such as cryptography, permissions, and secure IPC.</li>
+<li>Technologies like ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD
+calloc, and Linux mmap_min_addr to mitigate risks associated with common memory
+management errors</li>
+<li>An encrypted filesystem that can be enabled to protect data on lost or
+stolen devices.</li>
+</ul></p>
+
+<p>Nevertheless, it is important for developers to be familiar with Android
+security best practices to make sure they take advantage of these capabilities
+and to reduce the likelihood of inadvertently introducing security issues that
+can affect their applications.</p>
+
+<p>This document is organized around common APIs and development techniques
+that can have security implications for your application and its users. As
+these best practices are constantly evolving, we recommend you check back
+occasionally throughout your application development process.</p>
+
+<a name="Dalvik"></a>
+<h2>Using Dalvik Code</h2>
+<p>Writing secure code that runs in virtual machines is a well-studied topic
+and many of the issues are not specific to Android.  Rather than attempting to
+rehash these topics, we’d recommend that you familiarize yourself with the
+existing literature. Two of the more popular resources are:
+<ul>
+<li><a href="http://www.securingjava.com/toc.html">
+http://www.securingjava.com/toc.html</a></li>
+<li><a
+href="https://www.owasp.org/index.php/Java_Security_Resources">
+https://www.owasp.org/index.php/Java_Security_Resources</a></li>
+</ul></p>
+
+<p>This document is focused on the areas which are Android specific and/or
+different from other environments.  For developers experienced with VM
+programming in other environments, there are two broad issues that may be
+different about writing apps for Android:
+<ul>
+<li>Some virtual machines, such as the JVM or .net runtime, act as a security
+boundary, isolating code from the underlying operating system capabilities.  On
+Android, the Dalvik VM is not a security boundary -- the application sandbox is
+implemented at the OS level, so Dalvik can interoperate with native code in the
+same application without any security constraints.</li>
+<li>Given the limited storage on mobile devices, it’s common for developers
+to want to build modular applications and use dynamic class loading.  When
+doing this consider both the source where you retrieve your application logic
+and where you store it locally. Do not use dynamic class loading from sources
+that are not verified, such as unsecured network sources or external storage,
+since that code can be modified to include malicious behavior.</li>
+</ul></p>
+
+<a name="Native"></a>
+<h2>Using Native Code</h2>
+
+<p>In general, we encourage developers to use the Android SDK for most
+application development, rather than using native code.   Applications built
+with native code are more complex, less portable, and more like to include
+common memory corruption errors such as buffer overflows.</p>
+
+<p>Android is built using the Linux kernel and being familiar with Linux
+development security best practices is especially useful if you are going to
+use native code. This document is too short to discuss all of those best
+practices, but one of the most popular resources is  “Secure Programming for
+Linux and Unix HOWTO”, available at <a
+href="http://www.dwheeler.com/secure-programs">
+http://www.dwheeler.com/secure-programs</a>.</p>
+
+<p>An important difference between Android and most Linux environments is the
+Application Sandbox.  On Android, all applications run in the Application
+Sandbox, including those written with native code.  At the most basic level, a
+good way to think about it for developers familiar with Linux is to know that
+every application is given a unique UID with very limited permissions. This is
+discussed in more detail in the <a
+href="http://source.android.com/tech/security/index.html">Android Security
+Overview</a> and you should be familiar with application permissions even if
+you are using native code.</p>
+
+<a name="Data"></a>
+<h2>Storing Data</h2>
+
+<h3>Using internal files</h3>
+
+<p>By default, files created on <a
+href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal
+storage</a> are only accessible to the application that created the file. This
+protection is implemented by Android and is sufficient for most
+applications.</p>
+
+<p>Use of <a
+href="{@docRoot}reference/android/content/Context.html#MODE_WORLD_WRITEABLE">
+world writable</a> or <a
+href="{@docRoot}reference/android/content/Context.html#MODE_WORLD_READABLE
+">world readable</a> files for IPC is discouraged because it does not provide
+the ability to limit data access to particular applications, nor does it
+provide any control on data format. As an alternative, you might consider using
+a ContentProvider which provides read and write permissions, and can make
+dynamic permission grants on a case-by-case basis.</p>
+
+<p>To provide additional protection for sensitive data, some applications
+choose to encrypt local files using a key that is not accessible to the
+application. (For example, a key can be placed in a <code><a
+href={@docRoot}reference/java/security/KeyStore.html">KeyStore</a></code> and
+protected with a user password that is not stored on the device).  While this
+does not protect data from a root compromise that can monitor the user
+inputting the password,  it can provide protection for a lost device without <a
+href="http://source.android.com/tech/encryption/index.html">file system
+encryption</a>.</p>
+
+<h3>Using external storage</h3>
+
+<p>Files created on <a
+href="{@docRoot}guide/topics/data/data-storage.html#filesExternal">external
+storage</a>, such as SD Cards, are globally readable and writable.  Since
+external storage can be removed by the user and also modified by any
+application,  applications should not store sensitive information using
+external storage.</p>
+
+<p>As with data from any untrusted source, applications should perform input
+validation when handling data from external storage (see Input Validation
+section).  We strongly recommend that applications not store executables or
+class files on external storage prior to dynamic loading.  If an application
+does retrieve executable files from external storage they should be signed and
+cryptographically verified prior to dynamic loading.</p>
+
+<h3>Using content providers</h3>
+
+<p>ContentProviders provide a structured storage mechanism that can be limited
+to your own application, or exported to allow access by other applications. By
+default, a <code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code> is
+<a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">exported
+</a> for use by other applications.  If you do not intend to provide other
+applications with access to your<code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code>, mark them as <code><a
+href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
+android:exported=false</a></code> in the application manifest.</p>
+
+<p>When creating a <code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">ContentProvider
+</a></code> that will be exported for use by other applications, you can specify
+a single
+<a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission
+</a> for reading and writing, or distinct permissions for reading and writing
+within the manifest. We recommend that you limit your permissions to those
+required to accomplish the task at hand. Keep in mind that it’s usually
+easier to add permissions later to expose new functionality than it is to take
+them away and break existing users.</p>
+
+<p>If you are using a <code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code> for sharing data between applications built by the
+same developer, it is preferable to use
+<a href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
+level permissions</a>.  Signature permissions do not require user confirmation,
+so they provide a better user experience and more controlled access to the
+<code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code>.</p>
+
+<p>ContentProviders can also provide more granular access by declaring the <a
+href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+grantUriPermissions</a> element and using the <code><a
+href="{@docRoot}reference/android/content/Intent.html#FLAG_GRANT_READ_URI_PERMIS
+SION">FLAG_GRANT_READ_URI_PERMISSION</a></code> and <code><a
+href="{@docRoot}reference/android/content/Intent.html#FLAG_GRANT_WRITE_URI_PERMI
+SSION">FLAG_GRANT_WRITE_URI_PERMISSION</a></code> flags in the Intent object
+that activates the component.  The scope of these permissions can be further
+limited by the <code><a
+href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+grant-uri-permission element</a></code>.</p>
+
+<p>When accessing a <code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code>, use parameterized query methods such as <code>
+<a href="{@docRoot}reference/android/content/ContentProvider.html#query(android.net
+.Uri,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lan
+g.String)">query()</a></code>, <code><a
+href="{@docRoot}reference/android/content/ContentProvider.html#update(android.ne
+t.Uri,%20android.content.ContentValues,%20java.lang.String,%20java.lang.String[]
+)">update()</a></code>, and <code><a
+href="{@docRoot}reference/android/content/ContentProvider.html#delete(android.ne
+t.Uri,%20java.lang.String,%20java.lang.String[])">delete()</a></code> to avoid
+potential <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL
+Injection</a> from untrusted data. Note that using parameterized methods is not
+sufficient if the <code>selection</code> is built by concatenating user data
+prior to submitting it to the method.</p>
+
+<p>Do not have a false sense of security about the write permission.  Consider
+that the write permission allows SQL statements which make it possible for some
+data to be confirmed using creative <code>WHERE</code> clauses and parsing the
+results. For example, an attacker might probe for presence of a specific phone
+number in a call-log by modifying a row only if that phone number already
+exists. If the content provider data has predictable structure, the write
+permission may be equivalent to providing both reading and writing.</p>
+
+<a name="IPC"></a>
+<h2>Using Interprocess Communication (IPC)</h2>
+
+<p>Some Android applications attempt to implement IPC using traditional Linux
+techniques such as network sockets and shared files.  We strongly encourage the
+use of Android system functionality for IPC such as Intents, Binders, Services,
+and Receivers.  The Android IPC mechanisms allow you to verify the identity of
+the application connecting to your IPC and set security policy for each IPC
+mechanism.</p>
+
+<p>Many of the security elements are shared across IPC mechanisms. <a
+href="{@docRoot}reference/android/content/BroadcastReceiver.html">
+Broadcast Receivers</a>, <a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestActivity">
+Activities</a>, and <a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestService">
+Services</a> are all declared in the application manifest.  If your IPC mechanism is
+not intended for use by other applications, set the android:exported property
+to false.  This is useful for applications that consist of multiple processes
+within the same UID, or if you decide late in development that you do not
+actually want to expose functionality as IPC but you don’t want to rewrite
+the code.</p>
+
+<p>If your IPC is intended to be accessible to other applications, you can
+apply a security policy by using the <a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestPermission">
+Permission</a> tag. If IPC is between applications built by the same developer,
+it is preferable to use <a
+href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
+level permissions</a>.  Signature permissions do not require user confirmation,
+so they provide a better user experience and more controlled access to the IPC
+mechanism.</p>
+
+<p>One area that can introduce confusion is the use of intent filters. Note
+that Intent filters should not be considered a security feature -- components
+can be invoked directly and may not have data that would conform to the intent
+filter. You should perform input validation within your intent receiver to
+confirm that it is properly formatted for the invoked receiver, service, or
+activity.</p>
+
+<h3>Using intents</h3>
+
+<p>Intents are the preferred mechanism for asynchronous IPC in Android.
+Depending on your application requirements, you might use <code><a
+href="{@docRoot}reference/android/content/Context.html#sendBroadcast(android.con
+tent.Intent)">sendBroadcast()</a></code>, <code><a
+href="{@docRoot}reference/android/content/Context.html#sendOrderedBroadcast(andr
+oid.content.Intent,%20java.lang.String)">sendOrderedBroadcast()</a></code>, or
+direct an intent to a specific application component.</p>
+
+<p>Note that ordered broadcasts can be “consumed” by a recipient, so they
+may not be delivered to all applications.  If you are sending an Intent where
+delivery to a specific receiver is required, the intent must be delivered
+directly to the receiver.</p>
+
+<p>Senders of an intent can verify that the recipient has a permission
+specifying a non-Null Permission upon sending.  Only applications with that
+Permission will receive the intent.  If data within a broadcast intent may be
+sensitive, you should consider applying a permission to make sure that
+malicious applications cannot register to receive those messages without
+appropriate permissions.  In those circumstances, you may also consider
+invoking the receiver directly, rather than raising a broadcast.</p>
+
+<h3>Using binder and AIDL interfaces</h3>
+
+<p><a href="{@docRoot}reference/android/os/Binder.html">Binders</a> are the
+preferred mechanism for RPC-style IPC in Android. They provide a well-defined
+interface that enables mutual authentication of the endpoints, if required.</p>
+
+<p>We strongly encourage designing interfaces in a manner that does not require
+interface specific permission checks. Binders are not declared within the
+application manifest, and therefore you cannot apply declarative permissions
+directly to a Binder.  Binders generally inherit permissions declared in the
+application manifest for the Service or Activity within which they are
+implemented.  If you are creating an interface that requires authentication
+and/or access controls on a specific binder interface, those controls must be
+explicitly added as code in the interface.</p>
+
+<p>If providing an interface that does require access controls, use <code><a
+href="{@docRoot}reference/android/content/Context.html#checkCallingPermission(ja
+va.lang.String)">checkCallingPermission()</a></code> to verify whether the
+caller of the Binder has a required permission. This is especially important
+before accessing a Service on behalf of the caller, as the identify of your
+application is passed to other interfaces.  If invoking an interface provided
+by a Service, the <code><a
+href="{@docRoot}reference/android/content/Context.html#bindService(android.conte
+nt.Intent,%20android.content.ServiceConnection,%20int)">bindService()</a></code>
+ invocation may fail if you do not have permission to access the given Service.
+ If calling an interface provided locally by your own application, it may be
+useful to use the <code><a
+href="{@docRoot}reference/android/os/Binder.html#clearCallingIdentity()">
+clearCallingIdentity()</a></code> to satisfy internal security checks.</p>
+
+<h3>Using broadcast receivers</h3>
+
+<p>Broadcast receivers are used to handle asynchronous requests initiated via
+an intent.</p>
+
+<p>By default, receivers are exported and can be invoked by any other
+application. If your <code><a
+href={@docRoot}reference/android/content/BroadcastReceiver.html">
+BroadcastReceivers</a></code> is intended for use by other applications, you
+may want to apply security permissions to receivers using the <code><a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestReceiver">
+&lt;receiver&gt;</a></code> element within the application manifest.  This will
+prevent applications without appropriate permissions from sending an intent to
+the <code><a
+href={@docRoot}reference/android/content/BroadcastReceiver.html">
+BroadcastReceivers</a></code>.</p>
+
+<h3>Using Services</h3>
+
+<p>Services are often used to supply functionality for other applications to
+use. Each service class must have a corresponding <service> declaration in its
+package's AndroidManifest.xml.</p>
+
+<p>By default, Services are exported and can be invoked by any other
+application.  Services can be protected using the android:permission attribute
+within the manifest’s <code><a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestService">
+&lt;service&gt;</a></code> tag. By doing so, other applications will need to declare
+a corresponding <code><a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestService_permis
+sion">&lt;uses-permission&gt;</a></code> element in their own manifest to be
+able to start, stop, or bind to the service.</p>
+
+<p>A Service can protect individual IPC calls into it with permissions, by
+calling <code><a
+href="{@docRoot}reference/android/content/Context.html#checkCallingPermission(ja
+va.lang.String)">checkCallingPermission()</a></code>before executing
+the implementation of that call.  We generally recommend using the
+declarative permissions in the manifest, since those are less prone to
+oversight.</p>
+
+<h3>Using Activities</h3>
+
+<p>Activities are most often used for providing the core user-facing
+functionality of an application. By default, Activities are exported and
+invokable by other applications only if they have an intent filter or binder
+declared.  In general, we recommend that you specifically declare a Receiver or
+Service to handle IPC, since this modular approach reduces the risk of exposing
+functionality that is not intended for use by other applications.</p>
+
+<p>If you do expose an Activity for purposes of IPC, the  <code><a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestActivity_permi
+ssion">android:permission</a></code> attribute in the  <code><a
+href="{@docRoot}reference/android/R.styleable.html#AndroidManifestActivity">
+&lt;activity&gt;</a></code> declaration in the application manifest can be used to
+restrict access to only those applications which have the stated
+permissions.</p>
+
+<a name="Permissions"></a>
+<h2>Using Permissions</h2>
+
+<h3>Requesting Permissions</h3>
+
+<p>We recommend minimizing the number of permissions requested by an
+application. Not having access to sensitive permissions reduces the risk of
+inadvertently misusing those permissions, can improve user adoption, and makes
+applications less attractive targets for attackers.</p>
+
+<p>If it is possible to design your application in a way that does not require
+a permission, that is preferable.  For example, rather than requesting access
+to device information to create an identifier, create a <a
+href="{@docRoot}reference/java/util/UUID.html">GUID</a> for your application.
+(This specific example is also discussed in Handling User Data) Or, rather than
+using external storage, store data in your application directory.</p>
+
+<p>If a permission is not required, do not request it.  This sounds simple, but
+there has been quite a bit of research into the frequency of over-requesting
+permissions. If you’re interested in the subject you might start with this
+research paper published by U.C. Berkeley: <a
+href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2011/EECS-2011-48.pdf">
+http://www.eecs.berkeley.edu/Pubs/TechRpts/2011/EECS-2011-48.pdf</a></p>
+
+<p>In addition to requesting permissions, your application can use <a
+href="{@docRoot}guide/topics/manifest/permission-element.html">permissions</a>
+to protect IPC that is security sensitive and will be exposed to other
+applications -- such as a <code><a
+href="{@docRoot}reference/android/content/ContentProvider.html">
+ContentProvider</a></code>.  In general, we recommend using access controls
+other than user confirmed permissions where possible since permissions can
+be confusing for users. For example, consider using the <a
+href="{@docRoot}guide/topics/manifest/permission-element.html#plevel">signature
+protection level</a> on permissions for IPC communication between applications
+provided by a single developer.</p>
+
+<p>Do not cause permission re-delegation.  This occurs when an app exposes data
+over IPC that is only available because it has a specific permission, but does
+not require that permission of any clients of it’s IPC interface. More
+details on the potential impacts, and frequency of this type of problem is
+provided in this research paper published at USENIX: <a
+href="http://www.cs.berkeley.edu/~afelt/felt_usenixsec2011.pdf">http://www.cs.be
+rkeley.edu/~afelt/felt_usenixsec2011.pdf</a></p>
+
+<h3>Creating Permissions</h3>
+
+<p>Generally, you should strive to create as few permissions as possible while
+satisfying your security requirements.  Creating a new permission is relatively
+uncommon for most applications, since <a
+href="{@docRoot}reference/android/Manifest.permission.html">
+system-defined permissions</a> cover many situations.  Where appropriate,
+perform access checks using existing permissions.</p>
+
+<p>If you must create a new permission, consider whether you can accomplish
+your task with a Signature permission.  Signature permissions are transparent
+to the user and only allow access by applications signed by the same developer
+as application performing the permission check.  If you create a Dangerous
+permission, then the user needs to decide whether to install the application.
+This can be confusing for other developers, as well as for users.</p>
+
+<p>If you create a Dangerous permission, there are a number of complexities
+that you need to consider.
+<ul>
+<li>The permission must have a string that concisely expresses to a user the
+security decision they will be required to make.</li>
+<li>The permission string must be localized to many different languages.</li>
+<li>Uses may choose not to install an application because a permission is
+confusing or perceived as risky.</li>
+<li>Applications may request the permission when the creator of the permission
+has not been installed.</li>
+</ul></p>
+
+<p>Each of these poses a significant non-technical challenge for an application
+developer, which is why we discourage the use of Dangerous permission.</p>
+
+<a name="Networking"></a>
+<h2>Using Networking</h2>
+
+<h3>Using IP Networking</h3>
+
+<p>Networking on Android is not significantly different from Linux
+environments.  The key consideration is making sure that appropriate protocols
+are used for sensitive data, such as <a
+href="{@docRoot}reference/javax/net/ssl/HttpsURLConnection.html">HTTPS</a> for
+web traffic.   We prefer use of HTTPS over HTTP anywhere that HTTPS is
+supported on the server, since mobile devices frequently connect on networks
+that are not secured, such as public WiFi hotspots.</p>
+
+<p>Authenticated, encrypted socket-level communication can be easily
+implemented using the <code><a
+href="{@docRoot}reference/javax/net/ssl/SSLSocket.html">SSLSocket</a></code>
+class.  Given the frequency with which Android devices connect to unsecured
+wireless networks using WiFi, the use of secure networking is strongly
+encouraged for all applications.</p>
+
+<p>We have seen some applications use <a
+href="http://en.wikipedia.org/wiki/Localhost">localhost</a> network ports for
+handling sensitive IPC.  We discourage this approach since these interfaces are
+accessible by other applications on the device.  Instead, use an Android IPC
+mechanism where authentication is possible such as a Service and Binder.  (Even
+worse than using loopback is to bind to INADDR_ANY since then your application
+may receive requests from anywhere.  We’ve seen that, too.)</p>
+
+<p>Also, one common issue that warrants repeating is to make sure that you do
+not trust data downloaded from HTTP or other insecure protocols.  This includes
+validation of input in <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code> and
+any responses to intents issued against HTTP.</p>
+
+<h3>Using Telephony Networking</h3>
+
+<p>SMS is the telephony protocol most frequently used by Android developers.
+Developers should keep in mind that this protocol was primarily designed for
+user-to-user communication and is not well-suited for some application
+purposes. Due to the limitations of SMS, we strongly recommend the use of <a
+href="http://code.google.com/android/c2dm/">C2DM</a> and IP networking for
+sending data messages to devices.</p>
+
+<p>Many developers do not realize that SMS is not encrypted or strongly
+authenticated on the network or on the device.  In particular, any SMS receiver
+should expect that a malicious user may have sent the SMS to your application
+-- do not rely on unauthenticated SMS data to perform sensitive commands.
+Also, you should be aware that SMS may be subject to spoofing and/or
+interception on the network.  On the Android-powered device itself, SMS
+messages are transmitted as Broadcast intents, so they may be read or captured
+by other applications that have the READ_SMS permission.</p>
+
+<a name="DynamicCode"></a>
+<h2>Dynamically Loading Code</h2>
+
+<p>We strongly discourage loading code from outside of the application APK.
+Doing so significantly increases the likelihood of application compromise due
+to code injection or code tampering.  It also adds complexity around version
+management and application testing.  Finally, it can make it impossible to
+verify the behavior of an application, so it may be prohibited in some
+environments.</p>
+
+<p>If your application does dynamically load code, the most important thing to
+keep in mind about dynamically loaded code is that it runs with the same
+security permissions as the application APK.  The user made a decision to
+install your application based on your identity, and they are expecting that
+you provide any code run within the application, including code that is
+dynamically loaded.</p>
+
+<p>The major security risk associated with dynamically loading code is that the
+code needs to come from a verifiable source. If the modules are included
+directly within your APK, then they cannot be modified by other applications.
+This is true whether the code is a native library or a class being loaded using
+<a href="{@docRoot}reference/dalvik/system/DexClassLoader.html">
+<code>DexClassLoader</code></a>.  We have seen many instances of applications
+attempting to load code from insecure locations, such as downloaded from the
+network over unencrypted protocols or from world writable locations such as
+external storage. These locations could allow someone on the network to modify
+the content in transit, or another application on a users device to modify the
+content, respectively.</p>
+
+
+<h3>Using WebView</h3>
+
+<p>Since WebView consumes web content that can include HTML and JavaScript,
+improper use can introduce common web security issues such as <a
+href="http://en.wikipedia.org/wiki/Cross_site_scripting">cross-site-scripting</a
+> (JavaScript injection).  Android includes a number of mechanisms to reduce
+the scope of these potential issues by limiting the capability of WebView to
+the minimum functionality required by your application.</p>
+
+<p>If your application does not directly use JavaScript within a <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, do
+not call
+<a href="{@docRoot}reference/android/webkit/WebSettings.html#setJavaScriptEnabled(boolean)
+<code>setJavaScriptEnabled()</code></a>. We have seen this method invoked
+in sample code that might be repurposed in production application -- so
+remove it if necessary. By default, <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code> does
+not execute JavaScript so cross-site-scripting is not possible.</p>
+
+<p>Use <code><a
+href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(jav
+a.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> with
+particular care because it allows JavaScript to invoke operations that are
+normally reserved for Android applications.  Only expose <code><a
+href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(jav
+a.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> to
+sources from which all input is trustworthy.  If untrusted input is allowed,
+untrusted JavaScript may be able to invoke Android methods.  In general, we
+recommend only exposing <code><a
+href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(jav
+a.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> to
+JavaScript that is contained within your application APK.</p>
+
+<p>Do not trust information downloaded over HTTP, use HTTPS instead.  Even if
+you are connecting only to a single website that you trust or control, HTTP is
+subject to <a
+href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">MiTM</a> attacks
+and interception of data.  Sensitive capabilities using <code><a
+href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(jav
+a.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code> should
+not ever be exposed to unverified script downloaded over HTTP. Note that even
+with the use of HTTPS,
+<code><a
+href="{@docRoot}reference/android/webkit/WebView.html#addJavascriptInterface(jav
+a.lang.Object,%20java.lang.String)">addJavaScriptInterface()</a></code>
+increases the attack surface of your application to include the server
+infrastructure and all CAs trusted by the Android-powered device.</p>
+
+<p>If your application accesses sensitive data with a <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, you
+may want to use the <code><a
+href="{@docRoot}reference/android/webkit/WebView.html#clearCache(boolean)">
+clearCache()</a></code> method to delete any files stored locally. Server side
+headers like no-cache can also be used to indicate that an application should
+not cache particular content.</p>
+
+<a name="Input"></a>
+<h2>Performing Input Validation</h2>
+
+<p>Insufficient input validation is one of the most common security problems
+affecting applications, regardless of what platform they run on. Android does
+have platform-level countermeasures that reduce the exposure of applications to
+input validation issues, you should use those features where possible. Also
+note that selection of type-safe languages tends to reduce the likelihood of
+input validation issues.  We strongly recommend building your applications with
+the Android SDK.</p>
+
+<p>If you are using native code, then any data read from files, received over
+the network, or received from an IPC has the potential to introduce a security
+issue.  The most common problems are <a
+href="http://en.wikipedia.org/wiki/Buffer_overflow">buffer overflows</a>, <a
+href="http://en.wikipedia.org/wiki/Double_free#Use_after_free">use after
+free</a>, and <a
+href="http://en.wikipedia.org/wiki/Off-by-one_error">off-by-one errors</a>.
+Android provides a number of technologies like ASLR and DEP that reduce the
+exploitability of these errors, but they do not solve the underlying problem.
+These can be prevented by careful handling of pointers and managing of
+buffers.</p>
+
+<p>Dynamic, string based languages such as JavaScript and SQL are also subject
+to input validation problems due to escape characters and <a
+href="http://en.wikipedia.org/wiki/Code_injection">script injection</a>.</p>
+
+<p>If you are using data within queries that are submitted to SQL Database or a
+Content Provider, SQL Injection may be an issue.  The best defense is to use
+parameterized queries, as is discussed in the ContentProviders section.
+Limiting permissions to read-only or write-only can also reduce the potential
+for harm related to SQL Injection.</p>
+
+<p>If you are using <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, then
+you must consider the possibility of XSS.  If your application does not
+directly use JavaScript within a <code><a
+href="{@docRoot}reference/android/webkit/WebView.html">WebView</a></code>, do
+not call setJavaScriptEnabled() and XSS is no longer possible. If you must
+enable JavaScript then the WebView section provides other security best
+practices.</p>
+
+<p>If you cannot use the security features above, we strongly recommend the use
+of well-structured data formats and verifying that the data conforms to the
+expected format. While blacklisting of characters or character-replacement can
+be an effective strategy, these techniques are error-prone in practice and
+should be avoided when possible.</p>
+
+<a name="UserData"></a>
+<h2>Handling User Data</h2>
+
+<p>In general, the best approach is to minimize use of APIs that access
+sensitive or personal user data. If you have access to data and can avoid
+storing or transmitting the information, do not store or transmit the data.
+Finally, consider if there is a way that your application logic can be
+implemented using a hash or non-reversible form of the data.  For example, your
+application might use the hash of an an email address as a primary key, to
+avoid transmitting or storing the email address.  This reduces the chances of
+inadvertently exposing data, and it also reduces the chance of attackers
+attempting to exploit your application.</p>
+
+<p>If your application accesses personal information such as passwords or
+usernames, keep in mind that some jurisdictions may require you to provide a
+privacy policy explaining your use and storage of that data.  So following the
+security best practice of minimizing access to user data may also simplify
+compliance.</p>
+
+<p>You should also consider whether your application might be inadvertently
+exposing personal information to other parties such as third-party components
+for advertising or third-party services used by your application. If you don't
+know why a component or service requires a personal information, don’t
+provide it.  In general, reducing the access to personal information by your
+application will reduce the potential for problems in this area.</p>
+
+<p>If access to sensitive data is required, evaluate whether that information
+must be transmitted to a server, or whether the operation can be performed on
+the client.  Consider running any code using sensitive data on the client to
+avoid transmitting user data.</p>
+
+<p>Also, make sure that you do not inadvertently expose user data to other
+application on the device through overly permissive IPC, world writable files,
+or network sockets. This is a special case of permission redelegation,
+discussed in the Requesting Permissions section.</p>
+
+<p>If a GUID is required, create a large, unique number and store it.  Do not
+use phone identifiers such as the phone number or IMEI which may be associated
+with personal information.  This topic is discussed in more detail in the <a
+href="http://android-developers.blogspot.com/2011/03/identifying-app-installatio
+ns.html">Android Developer Blog</a>.</p>
+
+<h3>Handling Credentials</h3>
+
+<p>In general, we recommend minimizing the frequency of asking for user
+credentials -- to make phishing attacks more conspicuous, and less likely to be
+successful.  Instead use an authorization token and refresh it.</p>
+
+<p>Where possible, username and password should not be stored on the device.
+Instead, perform initial authentication using the username and password
+supplied by the user, and then use a short-lived, service-specific
+authorization token.</p>
+
+<p>Services that will be accessible to multiple applications should be accessed
+using <code>
+<a href="{@docRoot}reference/android/accounts/AccountManager.html">
+AccountManager</a></code>. If possible, use the <code><a
+href="{@docRoot}reference/android/accounts/AccountManager.html">
+AccountManager</a></code> class to invoke a cloud-based service and do not store
+passwords on the device.</p>
+
+<p>After using <code><a
+href="{@docRoot}reference/android/accounts/AccountManager.html">
+AccountManager</a></code> to retrieve an Account, check the <code><a
+href="{@docRoot}reference/android/accounts/Account.html#CREATOR">CREATOR</a>
+</code> before passing in any credentials, so that you do not inadvertently pass
+credentials to the wrong application.</p>
+
+<p>If credentials are to be used only by applications that you create, then you
+can verify the application which accesses the <code><a
+href="{@docRoot}reference/android/accounts/AccountManager.html">
+AccountManager</a></code> using <code><a href="<code><a
+href="{@docRoot}h/reference/android/content/pm/PackageManager.html#checkSignatur
+es(java.lang.String,%20java.lang.String)">checkSignature()</a></code>.
+Alternatively, if only one application will use the credential, you might use a
+<code><a
+href={@docRoot}reference/java/security/KeyStore.html">KeyStore</a></code> for
+storage.</p>
+
+<a name="Crypto"></a>
+<h2>Using Cryptography</h2>
+
+<p>In addition to providing data isolation, supporting full-filesystem
+encryption, and providing secure communications channels Android provides a
+wide array of algorithms for protecting data using cryptography.</p>
+
+<p>In general, try to use the highest level of pre-existing framework
+implementation that can  support your use case.  If you need to securely
+retrieve a file from a known location, a simple HTTPS URI may be adequate and
+require no knowledge of cryptography on your part.  If you need a secure
+tunnel, consider using
+<a href="{@docRoot}reference/javax/net/ssl/HttpsURLConnection.html">
+<code>HttpsURLConnection</code></a> or <code><a
+href="{@docRoot}reference/javax/net/ssl/SSLSocket.html">SSLSocket</a></code>,
+rather than writing your own protocol.</p>
+
+<p>If you do find yourself needing to implement your own protocol, we strongly
+recommend that you not implement your own cryptographic algorithms. Use
+existing cryptographic algorithms such as those in the implementation of AES or
+RSA provided in the <code><a
+href="{@docRoot}reference/javax/crypto/Cipher.html">Cipher</a></code> class.</p>
+
+<p>Use a secure random number generator (
+<a href="http://developer.android.com/reference/java/security/SecureRandom.html">
+<code>SecureRandom</code></a>) to initialize any cryptographic keys (<a
+href="http://developer.android.com/reference/javax/crypto/KeyGenerator.html">
+<code>KeyGenerator</code></a>). Use of a key that is not generated with a secure random
+number generator significantly weakens the strength of the algorithm, and may
+allow offline attacks.</p>
+
+<p>If you need to store a key for repeated use, use a mechanism like <code><a
+href={@docRoot}reference/java/security/KeyStore.html">KeyStore</a></code> that
+provides a mechanism for long term storage and retrieval of cryptographic
+keys.</p>
+
+<h2>Conclusion</h2>
+
+<p>Android provides developers with the ability to design applications with a
+broad range of security requirements.  These best practices will help you make
+sure that your application takes advantage of the security benefits provided by
+the platform.</p>
+
+<p>You can receive more information on these topics and discuss security best
+practices with other developers in the <a
+href="http://groups.google.com/group/android-security-discuss">Android Security
+Discuss</a> Google Group</p>
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
index 7bbf5e6..820c3c0 100644
--- a/docs/html/guide/topics/admin/device-admin.jd
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -27,6 +27,12 @@
       <li>{@link android.app.admin.DevicePolicyManager}</li>
       <li>{@link android.app.admin.DeviceAdminInfo}</li>
     </ol>
+    <h2>Related samples</h2>
+    <ol>
+      <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html">
+DeviceAdminSample</a></li>
+</ol>
 </div>
 </div>
 
@@ -201,6 +207,16 @@
 <td>Specifies that the storage area should be encrypted, if the device supports it. 
 Introduced in Android 3.0.</td> </tr>
 
+<tr>
+  <td>Disable camera</td>
+  
+  <td>Specifies that the camera should be disabled. Note that this doesn't have
+to be a permanent disabling. The camera can be enabled/disabled dynamically
+based on context, time, and so on. Introduced in Android 4.0.</td>
+  
+</tr>
+
+
 </table>
 
 <h4>Other features</h4>
@@ -247,6 +263,7 @@
 locks.</li>
   <li>Make the device lock immediately.</li>
   <li>Wipe the device's data (that is, restore factory settings).</li>
+  <li>Disable the camera.</li>
   
 </ul>
 
@@ -280,46 +297,38 @@
   <li>A declaration of security policies used in metadata.</li>
 </ul>
 <p>Here is an excerpt from the Device Administration sample manifest:</p>
-<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample$Controller&quot;
-          android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
-    &lt;intent-filter&gt;
-        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
-        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
-    &lt;/intent-filter&gt;
+<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample&quot;
+            android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
+        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
+    &lt;/intent-filter&gt;
 &lt;/activity&gt;
-
-&lt;receiver android:name=&quot;.app.DeviceAdminSample&quot;
-          android:label=&quot;&#64;string/sample_device_admin&quot;
-          android:description=&quot;&#64;string/sample_device_admin_description&quot;
-          android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
-    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
-               android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
-    &lt;intent-filter&gt;
-        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
-    &lt;/intent-filter&gt;
+&lt;receiver android:name=&quot;.app.DeviceAdminSample$DeviceAdminSampleReceiver&quot;
+        android:label=&quot;&#64;string/sample_device_admin&quot;
+        android:description=&quot;&#64;string/sample_device_admin_description&quot;
+        android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
+    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
+            android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
+    &lt;/intent-filter&gt;
 &lt;/receiver&gt;</pre>
 
  <p>Note that:</p>
 <ul>
-  <li>The activity in the sample application is an {@link android.app.Activity}
-subclass called <code>Controller</code>. The syntax
-<code>&quot;.app.DeviceAdminSample$Controller&quot;</code>  indicates that
-<code>Controller</code> is an inner class that is nested inside the
-<code>DeviceAdminSample</code> class. Note that an Activity does not need to be
-an inner class; it just is in this example.</li>
-
 <li>The following attributes refer to string resources that for the sample application reside in
 <code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
 <a
 href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
 <ul>
-<li><code>android:label=&quot;@string/activity_sample_device_admin&quot;</code> refers to the
+<li><code>android:label=&quot;&#64;string/activity_sample_device_admin&quot;</code> refers to the
 user-readable label for the activity.</li>
 
-<li><code>android:label=&quot;@string/sample_device_admin&quot;</code> refers to the
+<li><code>android:label=&quot;&#64;string/sample_device_admin&quot;</code> refers to the
 user-readable label for the permission.</li>
 
-<li><code>android:description=&quot;@string/sample_device_admin_description&quot;</code> refers to
+<li><code>android:description=&quot;&#64;string/sample_device_admin_description&quot;</code> refers to
 the user-readable description of the permission. A descripton is typically longer and more
 informative than
 a label.</li>
@@ -357,6 +366,9 @@
     &lt;reset-password /&gt;
     &lt;force-lock /&gt;
     &lt;wipe-data /&gt;
+    &lt;expire-password /&gt;
+    &lt;encrypted-storage /&gt;
+    &lt;disable-camera /&gt;
   &lt;/uses-policies&gt;
 &lt;/device-admin&gt;
 </pre>
@@ -401,33 +413,34 @@
 events. For example:</p>
 <pre>public class DeviceAdminSample extends DeviceAdminReceiver {
 
-...
+    void showToast(Context context, String msg) {
+        String status = context.getString(R.string.admin_receiver_status, msg);
+        Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
+    }
+
     &#64;Override
-    public void onEnabled(Context context, Intent intent) {
-        showToast(context, &quot;Sample Device Admin: enabled&quot;);
-    }
+    public void onEnabled(Context context, Intent intent) {
+        showToast(context, context.getString(R.string.admin_receiver_status_enabled));
+    }
 
-    &#64;Override
-    public CharSequence onDisableRequested(Context context, Intent intent) {
-        return &quot;This is an optional message to warn the user about disabling.&quot;;
-    }
+    &#64;Override
+    public CharSequence onDisableRequested(Context context, Intent intent) {
+        return context.getString(R.string.admin_receiver_status_disable_warning);
+    }
 
-    &#64;Override
-    public void onDisabled(Context context, Intent intent) {
-        showToast(context, &quot;Sample Device Admin: disabled&quot;);
-    }
+    &#64;Override
+    public void onDisabled(Context context, Intent intent) {
+        showToast(context, context.getString(R.string.admin_receiver_status_disabled));
+    }
 
-    &#64;Override
-    public void onPasswordChanged(Context context, Intent intent) {
-        showToast(context, &quot;Sample Device Admin: pw changed&quot;);
-    }
-
-    void showToast(Context context, CharSequence msg) {
-        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+    &#64;Override
+    public void onPasswordChanged(Context context, Intent intent) {
+        showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
     }
 ...
 }</pre>
 
+
 <h4 id="enabling">Enabling the application</h4>
 <p>One of the major events a device admin application has to handle is the user
 enabling the application. The user must explicitly enable the application for
@@ -438,43 +451,50 @@
 action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}
 intent. In the
 sample application, this happens when the user clicks the <strong>Enable
-Admin</strong> button. </p>
-<p>When the user clicks the <strong>Enable Admin</strong> button, the display
-changes to prompt the user to enable the device admin application, as shown in figure
+Admin</strong> checkbox. </p>
+<p>When the user clicks the <strong>Enable Admin</strong> checkbox, the display
+changes to prompt the user to activate the device admin application, as shown in figure
 2.</p>
 
 <img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
 <p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
-<p>Below  is the code that gets executed when the user clicks the <strong>Enable
-Admin</strong> button shown in figure 1. </p>
 
-<pre> private OnClickListener mEnableListener = new OnClickListener() {
-    public void onClick(View v) {
-        // Launch the activity to have the user enable our admin.
-        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
-        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
-               mDeviceAdminSample);
-        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
-               &quot;Additional text explaining why this needs to be added.&quot;);
-        startActivityForResult(intent, RESULT_ENABLE);
-    }
-};
+<p>Below  is the code that gets executed when the user clicks the <strong>Enable Admin</strong> checkbox. This has the effect of triggering the 
+{@link android.preference.Preference.OnPreferenceChangeListener#onPreferenceChange(android.preference.Preference, java.lang.Object) onPreferenceChange()} 
+callback. This callback is invoked when the value of this  {@link android.preference.Preference} has been changed by the user and is about to be set and/or persisted. If the user is enabling the application, the display
+changes to prompt the user to activate the device admin application, as shown in figure
+2. Otherwise, the device admin application is disabled. </p>
 
-...
-// This code checks whether the device admin app was successfully enabled.
-&#64;Override
-protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-    switch (requestCode) {
-        case RESULT_ENABLE:
-            if (resultCode == Activity.RESULT_OK) {
-                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enabled!&quot;);
-            } else {
-                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enable FAILED!&quot;);
-            }
-            return;
-    }
-    super.onActivityResult(requestCode, resultCode, data);
-}</pre>
+<pre>&#64;Override
+        public boolean onPreferenceChange(Preference preference, Object newValue) {
+            if (super.onPreferenceChange(preference, newValue)) {
+                return true;
+            }
+            boolean value = (Boolean) newValue;
+            if (preference == mEnableCheckbox) {
+                if (value != mAdminActive) {
+                    if (value) {
+                        // Launch the activity to have the user enable our admin.
+                        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
+                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
+                                mActivity.getString(R.string.add_admin_extra_app_text));
+                        startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
+                        // return false - don't update checkbox until we're really active
+                        return false;
+                    } else {
+                        mDPM.removeActiveAdmin(mDeviceAdminSample);
+                        enableDeviceCapabilitiesArea(false);
+                        mAdminActive = false;
+                    }
+                }
+            } else if (preference == mDisableCameraCheckbox) {
+                mDPM.setCameraDisabled(mDeviceAdminSample, value);
+                ...
+            }
+            return true;
+        }</pre>
+
 
 <p>The line
 <code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
@@ -489,18 +509,17 @@
 {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager}
 method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver}
 component as its argument:</p>
+
 <pre>
 DevicePolicyManager mDPM;
 ...
-boolean active = mDPM.isAdminActive(mDeviceAdminSample);
-if (active) {
-    // Admin app is active, so do some admin stuff
-               ...
-} else {
-    // do something else
+private boolean isActiveAdmin() {
+    return mDPM.isAdminActive(mDeviceAdminSample);
 }
 </pre>
 
+
+
 <h3 id="admin_ops">Managing policies</h3>
 <p>{@link android.app.admin.DevicePolicyManager} is a public class for managing policies
 enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one
@@ -618,49 +637,6 @@
 ...
 mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
 </pre>
-
-<p>From the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html"
->Device Administration API sample</a>, here is the code
-that updates the password expiration status:</p>
-
-<pre>
-DevicePolicyManager mDPM;
-ComponentName mDeviceAdminSample;
-private TextView mPasswordExpirationStatus;
-...
-void updatePasswordExpirationStatus() {
-    boolean active = mDPM.isAdminActive(mDeviceAdminSample);
-    String statusText;
-    if (active) {
-        long now = System.currentTimeMillis();
-        // Query the DevicePolicyManager twice - first for the expiration values
-        // set by the sample app, and later, for the system values (which may be different
-        // if there is another administrator active.)
-        long expirationDate = mDPM.getPasswordExpiration(mDeviceAdminSample);
-        long mSecUntilExpiration = expirationDate - now;
-        if (mSecUntilExpiration &gt;= 0) {
-            statusText = &quot;Expiration in &quot; + countdownString(mSecUntilExpiration);
-        } else {
-            statusText = &quot;Expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
-        }
-
-        // expirationTimeout is the cycle time between required password refresh
-        long expirationTimeout = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
-        statusText += &quot; / timeout period &quot; + countdownString(expirationTimeout);
-
-        // Now report the aggregate (global) expiration time
-        statusText += &quot; / Aggregate &quot;;
-        expirationDate = mDPM.getPasswordExpiration(null);
-        mSecUntilExpiration = expirationDate - now;
-        if (mSecUntilExpiration &gt;= 0) {
-            statusText += &quot;expiration in &quot; + countdownString(mSecUntilExpiration);
-        } else {
-            statusText += &quot;expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
-        }
-    } else {
-        statusText = &quot;&lt;inactive&gt;&quot;;
-    }
-    mPasswordExpirationStatus.setText(statusText);</pre>
     
 <h5 id="history">Restrict password based on history</h5>
 
@@ -718,6 +694,19 @@
 <p>The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of
 additional options. Currently the value must be 0. </p>
 
+<h4>Disable camera</h4>
+<p>Beginning with Android 4.0, you can disable the camera. Note that this doesn't have to be a permanent disabling. The camera can be enabled/disabled dynamically based on context, time, and so on. </p>
+<p>You control whether the camera is disabled by using the 
+{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean) setCameraDisabled()} method. For example, this snippet sets the camera to be enabled or disabled based on a checkbox setting:</p>
+
+<pre>private CheckBoxPreference mDisableCameraCheckbox;
+DevicePolicyManager mDPM;
+ComponentName mDeviceAdminSample;
+...
+mDPM.setCameraDisabled(mDeviceAdminSample, mDisableCameraCheckbox.isChecked());<br />
+</pre>
+
+
 <h4 id=storage">Storage encryption</h4>
 <p>Beginning with Android 3.0, you can use the 
 {@link android.app.admin.DevicePolicyManager#setStorageEncryption(android.content.ComponentName,boolean) setStorageEncryption()} 
diff --git a/docs/html/guide/topics/providers/calendar-provider.jd b/docs/html/guide/topics/providers/calendar-provider.jd
new file mode 100644
index 0000000..3ab5125
--- /dev/null
+++ b/docs/html/guide/topics/providers/calendar-provider.jd
@@ -0,0 +1,1185 @@
+page.title=Calendar Provider
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+    <h2>In this document</h2>
+    <ol>
+  <li><a href="#overview">Basics</a></li>
+  <li><a href="#manifest">User Permissions</a></li>
+  <li><a href="#calendar">Calendars table</a>
+<ol>
+      <li><a href="#query">Querying a calendar</a></li>
+      <li><a href="#modify-calendar">Modifying a calendar</a></li>
+      <li><a href="#insert-calendar">Inserting a calendar</a></li>
+    </ol>
+  </li>
+  <li><a href="#events">Events table</a>
+<ol>
+      <li><a href="#add-event">Adding Events</a></li>
+      <li><a href="#update-event">Updating Events</a></li>
+      <li><a href="#delete-event">Deleting Events</a></li>
+    </ol>
+  </li>
+  <li><a href="#attendees">Attendees table</a>
+<ol>
+      <li><a href="#add-attendees">Adding Attendees</a></li>
+    </ol>
+  </li>
+  <li><a href="#reminders">Reminders table</a>
+<ol>
+      <li><a href="#add-reminders">Adding Reminders</a></li>
+    </ol>
+  </li>
+  <li><a href="#instances">Instances table</a>
+  <ol>
+      <li><a href="#query-instances">Querying the Instances table</a></li>
+  </ol></li>
+  <li><a href="#intents">Calendar Intents</a>
+  <ol>
+      <li><a href="#intent-insert">Using an intent to insert an event</a></li>
+      <li><a href="#intent-edit">Using an intent to edit an event</a></li>
+      <li><a href="#intent-view">Using intents to view calendar data</a></li>
+    </ol>
+  </li>
+  
+  <li><a href="#sync-adapter">Sync Adapters</a></li>
+</ol>
+
+    <h2>Key classes</h2>
+    <ol>
+      <li>{@link android.provider.CalendarContract.Calendars}</li>
+      <li>{@link android.provider.CalendarContract.Events}</li>
+      <li>{@link android.provider.CalendarContract.Attendees}</li>
+      <li>{@link android.provider.CalendarContract.Reminders}</li>
+    </ol>
+</div>
+</div>
+
+<p>The Calendar Provider is a repository for a user's calendar events. The
+Calendar Provider API allows you to perform query, insert, update, and delete
+operations on calendars, events, attendees, reminders, and so on.</p>
+
+
+<p>The Calender Provider API can be used by applications and sync adapters. The
+rules vary depending on what type of program is making the calls. This document
+focuses primarily on using the Calendar Provider API as an application. For 
+a discussion of how sync adapters are different, see 
+<a href="#sync-adapter">Sync Adapters</a>.</p>
+
+
+<p>Normally, to read or write calendar data, an application's manifest must
+include the proper permissions, described in <a href="#manifest">User
+Permissions</a>. To make performing common operations easier, the Calendar
+Provider offers a set of intents, as described in <a href="#intents">Calendar
+Intents</a>. These intents take users to the Calendar application to insert, view,
+and edit events. The user interacts with the Calendar application and then
+returns to the original application. Thus your application doesn't need to request permissions,
+nor does it need to provide a user interface to view or create events.</p>
+
+<h2 id="overview">Basics</h2>
+
+<p><a href="{@docRoot}guide/topics/providers/content-providers.html">Content providers</a> store data and make it accessible to 
+applications. The content providers offered by the Android platform (including the Calendar Provider) typically expose data as a set of tables based on a
+relational database model, where each row is a record and each column is data of
+a particular type and meaning. Through the Calendar Provider API, applications
+and sync adapters can get read/write access to the database tables that hold a
+user's calendar data.</p>
+
+<p>Every content provider exposes a public URI (wrapped as a 
+{@link android.net.Uri} 
+object) that uniquely identifies its data set.  A content provider that controls
+ multiple data sets (multiple tables) exposes a separate URI for each one.  All 
+URIs for providers begin with the string &quot;content://&quot;.  This
+identifies the data as being controlled by a content provider. The Calendar
+Provider defines constants for the URIs for each of its classes (tables). These
+URIs have the format <code><em>&lt;class&gt;</em>.CONTENT_URI</code>. For
+example, {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.</p>
+
+<p>Figure 1 shows a graphical representation of the Calendar Provider data model. It shows the
+main tables and the fields that link them to each other.</p>
+
+<img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model"/>
+<p class="img-caption"><strong>Figure 1.</strong> Calendar Provider data model.</p>
+
+<p>A user can have multiple calendars, and different calendars can be associated with different types of accounts (Google Calendar, Exchange, and so on).</p>
+
+<p>The {@link android.provider.CalendarContract} defines the data model of calendar and event related information. This data is stored in a number of tables, listed below.</p>
+
+<table>
+  <tr>
+    <th>Table (Class)</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><p>{@link android.provider.CalendarContract.Calendars}</p></td>
+    
+    <td>This table holds 
+the calendar-specific information. Each  row in this table contains the details for
+a single calendar, such as the  name, color, sync information, and so on.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Events}</td>
+    
+    <td>This table holds the
+event-specific information. Each row  in this table has the information for a single
+event&mdash;for example, event title, location, start time, end
+time, and so on. The event can occur one-time or can recur multiple times. Attendees,
+reminders, and extended  properties are stored in separate tables. 
+They each have an {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} 
+that references the {@link android.provider.BaseColumns#_ID} in the Events table.</td>
+
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances}</td>
+    
+    <td>This table holds the
+start and end time for each occurrence of an event. Each row in this table
+represents a single event occurrence. For one-time events there is a 1:1 mapping
+of instances to events. For recurring events, multiple rows are automatically
+ generated that correspond to multiple occurrences of that event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Attendees}</td>
+    
+    <td>This table holds the
+event attendee (guest) information. Each row represents a single guest of an
+event. It specifies the type of guest and the guest's attendance response
+for the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Reminders}</td>
+    
+    <td>This table holds the
+alert/notification data. Each row represents a single alert for an event. An
+event can have multiple reminders. The maximum number of reminders per event is
+specified in 
+{@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS}, 
+which is set by the sync adapter that
+owns  the given calendar. Reminders are specified in minutes before the event
+and have a method that determines how the user will be alerted.</td>
+  </tr>
+  
+</table>
+
+<p>The Calendar Provider API is designed to be flexible and powerful. At the
+same time, it's important to provide a good end user experience and
+protect the integrity of the calendar and its data. To this end, here are
+some things to keep in mind when using the API:</p>
+
+<ul>
+
+<li><strong>Inserting, updating, and viewing calendar events.</strong> To directly insert, modify, and read events from the Calendar Provider, you need the appropriate <a href="#manifest">permissions</a>. However, if you're not building a full-fledged calendar application or sync adapter, requesting these permissions isn't necessary. You can instead use intents supported by Android's Calendar application to hand off read and write operations to that application. When you use the intents, your application sends users to the Calendar application to perform the desired operation
+in a pre-filled form. After they're done, they're returned to your application.
+By designing your application to perform common operations through the Calendar,
+you provide users with a consistent, robust user interface. This is the
+recommended approach. For more information, see <a href="#intents">Calendar
+Intents</a>.</p>
+
+
+<li><strong>Sync adapters.</strong> A sync adapter synchronizes the calendar data
+on a user's device with another server or data source. In the 
+{@link android.provider.CalendarContract.Calendars} and
+{@link android.provider.CalendarContract.Events} tables, 
+there are columns that are reserved for the sync adapters to use.
+The provider and applications should not modify them. In fact, they are not
+visible unless they are accessed as a sync adapter. For more information about
+sync adapters, see <a href="#sync-adapter">Sync Adapters</a>.</li>
+
+</ul>
+
+
+<h2 id="manifest">User Permissions</h2>
+
+<p>To read calendar data, an application must include the {@link
+android.Manifest.permission#READ_CALENDAR} permission in its manifest file. It
+must include the {@link android.Manifest.permission#WRITE_CALENDAR} permission
+to delete, insert or update calendar data:</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;...&gt;
+    &lt;uses-sdk android:minSdkVersion=&quot;14&quot; /&gt;
+    &lt;uses-permission android:name=&quot;android.permission.READ_CALENDAR&quot; /&gt;
+    &lt;uses-permission android:name=&quot;android.permission.WRITE_CALENDAR&quot; /&gt;
+    ...
+&lt;/manifest&gt;
+</pre>
+
+
+<h2 id="calendar">Calendars Table</h2>
+
+<p>The {@link android.provider.CalendarContract.Calendars} table contains details 
+for individual calendars. The following
+Calendars columns are writable by both an application and a <a href="#sync-adapter">sync adapter</a>. 
+For a full list of supported fields, see the
+{@link android.provider.CalendarContract.Calendars} reference.</p>
+<table>
+  <tr>
+    <th>Constant</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Calendars#NAME}</td>
+    <td>The name of the calendar.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td>
+    <td>The name of this calendar that is displayed to the user.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td>
+    
+    <td>A boolean indicating whether the calendar is selected to be displayed. A
+value of 0 indicates that events associated with this calendar should not be
+shown.  A value of 1 indicates that events associated with this calendar should
+be shown. This value affects the generation of rows in the {@link
+android.provider.CalendarContract.Instances} table.</td>
+
+
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td>
+    
+    <td>A boolean indicating whether the calendar should be synced and have its
+events stored on the device. A value of 0 says do not sync this calendar or
+store its events on the device.  A value of 1 says sync events for this calendar
+and store its events on the device.</td>
+  </tr>
+</table>
+
+<h3 id="query">Querying a calendar</h3>
+
+<p>Here is an example that shows how to get all the calendars for a particular
+user. For simplicity's sake, in this example the query operation is shown in the
+user interface thread ("main thread"). In practice, this should be done in an asynchronous
+thread instead of on the main thread. For more discussion, see 
+<a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a>. If you are not just reading data but modifying it, see {@link android.content.AsyncQueryHandler}.
+</p>
+
+
+<pre>
+  // Projection array. Creating indices for this array instead of doing
+  // dynamic lookups improves performance.
+  public static final String[] EVENT_PROJECTION = new String[] {
+    Calendars._ID,                           // 0
+    Calendars.ACCOUNT_NAME,                  // 1
+    Calendars.CALENDAR_DISPLAY_NAME          // 2
+  };
+  
+  // The indices for the projection array above.
+  private static final int PROJECTION_ID_INDEX = 0;
+  private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
+  private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;</pre>
+  
+
+<div class="sidebox-wrapper"> <div class="sidebox"> <h3>Why must you include
+ACCOUNT_TYPE?</h3> <p>If you query on a {@link
+android.provider.CalendarContract.Calendars#ACCOUNT_NAME
+Calendars.ACCOUNT_NAME}, you must also include 
+{@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}
+in the selection. That is because a given account is
+only considered unique given both its <code>ACCOUNT_NAME</code> and its
+<code>ACCOUNT_TYPE</code>. The <code>ACCOUNT_TYPE</code> refers to the way that
+the account is being  synced. It is often but not always the domain. For
+example, an account could be  synced through a corporate pop3 sync adapter, in which
+case the <code>ACCOUNT_TYPE</code> would not be a domain. There is also a
+special type of account called {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} for calendars not
+associated with a device account. {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} accounts do not get
+synced.</p> </div> </div> 
+
+
+<p> In the next part of the example, you construct your query. The selection
+specifies the criteria for the query. In this example the query is looking for
+all calendars that have the <code>ACCOUNT_NAME</code>
+"sampleuser@google.com" and the <code>ACCOUNT_TYPE</code>
+"com.google". The query returns a {@link android.database.Cursor}
+object that you can use to traverse the result set returned by the database
+query. For more discussion of using queries in content providers, see <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.</p>
+
+
+<pre>// Run query
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+Uri uri = Calendars.CONTENT_URI;   
+String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 
+                        + Calendars.ACCOUNT_TYPE + " = ?))";
+String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google"}; 
+// Submit the query and get a Cursor object back. 
+cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre>
+
+<p>This next section uses the cursor to step through the result set. It uses the
+constants that were set up at the beginning of the example to return the values
+for each field.</p>
+    
+<pre>// Use the cursor to step through the returned records
+while (cur.moveToNext()) {
+    long calID = 0;
+    String displayName = null;
+    String accountName = null;        
+      
+    // Get the field values
+    calID = cur.getLong(PROJECTION_ID_INDEX);
+    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
+    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
+              
+    // Do something with the values...
+
+   ...
+}
+</pre>
+  
+<h3 id="modify-calendar">Modifying a calendar</h3>
+
+<p>To perform an update of an calendar, you can provide the {@link
+android.provider.BaseColumns#_ID} of the calendar either as an appended ID to
+the Uri 
+
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 
+or as the first selection item. The  selection
+should start with <code>&quot;_id=?&quot;</code>, and the first
+<code>selectionArg</code> should be  the {@link
+android.provider.BaseColumns#_ID} of the calendar. 
+You can also do updates by encoding the ID in the URI. This example changes a
+calendar's display name using the 
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 
+approach:</p>
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long calID = 2;
+ContentValues values = new ContentValues();
+// The new display name for the calendar
+values.put(Calendars.CALENDAR_DISPLAY_NAME, &quot;Trevor's Calendar&quot;);
+Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);</pre>
+
+<h3 id="insert-calendar">Inserting a calendar</h2>
+
+<p>Calendars are  designed to be primarily managed by a sync adapter, so you
+should only insert new calendars as a sync adapter. For the most part,
+applications can only make superficial changes to calendars, such as changing the display name. If
+an application needs to create a local calendar, it can do this by performing
+the calendar insertion as a sync adapter, using an {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} of {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}.
+{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} 
+is a special account type for calendars that are not
+associated with a device account. Calendars of this type are not synced to a server. For a
+discussion of sync adapters, see <a href="#sync-adapter">Sync Adapters</a>.</p>
+
+<h2 id="events">Events Table</h2>
+
+<p>The {@link android.provider.CalendarContract.Events} table contains details
+for individual events. To add, update, or delete  events, an application must
+include the {@link android.Manifest.permission#WRITE_CALENDAR} permission in its
+<a href="#manifest">manifest file</a>.</p>
+
+<p>The following Events columns are writable by both an application and a sync
+adapter. For a full list of supported fields, see the {@link
+android.provider.CalendarContract.Events} reference.</p>
+
+<table>
+  <tr>
+    <th>Constant</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td>
+    <td>The {@link android.provider.BaseColumns#_ID} of the calendar the event belongs to.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td>
+    <td>Email of the organizer (owner) of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td>
+    <td>The title of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td>
+    <td>Where the event takes place. </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td>
+    <td>The description of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td>
+    <td>The time the event starts in UTC milliseconds since the epoch. </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td>
+    <td>The time the event ends in UTC milliseconds since the epoch. </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td>
+    <td>The time zone for the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td>
+    <td>The time zone for the end time of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td>
+    
+    <td>The duration of the event in <a
+href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a> format.
+For example, a value of <code>&quot;PT1H&quot;</code> states that the event
+should last one hour, and a value of <code>&quot;P2W&quot;</code> indicates a
+duration of 2 weeks. </td>
+
+
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td>
+    
+    <td>A value of 1 indicates this event occupies the entire day, as defined by
+the local time zone. A value of 0 indicates it is a regular event that may start
+and end at any time during a day.</td>
+
+    
+  </tr>
+  
+  
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td>
+    
+    <td>The recurrence rule for the event format. For
+example, <code>&quot;FREQ=WEEKLY;COUNT=10;WKST=SU&quot;</code>. You can find
+more examples <a
+href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">here</a>.</td>
+    
+  </tr>
+  
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td>
+    <td>The recurrence dates for the event. 
+    You typically use {@link android.provider.CalendarContract.EventsColumns#RDATE} 
+    in conjunction with {@link android.provider.CalendarContract.EventsColumns#RRULE} 
+    to define an aggregate set of
+repeating occurrences. For more discussion, see the <a
+href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">RFC5545 spec</a>.</td>
+</tr>
+ 
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td>
+    
+    <td>If this event counts as busy time or is free time that can be 
+scheduled over. </td>
+    
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td>
+    <td>Whether guests can modify the event. </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td>
+    <td>Whether guests can invite other guests. </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td>
+    <td>Whether guests can see the list of attendees.</td>
+  </tr>
+</table>
+
+<h3 id="add-event">Adding Events</h3>
+
+<p>When your application inserts a new event, we recommend that you use an
+{@link android.content.Intent#ACTION_INSERT INSERT} Intent, as described in <a
+href="#intent-insert">Using an intent to insert an event</a>. However, if you
+need to, you can insert events directly. This section describes how to do
+this.</p>
+
+
+<p>Here are the rules for inserting a new event: </p>
+<ul>
+
+  <li>You must include  {@link
+android.provider.CalendarContract.EventsColumns#CALENDAR_ID} and {@link
+android.provider.CalendarContract.EventsColumns#DTSTART}.</li>
+
+<li>You must include an {@link
+android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}. To get a list
+of the system's installed time zone IDs, use {@link
+java.util.TimeZone#getAvailableIDs()}. Note that this rule does not apply if
+you're inserting an event through the {@link
+android.content.Intent#ACTION_INSERT INSERT} Intent, described in <a
+href="#intent-insert">Using an intent to insert an event</a>&mdash;in that
+scenario, a default time zone is supplied.</li>
+  
+  <li>For non-recurring events, you must include {@link
+android.provider.CalendarContract.EventsColumns#DTEND}. </li>
+  
+  
+  <li>For recurring events, you must include a {@link
+android.provider.CalendarContract.EventsColumns#DURATION} in addition to  {@link
+android.provider.CalendarContract.EventsColumns#RRULE} or {@link
+android.provider.CalendarContract.EventsColumns#RDATE}. Note that this rule does not apply if
+you're inserting an event through the {@link
+android.content.Intent#ACTION_INSERT INSERT} Intent, described in <a
+href="#intent-insert">Using an intent to insert an event</a>&mdash;in that
+scenario, you can use an {@link
+android.provider.CalendarContract.EventsColumns#RRULE} in conjunction with {@link android.provider.CalendarContract.EventsColumns#DTSTART} and {@link android.provider.CalendarContract.EventsColumns#DTEND}, and the Calendar application 
+converts it to a duration automatically.</li>
+  
+</ul>
+
+<p>Here is an example of inserting an event. This is being performed in the UI
+thread for simplicity. In practice, inserts and updates should be done in an
+asynchronous thread to move the action into a background thread. For more
+information, see {@link android.content.AsyncQueryHandler}.</p>
+
+
+<pre>
+long calID = 3;
+long startMillis = 0; 
+long endMillis = 0;     
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 9, 14, 7, 30);
+startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 9, 14, 8, 45);
+endMillis = endTime.getTimeInMillis();
+...
+
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Events.DTSTART, startMillis);
+values.put(Events.DTEND, endMillis);
+values.put(Events.TITLE, &quot;Jazzercise&quot;);
+values.put(Events.DESCRIPTION, &quot;Group workout&quot;);
+values.put(Events.CALENDAR_ID, calID);
+values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
+Uri uri = cr.insert(Events.CONTENT_URI, values);
+
+// get the event ID that is the last element in the Uri
+long eventID = Long.parseLong(uri.getLastPathSegment());
+// 
+// ... do something with event ID
+//
+//</pre>
+
+<p class="note"><strong>Note:</strong> See how this example captures the event
+ID after the event is created. This is the easiest way to get an event ID. You often
+need the event ID to perform other calendar operations&mdash;for example, to add
+attendees or reminders to an event.</p>
+
+
+<h3 id="update-event">Updating Events</h3>
+
+<p>When your application wants to allow the user to edit an event, we recommend
+that you use an {@link android.content.Intent#ACTION_EDIT EDIT} Intent, as
+described in <a href="#intent-edit">Using an intent to edit an  event</a>.
+However, if you need to, you can edit events directly. To perform an update of
+an Event, you can provide the <code>_ID</code> of the 
+event either as an appended ID to the Uri ({@link
+android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}) 
+or as the first selection item. 
+The selection should start with <code>&quot;_id=?&quot;</code>, and the first
+<code>selectionArg</code> should be  the <code>_ID</code> of the event. You can
+also do updates using a selection with no ID. Here is an example of updating an
+event. It changes the title of the event using the 
+{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}
+approach:</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 188;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri updateUri = null;
+// The new title for the event
+values.put(Events.TITLE, &quot;Kickboxing&quot;); 
+myUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);  </pre>
+
+<h3 id="delete-event">Deleting Events</h3>
+
+<p>You can delete an event either by its {@link
+android.provider.BaseColumns#_ID} as an appended  ID on the URI, or by using
+standard selection. If you use an appended ID, you can't also do a selection.
+There are two versions of delete: as an application and as a sync adapter. An
+application delete sets the <em>deleted</em> column to 1. This flag that tells
+the sync adapter that the row was deleted and that this deletion should be
+propagated to the server. A sync adapter delete removes the event from the
+database along with all its associated data. Here is an example of application
+deleting an event through its {@link android.provider.BaseColumns#_ID}:</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 201;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri deleteUri = null;
+deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().delete(deleteUri, null, null);
+Log.i(DEBUG_TAG, &quot;Rows deleted: &quot; + rows);  
+</pre>
+
+<h2 id="attendees">Attendees Table</h2>
+
+<p>Each row of the {@link android.provider.CalendarContract.Attendees} table
+represents a single attendee or guest of an event. Calling 
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} 
+returns a list of attendees for  the
+event with the given {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}. 
+This  {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} 
+must match the {@link
+android.provider.BaseColumns#_ID} of a particular event.</p> 
+
+<p>The following table lists the
+writable fields. When inserting a new attendee, you must include all of them 
+except <code>ATTENDEE_NAME</code>.
+</p>
+
+
+<table>
+  <tr>
+    <th>Constant</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td>
+    <td>The ID of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td>
+    <td>The name of the attendee.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td>
+    <td>The email address of the attendee.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td>
+    <td><p>The relationship of the attendee to the event. One of:</p>
+      <ul>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li>
+    </ul>
+    </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td>
+    <td><p>The type of attendee. One of: </p>
+      <ul>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li>
+    </ul></td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td>
+    <td><p>The attendance status of the attendee. One of:</p>
+      <ul>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li>
+        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li>
+    </ul></td>
+  </tr>
+</table>
+
+<h3 id="add-attendees">Adding Attendees</h3>
+
+<p>Here is an example that adds a single attendee to an event. Note that the
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} 
+is required:</p>
+
+<pre>
+long eventID = 202;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Attendees.ATTENDEE_NAME, &quot;Trevor&quot;);
+values.put(Attendees.ATTENDEE_EMAIL, &quot;trevor@example.com&quot;);
+values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
+values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
+values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
+values.put(Attendees.EVENT_ID, eventID);
+Uri uri = cr.insert(Attendees.CONTENT_URI, values);
+</pre>
+
+<h2 id="reminders">Reminders Table</h2>
+
+<p>Each row of the {@link android.provider.CalendarContract.Reminders} table
+represents a single reminder for an event. Calling 
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()}  returns a list of reminders for the
+event with the given 
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}.</p>
+
+
+<p>The following table lists the writable fields for reminders. All of them must
+be included when inserting a new reminder. Note that sync adapters specify the
+types of reminders they support in the {@link
+android.provider.CalendarContract.Calendars} table. See 
+{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS} 
+for details.</p>
+
+
+<table>
+  <tr>
+    <th>Constant</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td>
+    <td>The ID of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td>
+    <td>The minutes prior to the event that the reminder should fire.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td>
+    <td><p>The alarm method, as set on the server. One of:</p>
+      <ul>
+        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li>
+        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li>
+        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li>
+        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li>
+    </ul></td>
+  </tr>
+</table>
+
+<h3 id="add-reminders">Adding Reminders</h3>
+
+<p>This example adds a reminder to an event. The reminder fires 15
+minutes before the event.</p>
+<pre>
+long eventID = 221;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Reminders.MINUTES, 15);
+values.put(Reminders.EVENT_ID, eventID);
+values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
+Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre>
+
+<h2 id="instances">Instances Table</h2>
+
+<p>The 
+{@link android.provider.CalendarContract.Instances} table holds the
+start and end time for occurrences of an event. Each row in this table
+represents a single event occurrence. The instances table is not writable and only
+provides a  way to query event occurrences. </p>
+
+<p>The following table lists some of the fields you can query on for an instance. Note 
+that time zone is defined by 
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE} 
+and 
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES}.</p>
+
+
+<table>
+  <tr>
+    <th>Constant</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td>
+    <td>The beginning time of the instance, in UTC milliseconds.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#END}</td>
+    <td>The ending time of the instance, in UTC milliseconds.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td>
+    
+    <td>The Julian end day of the instance, relative to the Calendar's time
+zone. 
+    
+</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td>
+    
+    <td>The end minute of the instance measured from midnight in the the
+Calendar's time zone.</td>
+    
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td>
+    <td>The <code>_ID</code> of the event for this instance.</td>
+  </tr>
+    <tr>
+    <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td>
+    <td>The Julian start day of the instance, relative to the Calendar's time zone. 
+ </td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td>
+    
+    <td>The start minute of the instance measured from midnight, relative to the
+Calendar's time zone. 
+</td>
+    
+  </tr>
+
+</table>
+
+<h3 id="query-instances">Querying the Instances table</h3>
+
+<p>To query the Instances table, you need to specify a range time for the query
+in the URI. In this example, {@link android.provider.CalendarContract.Instances}
+gets access to the {@link
+android.provider.CalendarContract.EventsColumns#TITLE} field through its
+implementation of the {@link android.provider.CalendarContract.EventsColumns} interface. 
+In other words, {@link
+android.provider.CalendarContract.EventsColumns#TITLE} is returned through a
+database view, not through querying the raw {@link
+android.provider.CalendarContract.Instances} table.</p>
+
+<pre>
+private static final String DEBUG_TAG = "MyActivity";
+public static final String[] INSTANCE_PROJECTION = new String[] {
+    Instances.EVENT_ID,      // 0
+    Instances.BEGIN,         // 1
+    Instances.TITLE          // 2
+  };
+  
+// The indices for the projection array above.
+private static final int PROJECTION_ID_INDEX = 0;
+private static final int PROJECTION_BEGIN_INDEX = 1;
+private static final int PROJECTION_TITLE_INDEX = 2;
+...
+
+// Specify the date range you want to search for recurring
+// event instances
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2011, 9, 23, 8, 0);
+long startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2011, 10, 24, 8, 0);
+long endMillis = endTime.getTimeInMillis();
+  
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+
+// The ID of the recurring event whose instances you are searching
+// for in the Instances table
+String selection = Instances.EVENT_ID + " = ?";
+String[] selectionArgs = new String[] {"207"};
+
+// Construct the query with the desired date range.
+Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
+ContentUris.appendId(builder, startMillis);
+ContentUris.appendId(builder, endMillis);
+
+// Submit the query
+cur =  cr.query(builder.build(), 
+    INSTANCE_PROJECTION, 
+    selection, 
+    selectionArgs, 
+    null);
+   
+while (cur.moveToNext()) {
+    String title = null;
+    long eventID = 0;
+    long beginVal = 0;    
+    
+    // Get the field values
+    eventID = cur.getLong(PROJECTION_ID_INDEX);
+    beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
+    title = cur.getString(PROJECTION_TITLE_INDEX);
+              
+    // Do something with the values. 
+    Log.i(DEBUG_TAG, "Event:  " + title); 
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTimeInMillis(beginVal);  
+    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
+    Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));    
+    }
+ }</pre>
+
+<h2 id="intents">Calendar Intents</h2>
+<p>Your application doesn't need <a href="#manifest">permissions</a> to read and write calendar data. It can instead use intents supported by Android's Calendar application to hand off read and write operations to that application. The following table lists the intents supported by the Calendar Provider:</p>
+<table>
+  <tr>
+    <th>Action</th>
+    <th>URI</th>
+
+    <th>Description</th>
+    <th>Extras</th>
+  </tr>
+  <tr>
+    <td><br>
+    {@link android.content.Intent#ACTION_VIEW VIEW} <br></td>
+    <td><p><code>content://com.android.calendar/time/&lt;ms_since_epoch&gt;</code></p>
+    You can also refer to the URI with 
+{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI}. 
+For an example of using this intent, see <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Using intents to view calendar data</a>. 
+
+    </td>
+    <td>Open calendar to the time specified by <code>&lt;ms_since_epoch&gt;</code>.</td>
+    <td>None.</td>
+  </tr>
+  <tr>
+    <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p>
+
+     </td>
+    <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+    
+    You can also refer to the URI with 
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 
+For an example of using this intent, see <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Using intents to view calendar data</a>.
+    
+    </td>
+    <td>View the event specified by <code>&lt;event_id&gt;</code>.</td>
+
+    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+      <br>
+      <br>
+    {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+  </tr>
+
+  <tr>
+    <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td>
+    <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+    
+  You can also refer to the URI with 
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 
+For an example of using this intent, see <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">Using an intent to edit an event</a>.
+    
+    
+    </td>
+    <td>Edit the event specified by <code>&lt;event_id&gt;</code>.</td>
+
+    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+      <br>
+      <br>
+    {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+  </tr>
+
+  <tr>
+    <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br>
+    <br>
+    {@link android.content.Intent#ACTION_INSERT INSERT} </td>
+    <td><p><code>content://com.android.calendar/events</code></p>
+    
+   You can also refer to the URI with 
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}. 
+For an example of using this intent, see <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">Using an intent to insert an event</a>.
+    
+    </td>
+
+    <td>Create an event.</td>
+    <td>Any of the extras listed in the table below.</td>
+  </tr>
+</table>
+
+<p>The following table lists the intent extras supported by the Calendar Provider:
+</p>
+<table>
+  <tr>
+    <th>Intent Extra</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td>
+    <td>Name for the event.</td>
+  </tr>
+  <tr>
+  
+    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME}</td>
+    <td>Event begin time in milliseconds from the epoch.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME}</td>
+    
+    <td>Event end time in milliseconds from the epoch.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY
+CalendarContract.EXTRA_EVENT_ALL_DAY}</td>
+    
+    <td>A boolean that indicates that an event is all day. Value can be
+<code>true</code> or <code>false</code>.</td> </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION
+Events.EVENT_LOCATION}</td>
+    
+    <td>Location of the event.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION
+Events.DESCRIPTION}</td>
+    
+    <td>Event description.</td>
+  </tr>
+  <tr>
+    <td>
+    {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td>
+    <td>Email addresses of those to invite as a comma-separated list.</td>
+  </tr>
+  <tr>
+    <td>
+    {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td>
+    <td>The recurrence rule for the event.</td>
+  </tr>
+  <tr>
+    <td>
+    {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL
+Events.ACCESS_LEVEL}</td>
+    
+    <td>Whether the event is private or public.</td>
+  </tr>
+  <tr>
+    <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY
+Events.AVAILABILITY}</td>
+    
+    <td>If this event counts as busy time or is free time that can be scheduled over.</td>
+    
+</table> 
+<p>The following sections describe how to use these intents.</p>
+
+
+<h3 id="intent-insert">Using an intent to insert an event</h3>
+
+<p>Using the {@link android.content.Intent#ACTION_INSERT INSERT} Intent
+lets your application hand off the event insertion task to the Calendar itself.
+With this approach, your application doesn't even need to have the {@link
+android.Manifest.permission#WRITE_CALENDAR} permission included in its <a
+href="#manifest">manifest file</a>.</p>
+
+  
+<p>When users run an application that uses this approach, the application sends
+them to the Calendar to finish adding the event. The {@link
+android.content.Intent#ACTION_INSERT INSERT} Intent uses extra fields to
+pre-populate a form with the details of the event in the Calendar. Users can
+then cancel the event, edit the form as needed, or save the event to their
+calendars.</p>
+  
+
+
+<p>Here is a code snippet that schedules an event on January 19, 2012, that runs
+from 7:30 a.m. to 8:30 a.m. Note the following about this code snippet:</p>
+
+<ul>
+  <li>It specifies {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI} 
+  as the Uri.</li>
+  
+  <li>It uses the {@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME} and {@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME} extra fields to pre-populate the form
+with the time of the event. The values  for these times must be in UTC milliseconds
+from the epoch.</li>
+  
+  <li>It uses the {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}
+extra field to provide a comma-separated list of invitees, specified by email address.</li>
+  
+</ul>
+<pre>
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 0, 19, 8, 30);
+Intent intent = new Intent(Intent.ACTION_INSERT)
+        .setData(Events.CONTENT_URI)
+        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
+        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
+        .putExtra(Events.TITLE, &quot;Yoga&quot;)
+        .putExtra(Events.DESCRIPTION, &quot;Group class&quot;)
+        .putExtra(Events.EVENT_LOCATION, &quot;The gym&quot;)
+        .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
+        .putExtra(Intent.EXTRA_EMAIL, &quot;rowan@example.com,trevor@example.com&quot;);
+startActivity(intent);
+</pre>
+
+<h3 id="intent-edit">Using an intent to edit an event</h3>
+
+<p>You can update an event directly, as described in <a
+href="#update-event">Updating events</a>. But using the {@link
+android.content.Intent#ACTION_EDIT EDIT} Intent allows an application that
+doesn't have permission to hand off event editing to the Calendar application.
+When users finish editing their event in Calendar, they're returned to the
+original application.</p> <p>Here is an example of an intent that sets a new
+title for a specified event and lets users edit the event in the Calendar.</p>
+
+
+<pre>long eventID = 208;
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_EDIT)
+    .setData(uri)
+    .putExtra(Events.TITLE, &quot;My New Title&quot;);
+startActivity(intent);</pre>
+
+<h3 id="intent-view">Using  intents to view calendar data</h3>
+<p>Calender Provider offers two different ways to use the {@link android.content.Intent#ACTION_VIEW VIEW} Intent:</p>
+<ul>
+  <li>To open the Calendar to a particular date.</li>
+  <li>To view an event.</li>
+
+</ul>
+<p>Here is an example that shows how to open the Calendar to a particular date:</p>
+<pre>// A date-time specified in milliseconds since the epoch.
+long startMillis;
+...
+Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+builder.appendPath(&quot;time&quot;);
+ContentUris.appendId(builder, startMillis);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+    .setData(builder.build());
+startActivity(intent);</pre>
+
+<p>Here is an example that shows how to open an event for viewing:</p>
+<pre>long eventID = 208;
+...
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+   .setData(uri);
+startActivity(intent);
+</pre>
+
+
+<h2 id="sync-adapter">Sync Adapters</h2>
+
+
+<p>There are only minor differences in how an application and a sync adapter
+access the Calendar Provider:</p>
+
+<ul>
+  <li>A sync adapter needs to specify that it's a sync adapter by setting {@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER} to <code>true</code>.</li>
+  
+  
+  <li>A sync adapter needs to provide an {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME} and an {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} as query parameters in the URI. </li>
+  
+  <li>A sync adapter has write access to more columns than an application or widget.
+  For example, an application can only modify a few characteristics of a calendar, 
+  such as its name, display name, visibility setting, and whether the calendar is
+  synced. By comparison, a sync adapter can access not only those columns, but many others,
+  such as calendar color, time zone, access level, location, and so on.
+However, a sync adapter is restricted to the <code>ACCOUNT_NAME</code> and 
+<code>ACCOUNT_TYPE</code> it specified.</li> </ul>
+
+<p>Here is a helper method you can use to return a URI for use with a sync adapter:</p>
+<pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) {
+    return uri.buildUpon()
+        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,&quot;true&quot;)
+        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+ }
+</pre>
+<p>For a sample implementation of a sync adapter (not specifically related to Calendar), see 
+<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>.
+</body>
+</html>
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 513886a..95331ce 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -19,6 +19,11 @@
 <li>{@link android.content.ContentResolver}</li>
 <li>{@link android.database.Cursor}</li>
 </ol>
+
+<h2>See also</h2>
+<ol>
+  <li><a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a></li>
+</ol>
 </div>
 </div>
 
@@ -36,6 +41,10 @@
 for some, you must acquire the proper permission to read the data).
 </p>   
 
+<p class="note"><strong>Note:</strong> Android 4.0 introduces the Calendar
+Provider. For more information, see <a
+href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar
+Provider</a>.</p>
 <p>
 If you want to make your own data public, you have two options:  You can 
 create your own content provider (a {@link android.content.ContentProvider} 
diff --git a/docs/html/guide/topics/resources/drawable-resource.jd b/docs/html/guide/topics/resources/drawable-resource.jd
index ed9f990..5218c7e 100644
--- a/docs/html/guide/topics/resources/drawable-resource.jd
+++ b/docs/html/guide/topics/resources/drawable-resource.jd
@@ -646,6 +646,7 @@
         android:state_checkable=["true" | "false"]
         android:state_checked=["true" | "false"]
         android:state_enabled=["true" | "false"]
+        android:state_activated=["true" | "false"]
         android:state_window_focused=["true" | "false"] />
 &lt;/selector>
 </pre>
@@ -690,8 +691,8 @@
           <dd><em>Boolean</em>. "true" if this item should be used when the object is pressed (such as when a button
 is touched/clicked); "false" if this item should be used in the default, non-pressed state.</dd>
         <dt><code>android:state_focused</code></dt>
-          <dd><em>Boolean</em>. "true" if this item should be used when the object is focused (such as when a button
-is highlighted using the trackball/d-pad); "false" if this item should be used in the default,
+          <dd><em>Boolean</em>. "true" if this item should be used when the object has input focus
+(such as when the user selects a text input); "false" if this item should be used in the default,
 non-focused state.</dd>
         <dt><code>android:state_hovered</code></dt>
           <dd><em>Boolean</em>. "true" if this item should be used when the object is being hovered
@@ -699,8 +700,11 @@
 drawable may be the same drawable used for the "focused" state.
           <p>Introduced in API level 14.</p></dd>
         <dt><code>android:state_selected</code></dt>
-          <dd><em>Boolean</em>. "true" if this item should be used when the object is selected (such as when a
-tab is opened); "false" if this item should be used when the object is not selected.</dd>
+          <dd><em>Boolean</em>. "true" if this item should be used when the object is the current
+user selection when navigating with a directional control (such as when navigating through a list
+with a d-pad); "false" if this item should be used when the object is not selected.
+<p>The selected state is used when focus (<code>android:state_focused</code>) is not sufficient
+(such as when list view has focus and an item within it is selected with a d-pad).</p></dd>
         <dt><code>android:state_checkable</code></dt>
           <dd><em>Boolean</em>. "true" if this item should be used when the object is checkable; "false" if this
 item should be used when the object is not checkable. (Only useful if the object can
@@ -709,8 +713,14 @@
           <dd><em>Boolean</em>. "true" if this item should be used when the object is checked; "false" if it
 should be used when the object is un-checked.</dd>
         <dt><code>android:state_enabled</code></dt>
-          <dd><em>Boolean</em>. "true" if this item should be used when the object is enabled (capable of
-receiving touch/click events); "false" if it should be used when the object is disabled.</dd>
+          <dd><em>Boolean</em>. "true" if this item should be used when the object is enabled
+(capable of receiving touch/click events); "false" if it should be used when the object is
+disabled.</dd>
+        <dt><code>android:state_activated</code></dt>
+          <dd><em>Boolean</em>. "true" if this item should be used when the object is activated as
+the persistent selection (such as to "highlight" the previously selected list item in a persistent
+navigation view); "false" if it should be used when the object is not activated.
+<p>Introduced in API level 11.</p></dd>
         <dt><code>android:state_window_focused</code></dt>
           <dd><em>Boolean</em>. "true" if this item should be used when the application window has focus (the
 application is in the foreground), "false" if this item should be used when the application
diff --git a/docs/html/images/admin/device-admin-activate-prompt.png b/docs/html/images/admin/device-admin-activate-prompt.png
index 2851194..3786788 100644
--- a/docs/html/images/admin/device-admin-activate-prompt.png
+++ b/docs/html/images/admin/device-admin-activate-prompt.png
Binary files differ
diff --git a/docs/html/images/admin/device-admin-app.png b/docs/html/images/admin/device-admin-app.png
index c96defc..6b23aba 100644
--- a/docs/html/images/admin/device-admin-app.png
+++ b/docs/html/images/admin/device-admin-app.png
Binary files differ
diff --git a/docs/html/images/providers/datamodel.graffle b/docs/html/images/providers/datamodel.graffle
new file mode 100644
index 0000000..f8d730f
--- /dev/null
+++ b/docs/html/images/providers/datamodel.graffle
@@ -0,0 +1,2029 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>ApplicationVersion</key>
+	<array>
+		<string>com.omnigroup.OmniGrafflePro</string>
+		<string>138.9.0.117994</string>
+	</array>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>BackgroundGraphic</key>
+	<dict>
+		<key>Bounds</key>
+		<string>{{0, 0}, {576, 733}}</string>
+		<key>Class</key>
+		<string>SolidGraphic</string>
+		<key>ID</key>
+		<integer>2</integer>
+		<key>Style</key>
+		<dict>
+			<key>shadow</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+			<key>stroke</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+		</dict>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2011-10-12 11:34:15 -0700</string>
+	<key>Creator</key>
+	<string>Katie McCormick</string>
+	<key>DisplayScale</key>
+	<string>1 0/72 in = 1.0000 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>6</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{249.63, 336.648}, {140.426, 27.9745}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>29</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>169</integer>
+				<key>Position</key>
+				<real>0.33598536252975464</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>Width</key>
+					<real>0.0</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 \
+Reminders.EVENT_ID\
+}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{248.834, 121}, {145.338, 27.9745}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>15</integer>
+				<key>Position</key>
+				<real>0.49666976928710938</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>Width</key>
+					<real>0.0</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 \
+Events.CALENDAR_ID\
+}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>157</integer>
+				<key>Info</key>
+				<integer>5</integer>
+			</dict>
+			<key>ID</key>
+			<integer>170</integer>
+			<key>Points</key>
+			<array>
+				<string>{188.253, 404}</string>
+				<string>{321.503, 245.17}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>Cap</key>
+					<integer>0</integer>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>Join</key>
+					<integer>0</integer>
+					<key>TailArrow</key>
+					<string>CrowBall</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>165</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>157</integer>
+			</dict>
+			<key>ID</key>
+			<integer>169</integer>
+			<key>Points</key>
+			<array>
+				<string>{319.003, 404}</string>
+				<string>{321.503, 245.17}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>Cap</key>
+					<integer>0</integer>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>Join</key>
+					<integer>0</integer>
+					<key>TailArrow</key>
+					<string>CrowBall</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>166</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>157</integer>
+				<key>Info</key>
+				<integer>5</integer>
+			</dict>
+			<key>ID</key>
+			<integer>168</integer>
+			<key>Points</key>
+			<array>
+				<string>{450.042, 404}</string>
+				<string>{321.503, 245.17}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>Cap</key>
+					<integer>0</integer>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>Join</key>
+					<integer>0</integer>
+					<key>TailArrow</key>
+					<string>CrowBall</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>167</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>155</integer>
+			</dict>
+			<key>ID</key>
+			<integer>15</integer>
+			<key>Points</key>
+			<array>
+				<string>{321.503, 195}</string>
+				<string>{321.503, 74.1697}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>Cap</key>
+					<integer>0</integer>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>Join</key>
+					<integer>0</integer>
+					<key>TailArrow</key>
+					<string>CrowBall</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>157</integer>
+				<key>Info</key>
+				<integer>6</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{281.41, 24}, {80.1852, 50.1697}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica-Bold</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>155</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 1}</string>
+				<string>{1, -1}</string>
+				<string>{-1, -1}</string>
+				<string>{-1, 1}</string>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+				<string>{-0.5, -0.233518}</string>
+				<string>{-0.491442, 0.260063}</string>
+				<string>{0.507118, -0.224086}</string>
+				<string>{0.507118, 0.267179}</string>
+				<string>{-0.27431, -0.474028}</string>
+				<string>{0.27978, -0.478478}</string>
+				<string>{0.293938, 0.543044}</string>
+				<string>{-0.286232, 0.553804}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.938075</string>
+						<key>g</key>
+						<string>0.938269</string>
+						<key>r</key>
+						<string>0.938154</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0.727869</string>
+						<key>g</key>
+						<string>0.728019</string>
+						<key>r</key>
+						<string>0.72793</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>a</key>
+						<string>0.35</string>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>Fuzziness</key>
+					<real>2.3972222805023193</real>
+					<key>ShadowVector</key>
+					<string>{0, 1}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.472997</string>
+						<key>g</key>
+						<string>0.473094</string>
+						<key>r</key>
+						<string>0.473036</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>3</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Calendars}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{433, 404}, {80.1852, 50.1697}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>1</string>
+					<key>g</key>
+					<string>1</string>
+					<key>r</key>
+					<string>1</string>
+				</dict>
+				<key>Font</key>
+				<string>DroidSans-Bold</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>167</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 1}</string>
+				<string>{1, -1}</string>
+				<string>{-1, -1}</string>
+				<string>{-1, 1}</string>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+				<string>{-0.5, -0.233518}</string>
+				<string>{-0.491442, 0.260063}</string>
+				<string>{0.507118, -0.224086}</string>
+				<string>{0.507118, 0.267179}</string>
+				<string>{-0.27431, -0.474028}</string>
+				<string>{0.27978, -0.478478}</string>
+				<string>{0.293938, 0.543044}</string>
+				<string>{-0.286232, 0.553804}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.937525</string>
+						<key>g</key>
+						<string>0.489708</string>
+						<key>r</key>
+						<string>0.223421</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0.905866</string>
+						<key>g</key>
+						<string>0.149816</string>
+						<key>r</key>
+						<string>0.119797</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>a</key>
+						<string>0.35</string>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>Fuzziness</key>
+					<real>2.3972222805023193</real>
+					<key>ShadowVector</key>
+					<string>{1, 2}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.461178</string>
+						<key>g</key>
+						<string>0.0874307</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>3</real>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf1 Instances}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{278.91, 404}, {80.1852, 50.1697}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>1</string>
+					<key>g</key>
+					<string>1</string>
+					<key>r</key>
+					<string>1</string>
+				</dict>
+				<key>Font</key>
+				<string>DroidSans-Bold</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>166</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 1}</string>
+				<string>{1, -1}</string>
+				<string>{-1, -1}</string>
+				<string>{-1, 1}</string>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+				<string>{-0.5, -0.233518}</string>
+				<string>{-0.491442, 0.260063}</string>
+				<string>{0.507118, -0.224086}</string>
+				<string>{0.507118, 0.267179}</string>
+				<string>{-0.27431, -0.474028}</string>
+				<string>{0.27978, -0.478478}</string>
+				<string>{0.293938, 0.543044}</string>
+				<string>{-0.286232, 0.553804}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.937525</string>
+						<key>g</key>
+						<string>0.489708</string>
+						<key>r</key>
+						<string>0.223421</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0.905866</string>
+						<key>g</key>
+						<string>0.149816</string>
+						<key>r</key>
+						<string>0.119797</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>a</key>
+						<string>0.35</string>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>Fuzziness</key>
+					<real>2.3972222805023193</real>
+					<key>ShadowVector</key>
+					<string>{1, 2}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.461178</string>
+						<key>g</key>
+						<string>0.0874307</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>3</real>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf1 Reminders}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{281.41, 195}, {80.1852, 50.1697}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>DroidSans-Bold</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>157</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 1}</string>
+				<string>{1, -1}</string>
+				<string>{-1, -1}</string>
+				<string>{-1, 1}</string>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+				<string>{-0.5, -0.233518}</string>
+				<string>{-0.491442, 0.260063}</string>
+				<string>{0.507118, -0.224086}</string>
+				<string>{0.507118, 0.267179}</string>
+				<string>{-0.27431, -0.474028}</string>
+				<string>{0.27978, -0.478478}</string>
+				<string>{0.293938, 0.543044}</string>
+				<string>{-0.286232, 0.553804}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.874135</string>
+						<key>r</key>
+						<string>0.71718</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.662438</string>
+						<key>r</key>
+						<string>0.464468</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>a</key>
+						<string>0.35</string>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>Fuzziness</key>
+					<real>2.3972222805023193</real>
+					<key>ShadowVector</key>
+					<string>{0, 1}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.93512</string>
+						<key>g</key>
+						<string>0.472602</string>
+						<key>r</key>
+						<string>0.333854</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>3</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 Events}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{124.821, 404}, {80.1852, 50.1697}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>1</string>
+					<key>g</key>
+					<string>1</string>
+					<key>r</key>
+					<string>1</string>
+				</dict>
+				<key>Font</key>
+				<string>DroidSans-Bold</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>165</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 1}</string>
+				<string>{1, -1}</string>
+				<string>{-1, -1}</string>
+				<string>{-1, 1}</string>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+				<string>{-0.5, -0.233518}</string>
+				<string>{-0.491442, 0.260063}</string>
+				<string>{0.507118, -0.224086}</string>
+				<string>{0.507118, 0.267179}</string>
+				<string>{-0.27431, -0.474028}</string>
+				<string>{0.27978, -0.478478}</string>
+				<string>{0.293938, 0.543044}</string>
+				<string>{-0.286232, 0.553804}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.937525</string>
+						<key>g</key>
+						<string>0.489708</string>
+						<key>r</key>
+						<string>0.223421</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientAngle</key>
+					<real>90</real>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0.905866</string>
+						<key>g</key>
+						<string>0.149816</string>
+						<key>r</key>
+						<string>0.119797</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>a</key>
+						<string>0.35</string>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>Fuzziness</key>
+					<real>2.3972222805023193</real>
+					<key>ShadowVector</key>
+					<string>{1, 2}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.461178</string>
+						<key>g</key>
+						<string>0.0874307</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>3</real>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf1 Attendees}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{383, 317.03}, {150.288, 18.4565}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>22</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Pad</key>
+				<integer>0</integer>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Instances.EVENT_ID}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+			<key>Wrap</key>
+			<string>NO</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{107, 317.03}, {154.243, 18.4565}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>20</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Pad</key>
+				<integer>0</integer>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Attendees.EVENT_ID}</string>
+				<key>VerticalPad</key>
+				<integer>0</integer>
+			</dict>
+			<key>Wrap</key>
+			<string>NO</string>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict>
+		<key>ShowsGrid</key>
+		<string>YES</string>
+	</dict>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict>
+		<key>Animate</key>
+		<string>NO</string>
+		<key>circoMinDist</key>
+		<real>18</real>
+		<key>circoSeparation</key>
+		<real>0.0</real>
+		<key>layoutEngine</key>
+		<string>dot</string>
+		<key>neatoSeparation</key>
+		<real>0.0</real>
+		<key>twopiSeparation</key>
+		<real>0.0</real>
+	</dict>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheets</key>
+	<array/>
+	<key>ModificationDate</key>
+	<string>2011-10-20 15:09:11 -0700</string>
+	<key>Modifier</key>
+	<string>Katie McCormick</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>41</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+	</dict>
+	<key>PrintOnePage</key>
+	<false/>
+	<key>QuickLookPreview</key>
+	<data>
+	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
+	IC9QYWdlIC9QYXJlbnQgNCAwIFIgL1Jlc291cmNlcyA3IDAgUiAvQ29udGVudHMgNSAw
+	IFIgL01lZGlhQm94IFswIDAgNTc2IDczM10KPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1By
+	b2NTZXQgWyAvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJIF0gL0NvbG9y
+	U3BhY2UgPDwgL0NzMSA4IDAgUgovQ3MyIDEzIDAgUiA+PiAvRm9udCA8PCAvRjEuMCAx
+	NCAwIFIgL0YyLjAgMTYgMCBSID4+IC9YT2JqZWN0IDw8IC9JbTEgOSAwIFIKL0ltMiAx
+	MSAwIFIgPj4gL1NoYWRpbmcgPDwgL1NoMiAxNyAwIFIgL1NoMSAxNSAwIFIgL1NoMyAx
+	OCAwIFIgL1NoNCAxOSAwIFIKL1NoNSAyMCAwIFIgPj4gPj4KZW5kb2JqCjE3IDAgb2Jq
+	Cjw8IC9Db2xvclNwYWNlIDIxIDAgUiAvU2hhZGluZ1R5cGUgMiAvQ29vcmRzIFsgNDAu
+	NTkyNiAtMjUuNTg0ODUgNDAuNTkyNTkKMjUuNTg0ODcgXSAvRG9tYWluIFsgMCAxIF0g
+	L0V4dGVuZCBbIGZhbHNlIGZhbHNlIF0gL0Z1bmN0aW9uIDIyIDAgUiA+PgplbmRvYmoK
+	MTUgMCBvYmoKPDwgL0NvbG9yU3BhY2UgMjEgMCBSIC9TaGFkaW5nVHlwZSAyIC9Db29y
+	ZHMgWyA0MC41OTI2IC0yNS41ODQ4NSA0MC41OTI1OQoyNS41ODQ4NyBdIC9Eb21haW4g
+	WyAwIDEgXSAvRXh0ZW5kIFsgZmFsc2UgZmFsc2UgXSAvRnVuY3Rpb24gMjMgMCBSID4+
+	CmVuZG9iagoxOCAwIG9iago8PCAvQ29sb3JTcGFjZSAyMSAwIFIgL1NoYWRpbmdUeXBl
+	IDIgL0Nvb3JkcyBbIDQwLjU5MjYgLTI1LjU4NDg1IDQwLjU5MjU5CjI1LjU4NDg3IF0g
+	L0RvbWFpbiBbIDAgMSBdIC9FeHRlbmQgWyBmYWxzZSBmYWxzZSBdIC9GdW5jdGlvbiAy
+	NCAwIFIgPj4KZW5kb2JqCjE5IDAgb2JqCjw8IC9Db2xvclNwYWNlIDIxIDAgUiAvU2hh
+	ZGluZ1R5cGUgMiAvQ29vcmRzIFsgNDAuNTkyNiAtMjUuNTg0ODUgNDAuNTkyNTkKMjUu
+	NTg0ODcgXSAvRG9tYWluIFsgMCAxIF0gL0V4dGVuZCBbIGZhbHNlIGZhbHNlIF0gL0Z1
+	bmN0aW9uIDI1IDAgUiA+PgplbmRvYmoKMjAgMCBvYmoKPDwgL0NvbG9yU3BhY2UgMjEg
+	MCBSIC9TaGFkaW5nVHlwZSAyIC9Db29yZHMgWyA0MC41OTI2IC0yNS41ODQ4NSA0MC41
+	OTI1OQoyNS41ODQ4NyBdIC9Eb21haW4gWyAwIDEgXSAvRXh0ZW5kIFsgZmFsc2UgZmFs
+	c2UgXSAvRnVuY3Rpb24gMjYgMCBSID4+CmVuZG9iago5IDAgb2JqCjw8IC9MZW5ndGgg
+	MTAgMCBSIC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMTc0IC9I
+	ZWlnaHQgMTE0IC9JbnRlcnBvbGF0ZQp0cnVlIC9Db2xvclNwYWNlIDI3IDAgUiAvSW50
+	ZW50IC9QZXJjZXB0dWFsIC9TTWFzayAyOCAwIFIgL0JpdHNQZXJDb21wb25lbnQKOCAv
+	RmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0AENAAAAwqD3T20ON4hAYcCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	DBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCA
+	AQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgw
+	YMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMG
+	PgYG6HQAAQplbmRzdHJlYW0KZW5kb2JqCjEwIDAgb2JqCjI4MwplbmRvYmoKMTEgMCBv
+	YmoKPDwgL0xlbmd0aCAxMiAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdl
+	IC9XaWR0aCAxODIgL0hlaWdodCAxMjIgL0ludGVycG9sYXRlCnRydWUgL0NvbG9yU3Bh
+	Y2UgMjcgMCBSIC9JbnRlbnQgL1BlcmNlcHR1YWwgL1NNYXNrIDMwIDAgUiAvQml0c1Bl
+	ckNvbXBvbmVudAo4IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ae3QMQEA
+	AADCoPVPbQZ/iEBhwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM
+	GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB
+	AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg
+	wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg4BsYBEMA
+	AQplbmRzdHJlYW0KZW5kb2JqCjEyIDAgb2JqCjMxNAplbmRvYmoKMzAgMCBvYmoKPDwg
+	L0xlbmd0aCAzMSAwIFIgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0ltYWdlIC9XaWR0
+	aCAxODIgL0hlaWdodCAxMjIgL0NvbG9yU3BhY2UKL0RldmljZUdyYXkgL0ludGVycG9s
+	YXRlIHRydWUgL0JpdHNQZXJDb21wb25lbnQgOCAvRmlsdGVyIC9GbGF0ZURlY29kZSA+
+	PgpzdHJlYW0KeAHt3E1vomAQB3ABBcQXKjTtYqH2UGxtlaauTeoLTU1gtW6tmEq13/+L
+	LLibFNHZyzrZx2TmZOYwjj/R2/wzGSoSIAES2JcAx/MCi8XzHPQROV7IiZKcZ69kScwK
+	uxfnhJxcKKkVjb2qqKWCnBN2ePOCWFD106ppnbNWllk91dWCuL02J0hFvXph3zQd546t
+	cpxmw64ZelFKr80JYvHYqjsP3YH7xFq5g27HqVvHxbQ2nyvo1nW7P/RH4xfWajzyh732
+	taUpOX7jr0SQVaPedv2fb7NgzloFs7eJN2jXDVUSkltz2YJ+4fT91/kiDD9YqzBczF+9
+	nlPTlWzyf4QXS6f2w3AyD5fL1Wr1yVJF+yyX4Xwy7NgnJXFja0mt3nT9t0W8M2Nbf37G
+	ey+mfrdRVaXkgy3IFbM5GM1C5qTjbz3eOpyN+rdnR/LG1vmK5bjjIGQP+s/aYTB2W1ZF
+	Tv4chbx27jy9zKOtWXqkv3ZZhcHLk2Np+fTWdwe79cfXp2Ps1ccctmZ86/PdTwhtvd9H
+	bP2EkPV+UYFpZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILTJGgEVGEnWAAxCm6wRUIGR
+	ZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILTJGgEV
+	GEnWAAxCm6wRUIGRZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILTJGgEVGEnWAAxCm6wR
+	UIGRZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILTJGgEVGEnWAAxCm6wRUIGRZA3AILQP
+	2Bq8JUVg2sdI8AL2993uPt4CYQaw9UHcSJupG+lDuUffuKLno9v/Rtefrm//Eb7gfxsZ
+	X9G/T71uI4qHSF7Rr3MWOmznLDx3LlM5C1xW0WtOz1tnWjCWahFG9R5nWrTSmRYZQVIN
+	uz3wJtNZwFqASBDMplF+yL1tlDfzQzJ8TtGsq3bv2fvBXFjLePTDe+7dX5lbWS3rXBzT
+	bnUe+y5rwTiu23/83rJNfSsXJxNnEGlG7bJx22w5bFWreXt9WfumbS+didYWlbJ+YpyZ
+	FmtlnhknWllJJxCtI3KibC1JKZWPKlExFK8Vr3NULirSzmytSJsXslGOGXtBZvJfcsxi
+	cI7N0LgoMi6Z4pNMT6LXJEAC/1fgF8y5cjkKZW5kc3RyZWFtCmVuZG9iagozMSAwIG9i
+	ago4ODQKZW5kb2JqCjI4IDAgb2JqCjw8IC9MZW5ndGggMjkgMCBSIC9UeXBlIC9YT2Jq
+	ZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMTc0IC9IZWlnaHQgMTE0IC9Db2xvclNw
+	YWNlCi9EZXZpY2VHcmF5IC9JbnRlcnBvbGF0ZSB0cnVlIC9CaXRzUGVyQ29tcG9uZW50
+	IDggL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB7dzbTupQEAbgrh4obYAe
+	EuuuUpINJh5Ka4KJNUGqRmNLorYEi/D+L7IXVHR03w7JIpm5mqvJz5cpd2skiWrnAkyW
+	FRFLltnv386Yojb0piFeNfWGqrAfgZms6mbbchxXtHJsq2XqKvRlima0Xe+oG/REq6Dr
+	e27b0L7jMlkz7cPeyfkwji/Fqjganp/0Dm1Tk7fLy1TD9gfh1c14kopWk/HNVdj3bUPd
+	rq6itw8HcXL3lOVT0SrPntIk6nttXalxmWq6vTB5yF+LciZalcVr/pCEgWt+4rJGyzu5
+	usuLeVUtRKuqmhd5Ohp4La1eBVm3js5vnl7ni4/lcrkSqXiej8X85TE58zt6/Z3JTbs7
+	HGdFxcOKFHWThcd9L57H4bH9mVYxnCCa5GUlYNjVarmsynwSdZ1m/ZkphtuL0+msEk92
+	zcvTTidx4BrfaS/FTpv+n3Yh3NLWgRaz6b6l7f3eBKFtKe1ONn+zt2RLtivahJ0swWYo
+	2ZJtLUCbQJtAm7C7HSBbsoUC9H8LNXB7ssX1hNPIFmrg9mSL6wmnkS3UwO3JFtcTTiNb
+	qIHbky2uJ5xGtlADtydbXE84jWyhBm5PtriecBrZQg3cnmxxPeE0soUauD3Z4nrCaWQL
+	NXB7ssX1hNPIFmrg9mSL6wmnkS3UwO3JFtcTTiNbqIHbky2uJ5xGtlADtydbXE84jWyh
+	Bm5PtriecBrZQg3cnmxxPeG0je0ev93bp3eR+/TmdL/e88p6xz8T/K30qd9p1G+lmdby
+	BqM0f5u/V4K9ROd53udvGX+HfrB9h75+4x+EyX32UpSiPfIvy+Ilu7++CJyvAwr8foLX
+	j67Tx2fhDijk2fNjer2+n/C5CJLEb1NYfj8cJeNb0Y5TTG7Hyeji7x/ri1aS+N0PywsG
+	p+EwisWqaBieDgLP4mdKtnc/JH6mhN9UOfCPu4Fo1T32D5wfN1X4Lshqw2x1bIeXQBdr
+	1nGsTsto/LhXw5F5Xk3EY0D8FJD2O+t6J5iYh5b4maXt7ZevzaWGBP4BbIC/7gplbmRz
+	dHJlYW0KZW5kb2JqCjI5IDAgb2JqCjc3NwplbmRvYmoKMzIgMCBvYmoKPDwgL0xlbmd0
+	aCAzMyAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0ZpbHRlciAvRmxhdGVE
+	ZWNvZGUgPj4Kc3RyZWFtCngBhVTPaxNBFP42bqnQIghaaw6yeJAiSVmraEXUNv0RYmsM
+	2x+2RZBkM0nWbjbr7ia1pYjk4tEq3kXtoQf/gB568GQvSoVaRSjeqyhioRct8c1uTLal
+	6sDOfvPeN+99b3bfAA1y0jT1gATkDcdSohFpbHxCavyIAI6iCUE0JVXb7E4kBkGDc/l7
+	59h6D4FbVsN7+3eyd62a0raaB4T9QOBHmtkqsO8XcQpZEgKIPN+hKcd0CN/j2PLsjzlO
+	eXjBtQ8rPcRZInxANS3Of024U80l00CDSDiU9XFSPpzXi5TXHQdpbmbGyBC9T5Cmu8zu
+	q2KhnE72DpC9nfR+TrPePsIhwgsZrT9GuI2e9YzVP+Jh4aTmxIY9HBg19PhgFbcaqfg1
+	whRfEE0nolRx2S4N8Ziu/VbySoJwkDjKZGGAc1pIT9dMbvi6hwV9JtcTr+J3VlHheY8T
+	Z97U3e9F2gKvMA4dDBoMmg1IUBBFBGGYsFBAhjwaMTSycj8jqwYbk3sydSRqu3RiRLFB
+	ezbcPbdRpN08/igicZRDtQiS/EH+Kq/JT+V5+ctcsNhW95Stm5q68uA7xeWZuRoe19PI
+	43NNXnyV1HaTV0eWrHl6vJrsGj/sV5cx5oI1j8RzsPvxLV+VzJcpjBTF41Xz6kuEdVox
+	N9+fbH87PeIuzy611nOtiYs3VpuXZ/1qSPvuqryT5lX5T1718fxnzcRj4ikxJnaK5yGJ
+	l8Uu8ZLYS6sL4mBtxwidlYYp0m2R+iTVYGCavPUvXT9beL1Gfwz1UZQZzNJUifd/wipk
+	NJ25Dm/6j9vH/Bfk94rnnygCL2zgyJm6bVNx7xChZaVuc64CF7/RffC2bmujfjj8BFg8
+	qxatUjWfILwBHHaHeh7oKZjTlpbNOVKHLJ+TuunKYlLMUNtDUlLXJddlSxazmVVi6XbY
+	mdMdbhyhOUL3xKdKZZP6r/ERsP2wUvn5rFLZfk4a1oGX+m/AvP1FCmVuZHN0cmVhbQpl
+	bmRvYmoKMzMgMCBvYmoKNzM3CmVuZG9iagoyMSAwIG9iagpbIC9JQ0NCYXNlZCAzMiAw
+	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
+	MbIHs0dlT+Ceyj2TktSS2pKRkvWSM3uZ95ruTd7bsvejlKCUo1Se1H2pbWkFaX/paukX
+	MgwyxjLJMu0yn2XFZUmypbJP5AhyBnJJcq1yq/IS8p7y5fJPFYgKBxSOKfQo/FRUUgxV
+	vKK4qCSo5KpUpjSpzKhsoZyt/EAFo6KjkqTSobKhqqgartqs+klNUs1P7ZLawj6RfZ77
+	qvfNqfOru6mfV5/W4NVw1TinMa3Jp+mmWak5qyWg5aFVo/VOW0zbV/uy9kcdaZ1QnRs6
+	a7qqugm63XooPUO9TL0hfQZ9W/0S/SkDfgNvg3qDFUMFwzjD7v2Y/Sb78/ZPGnEZkYzq
+	jFaMlYwTjPtMqE2sTUpMZk3FTUNN2w/AB4wPnDrw0kzILNCsxRyYG5mfMn9lIWIRYnHL
+	EmtpYVlq+dZKxire6r410drF+pL1dxsdm1ybF7aithG2PXa0dk52dXZr9nr2+fbTB6UO
+	JhwccGB3IDu0OuIc7RxrHL8d0j90+tC8k4JTutPEYZHD0YcfOrM7+zt3utC6uLlcc8W4
+	2rtect1yM3erdPvmbuRe5r5C0iUVkZY8tDwKPBY91T3zPd95qXvley14q3uf8l700fQp
+	9Fkm65JLyKu++30rfNf8zP0u+u342/s3BlAEuAa0BTIE+gX2BXEHRQeNBEsEpwdPh6iG
+	nA5ZCTUJrQmDwg6HtYYzIi+HgxGiEWkRM5EakaWR61F2Udei6aMDowdjxGMyYt7FGsRe
+	iEPHkeJ64vnij8bPJGgnnE+EEt0Te5IEklKT5o8YHqk9SnXU7+ijZOnk/OSvKfYp7alc
+	qUdS59IM0+rTadJD0yePqR2rOI4+Tj4+lCGXcSZjO9Mjsz9LOqswayublN1/QuZE8Ymd
+	HK+coVzF3PKT2JOBJyfyNPNq8+nzY/PnTh04dbOAtyCz4Otpl9MPC+ULK4qoiiKKpotN
+	i1vPCJ45eWarxKdkvFSntLGMsyyjbO2sx9nRcq3yKxVcFVkVP86Rzz09b3j+ZqVwZWEV
+	tiqy6m21XfX9C8oX6mrYa7Jqfl4MvDhda1XbV6dUV3eJ81JuPVwfUb942enycINeQ+sV
+	ySvnG5kbs5pAU0TT+6uuVyeaTZp7rilfu3Jd6HrZDeKNzJvQzZibKy0+LdOtDq0jbcZt
+	Pe1q7Tdu7b11sYOvo7STqTO3i6ortWvnduztb93B3ct3vO/M9bj0vOg92Pukz7Jv6K7J
+	3Qf3DO713te+f/uB+oOOh6oP2/qV+1sGFAduDioM3nik8OjGkOLQzcdKj1uHVYbbR/aN
+	dI1qjt4Z0xu798ToycC42fjIhO3E00mnyemnHk8Xnvk/W30e+XzzxZGXmJeZr+heFU5x
+	TlW+FnvdOK043TmjNzM4az37Yo40t/Qm7M3WfOpbwtvCdzzv6hZkFzoWDRaH3x96P78U
+	vLS5nP6B/kPZR9GP1z9pfRpcObgyvxq6uvM5+wvbl4tf5b/2fLP4NvU94PvmWuY623rt
+	hvLG/R/2P95tRm3htop/iv1s3zbZfrkTsLMT7Bbq9utdAIX0sJcXAJ8vIu8JDkjtMAwA
+	Fc3vmuKXBVKuQIgNgu2gvdASfBbljBZCv8d0Y4txwRRWlPpUingp6r0ECRplWhM6V/oI
+	htPENsYZZmoWbdZQtgb2JU4xLl/uJp51Pj3+kwKzQjLCx0ReiSmIn5RYltTfWyW1LeMk
+	2y7PrhCtOK4sp5KjurzPUP2cxg8tK+0LOht6JvolBgv75Y3ijLtMoQNaZrHmTRZzVvTW
+	6jYetml25+yvHbzt0OvYfajNqfFwjXOZy0nXZLcQd2eSqYeSJ78XwWvNe8ann9zsW+KX
+	7E8OsAhUCGIJWgseC6kPTQozD+cJ/xTRFZkT5RQtEf0jpj+2JI4cr5yATRhLrEjyP6Jz
+	VDCZMYU2lS6NPp3uGOE4ZQY6YydzI+tz9tKJ2ZznuaMnB/J68ttOXSmoOn2mMKcopTju
+	TExJcmlx2Y2zw+WzFcvnVs6vVK5Ufar+eOFDzdLFhdo3dTOX5upXG+iv6DYmNrVcfd28
+	fh13g3iTp0W8VaFNs93olnWHe2d0V/HtO90LPeheYh/7Xd574veVHug81OkX7f80kDnI
+	Nnj+keaj5aGGx6HDKiPQyKPR8rGQJ/rjbOMfJ3oni576PFN8tvO8+0XsS7mXy68apsJe
+	75vGTo/OlM16zcnMbb65N1/w1vOd6gLDwvvFrvfZS/bLfMuLH65+jP2ks4JfGV9t+Fz+
+	5frXte9ea883tH4UbE7/lNsu2Nn5lX8BqAl2QDGgHqDTMSZYJuwr3DWKbEp/Klu8HrUc
+	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
+	W2SR/Q9AGf1mCmVuZHN0cmVhbQplbmRvYmoKMzkgMCBvYmoKNzA0CmVuZG9iagoxMyAw
+	IG9iagpbIC9JQ0NCYXNlZCAzOCAwIFIgXQplbmRvYmoKNCAwIG9iago8PCAvVHlwZSAv
+	UGFnZXMgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0gL0NvdW50IDEgL0tpZHMgWyAzIDAg
+	UiBdID4+CmVuZG9iago0MCAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvT3V0bGluZXMg
+	MiAwIFIgL1BhZ2VzIDQgMCBSIC9WZXJzaW9uIC8xLjQgPj4KZW5kb2JqCjI2IDAgb2Jq
+	Cjw8IC9MZW5ndGggNDEgMCBSIC9PcmRlciAxIC9FbmNvZGUgWyAwIDEzNjQgXSAvRnVu
+	Y3Rpb25UeXBlIDAgL0JpdHNQZXJTYW1wbGUKOCAvRGVjb2RlIFsgMCAxIDAgMSAwIDEg
+	XSAvRG9tYWluIFsgMCAxIF0gL1JhbmdlIFsgMCAxIDAgMSAwIDEgXSAvU2l6ZSBbIDEz
+	NjUKXSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGtwQcCgQAAQNH7X0k0
+	VLQ1jBbtNHUFd+C/t20/+mwfzspZlnWhzMvMmaZ5oozTyBlA7+HN6UFd31HaruU0TdtQ
+	6qbmVFVdUcqq5BSgV/HiPEH5M6dkecZJ0yylJGnCieMkpjziB+cOut1vnCsoukaUMAo5
+	QRAGFD/wOReQd/E4LshxHY4NsmyLYlomyDANytk4c04g/aRzNJCqqZwjSDkqFFmRQZIs
+	UURJ5BxA+8OeI4B2wu5/X6r+RswKZW5kc3RyZWFtCmVuZG9iago0MSAwIG9iagoxODgK
+	ZW5kb2JqCjI1IDAgb2JqCjw8IC9MZW5ndGggNDIgMCBSIC9PcmRlciAxIC9FbmNvZGUg
+	WyAwIDEzNjQgXSAvRnVuY3Rpb25UeXBlIDAgL0JpdHNQZXJTYW1wbGUKOCAvRGVjb2Rl
+	IFsgMCAxIDAgMSAwIDEgXSAvRG9tYWluIFsgMCAxIF0gL1JhbmdlIFsgMCAxIDAgMSAw
+	IDEgXSAvU2l6ZSBbIDEzNjUKXSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0K
+	eAGVwolS02AUBtBHabqmaZI2adINRUFRFEFFUVxRFBUFcUVQ9Hnz73kFp4yd2k6a3u/M
+	GfxJB1N/pwPoWTo43z9LSX+lfejPtE9/mvaz9k7T7Cdpb37TOxn9YXrQY9PL3T02499N
+	F/rNdKFfTRfZ+WKAn00H+sl0oEemMxofmTk/mhh6aOLsOj7MeqDjGaMDnfGDjujf6wi6
+	ryPa9r4efgd+q9v0b3Qbuqfbezqkf61D6Csd0u/qcFyFu8NBzpcqgL5QAXRHBbO3dtTE
+	56oFfaZa0KeqRd58orCPVRP6SDWh26o56m+r3NJ/CH4gfeiW9LN6WzL7fenR35MedFN6
+	hO6m/PeudKF3pEt/W7rQDeluyAb9umzkFY31ybdEg35NNCY7ayLvTeFAbwiHflU4ueur
+	YuJ1UYdeE3XoiqjT2ivCvgq+ImzosrCnc3t59iVun68t8fkv8xr0Eq9BF3kta3WRZ7/I
+	q/QXeBW6wKvzVhb4+IBXoH1eoe/xCrTLy8OMusPK0JiV6SNWnlyKWN42K0FDVqIPWGn2
+	YsCmt1gR2mRFqM+KtJbPLI8+sbzEcsGNxII6ieUkBeJ6UoDaSQFaSwr//QuuW4G8CmVu
+	ZHN0cmVhbQplbmRvYmoKNDIgMCBvYmoKNDU2CmVuZG9iagoyNCAwIG9iago8PCAvTGVu
+	Z3RoIDQzIDAgUiAvT3JkZXIgMSAvRW5jb2RlIFsgMCAxMzY0IF0gL0Z1bmN0aW9uVHlw
+	ZSAwIC9CaXRzUGVyU2FtcGxlCjggL0RlY29kZSBbIDAgMSAwIDEgMCAxIF0gL0RvbWFp
+	biBbIDAgMSBdIC9SYW5nZSBbIDAgMSAwIDEgMCAxIF0gL1NpemUgWyAxMzY1Cl0gL0Zp
+	bHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBlcKJUtNgFAbQR2m6pmmSNmnSDUVB
+	URRBRVFcURQVBXFFUPR58+95BaeMndpOmt7vzBn8SQdTf6cD6Fk6ON8/S0l/pX3oz7RP
+	f5r2s/ZO0+wnaW9+0zsZ/WF60GPTy909NuPfTRf6zXShX00X2fligJ9NB/rJdKBHpjMa
+	H5k5P5oYemji7Do+zHqg4xmjA53xg47o3+sIuq8j2va+Hn4Hfqvb9G90G7qn23s6pH+t
+	Q+grHdLv6nBchbvDQc6XKoC+UAF0RwWzt3bUxOeqBX2mWtCnqkXefKKwj1UT+kg1oduq
+	Oepvq9zSfwh+IH3olvSzelsy+33p0d+THnRTeoTupvz3rnShd6RLf1u60A3pbsgG/bps
+	5BWN9cm3RIN+TTQmO2si703hQG8Ih35VOLnrq2LidVGHXhN16Iqo09orwr4KviJs6LKw
+	p3N7efYlbp+vLfH5L/Ma9BKvQRd5LWt1kWe/yKv0F3gVusCr81YW+PiAV6B9XqHv8Qq0
+	y8vDjLrDytCYlekjVp5ciljeNitBQ1aiD1hp9mLAprdYEdpkRajPirSWzyyPPrG8xHLB
+	jcSCOonlJAXielKA2kkBWksK//0LrluBvAplbmRzdHJlYW0KZW5kb2JqCjQzIDAgb2Jq
+	CjQ1NgplbmRvYmoKMjMgMCBvYmoKPDwgL0xlbmd0aCA0NCAwIFIgL09yZGVyIDEgL0Vu
+	Y29kZSBbIDAgMTM2NCBdIC9GdW5jdGlvblR5cGUgMCAvQml0c1BlclNhbXBsZQo4IC9E
+	ZWNvZGUgWyAwIDEgMCAxIDAgMSBdIC9Eb21haW4gWyAwIDEgXSAvUmFuZ2UgWyAwIDEg
+	MCAxIDAgMSBdIC9TaXplIFsgMTM2NQpdIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0
+	cmVhbQp4AZXCiVLTYBQG0EdpuqZpkjZp0g1FQVEUQUVRXFEUFQVxRVD0efPveQWnjJ3a
+	Tpre78wZ/EkHU3+nA+hZOjjfP0tJf6V96M+0T3+a9rP2TtPsJ2lvftM7Gf1hetBj08vd
+	PTbj300X+s10oV9NF9n5YoCfTQf6yXSgR6YzGh+ZOT+aGHpo4uw6Psx6oOMZowOd8YOO
+	6N/rCLqvI9r2vh5+B36r2/RvdBu6p9t7OqR/rUPoKx3S7+pwXIW7w0HOlyqAvlABdEcF
+	s7d21MTnqgV9plrQp6pF3nyisI9VE/pINaHbqjnqb6vc0n8IfiB96Jb0s3pbMvt96dHf
+	kx50U3qE7qb89650oXekS39butAN6W7IBv26bOQVjfXJt0SDfk00JjtrIu9N4UBvCId+
+	VTi566ti4nVRh14TdeiKqNPaK8K+Cr4ibOiysKdze3n2JW6fry3x+S/zGvQSr0EXeS1r
+	dZFnv8ir9Bd4FbrAq/NWFvj4gFegfV6h7/EKtMvLw4y6w8rQmJXpI1aeXIpY3jYrQUNW
+	og9YafZiwKa3WBHaZEWoz4q0ls8sjz6xvMRywY3EgjqJ5SQF4npSgNpJAVpLCv/9C65b
+	gbwKZW5kc3RyZWFtCmVuZG9iago0NCAwIG9iago0NTYKZW5kb2JqCjIyIDAgb2JqCjw8
+	IC9MZW5ndGggNDUgMCBSIC9PcmRlciAxIC9FbmNvZGUgWyAwIDEzNjQgXSAvRnVuY3Rp
+	b25UeXBlIDAgL0JpdHNQZXJTYW1wbGUKOCAvRGVjb2RlIFsgMCAxIDAgMSAwIDEgXSAv
+	RG9tYWluIFsgMCAxIF0gL1JhbmdlIFsgMCAxIDAgMSAwIDEgXSAvU2l6ZSBbIDEzNjUK
+	XSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGlwoVSQlEAQMG/tru7u7Hp
+	BhUDA1uxA+tTjjEy+PDFjZ1NfpC0mPjg+7vi+DvF34gLj71h95WY7egrEl+IGkdeUJwj
+	kiOsPZQj9Kw++IzhE0GZgSfsPhKw7X9E9AP+f30PqLzH99N7j2bPHTrddxje4pa5eovl
+	G1adrtwg9JoVs8vXSL9iOX/pCs2LWXQuZCm8ZEHy/CXmL5gX6LpA6Dkus3PnSD9jLn/2
+	DK2nzOidPuX3CdPyp04wf8yUwMljnB8xaXHiCLmHTPw5foj6DOMZxvSOZvh9wKj8kQNM
+	7jMidngfh3sMWx/aQ+IuQ8aDu6hPM5hmQG9/mu87ivt2KL5Nn/DebRxu0Wu9ZwuJm/QY
+	d2+iOEX3z64UOjtTdG6o79ig+DodwtvXsbtGu+22NUQnafu3NYnKBK35LQl0Nidojqtv
+	imMYo0lmYwzLURqdNkQRGqHBbH0ElWHq8+vC6KwNobMmRGGQGsnVQSwHqHZaFUConyqz
+	lX6k+6j8s8KHei/lesu8FHook1zqwbybUoElbr5+Al7liFUKZW5kc3RyZWFtCmVuZG9i
+	ago0NSAwIG9iago0MTAKZW5kb2JqCjIgMCBvYmoKPDwgL0xhc3QgNDYgMCBSIC9GaXJz
+	dCA0NyAwIFIgPj4KZW5kb2JqCjQ3IDAgb2JqCjw8IC9QYXJlbnQgNDggMCBSIC9Db3Vu
+	dCAwIC9EZXN0IFsgMyAwIFIgL1hZWiAwIDczMyAwIF0gL1RpdGxlIChDYW52YXMgMSkK
+	Pj4KZW5kb2JqCjQ4IDAgb2JqCjw8ID4+CmVuZG9iago0NiAwIG9iago8PCAvUGFyZW50
+	IDQ4IDAgUiAvQ291bnQgMCAvRGVzdCBbIDMgMCBSIC9YWVogMCA3MzMgMCBdIC9UaXRs
+	ZSAoQ2FudmFzIDEpCj4+CmVuZG9iago0OSAwIG9iago8PCAvTGVuZ3RoIDUwIDAgUiAv
+	TGVuZ3RoMSAxMDUzMiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAG9ent8
+	VEWW8Km6z34k6e50p9+PS6e78w4JEAgJpAlJCK8IBCFBowkkkCCMgDGKO/BFRYGIKCIP
+	xVVRh6dOmsBIA4PLsDDI7syIM4oj6646ouu6mx878+F8M0B3f6duhwzJz5kff/ibe/tU
+	1annqVOnzjlVtztXPdgGKdANHMxa0LJiMahPKAxALi9a3rIiiaebMT6wqKvTl8SFLABu
+	2eIVS5Yncfl5AK17ybLVA+3TrwKYPmhva2lNlsMNjEvaMSOJk9EYZ7Yv73w4iZuOYNy8
+	7P5FA+XppxAvXt7y8MD48Anivh+0LG/DGJ+QC4PMFfc/0KmiEHwX47krVrUN1CcNSN97
+	QDDXBveDBu4DCSgY8G0CkL7WuoHHUlaOT2uebuu9aeXfglFW8XtnPqPGP1d+evFPbTdC
+	ui3ynzFDc7M+i8XseDaAnmB5v27LYInaDgNbFOpzozAVoQJhDEJu7iQbdJM98CzCqwgc
+	dJCnYDXCRoQXEPjB1H7EjpGn+ng5fJysBgeZFtbx3rlmu9em1Xl/HSXikZe9H9u+OEHs
+	uHqfE3tfCmgmacmr5BVoBS/5EQTII1ALWeTFw9nLvM1YtB9WIHQjcGpIyP4+T7H3HZIH
+	AZ5gmyB4ePK29z+L8r1fFkUp6fOeDkV5jH7mQSyc5j3lftn7T+4l3ncQDiaLDmRjjbe9
+	+93LvFs9UfJin/c5d5Rgmy3J6EE3Nn3buzx7u7e1SC2fsT1KD/Z5S7F8XljnLRmneMe4
+	L3sLQ1GZIJ7vnuHNKfqlNxMbYjUfdhoIG70u91bveCzyuKtD4xFOkANkF+SQXX2Bad7j
+	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
+	uIoNeAQzQibCaIQqhLkIrQidCOsQnkd4A+EIwhmEDxIDD/YBg2mCemcoPmkYPnkYXjUM
+	rx6Go4Id0v+MYXjdMHzOMBznMaT9vGH4vcNwxsFb57NoGN46DFfX9pb5dwwrV/+PeEv5
+	D4aVrxqG483wkPGR/0PwLob/fzlhnKgKZW5kc3RyZWFtCmVuZG9iago1MCAwIG9iago2
+	ODEyCmVuZG9iago1MSAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0FzY2Vu
+	dCA3NzAgL0NhcEhlaWdodCA2ODQgL0Rlc2NlbnQgLTIzMCAvRmxhZ3MgMzIKL0ZvbnRC
+	Qm94IFstOTUxIC00ODEgMTQ0NSAxMTIyXSAvRm9udE5hbWUgL1ZWWEZIWitIZWx2ZXRp
+	Y2EgL0l0YWxpY0FuZ2xlIDAKL1N0ZW1WIDAgL01heFdpZHRoIDE1MDAgL1hIZWlnaHQg
+	NTEzIC9Gb250RmlsZTIgNDkgMCBSID4+CmVuZG9iago1MiAwIG9iagpbIDI3OCAwIDAg
+	MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA2NjcgMCA3MjIgNzIyIDY2NyAw
+	IDAgMCAyNzggMCAwCjU1NiAwIDcyMiAwIDAgMCA3MjIgMCA2MTEgMCA2NjcgMCAwIDAg
+	MCAwIDAgMCAwIDU1NiAwIDU1NiAwIDUwMCA1NTYgNTU2IDAKMCAwIDIyMiAwIDAgMCA4
+	MzMgNTU2IDAgMCAwIDMzMyA1MDAgMjc4IDAgNTAwIF0KZW5kb2JqCjE0IDAgb2JqCjw8
+	IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UcnVlVHlwZSAvQmFzZUZvbnQgL1ZWWEZIWitI
+	ZWx2ZXRpY2EgL0ZvbnREZXNjcmlwdG9yCjUxIDAgUiAvV2lkdGhzIDUyIDAgUiAvRmly
+	c3RDaGFyIDQ2IC9MYXN0Q2hhciAxMTggL0VuY29kaW5nIC9NYWNSb21hbkVuY29kaW5n
+	Cj4+CmVuZG9iago1MyAwIG9iago8PCAvTGVuZ3RoIDU0IDAgUiAvTGVuZ3RoMSA5MDEy
+	IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4Ab1aC3RTZbbe+7zy6iNpm6ZJ
+	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
+	LF3y+flo7Au68O9aYPWUlZUYjZcVNfiG9vzpkRNu65w5ztJ0Q1Xu4vbND5/8036WBghB
+	H/srcz3fT/Yzf0zrSrYkuHTP4AbgsMubroAuAYUMGppkYYJTOeFfaJwywph0UOyRhue1
+	mjORmokaaXz+2y8fHsZraXkoLUmtkM4Ps/U2nbT7rHTrFQL1Taffi6aRkezlieak7X+Y
+	X8KufwFLoi+9EDk6T0R8nVf4S1czD5BOdO7iltM3NgF+7l3kFJbQAecx4Wm60xdQyzRR
+	0g3MIHsdJzThDtjO7+Ef5w/xJ9iP8CyqWCvHOVN4XmCsiM4UqkJgePpsLrCMWsmQswlj
+	wijLkwUmjHFGRZ/UD+PFBwij9ncZ8kSQTg5Th4YbAsenzgsUji/Y5OXJVaKYyjqwLHpd
+	9NXoJvS+z9WfO8LVnz9Fc1P+xaQvTN/2S6FIO+RALllhBX0na6QvUs301W4ReaDF9KVr
+	GSyHgFwQyY9JZ05ynfQFEBqX1s/vaClo7lu3sW9wTW+wsP7qdauksbzwa6MA/ZcD/c8D
+	wI1EtxHdT/RLol8TvUh0iuhvROepYALRLCIXUQ3RAqKu2OSP8sBUGOn8O12Wp9RF6Q0z
+	0ltmyO0z5OAMuXeGTB2b1r6M5UXtrZmRvm6GLP9/ykX5r5qRfs0M+UczZPn/Sy4qL90B
+	wP8BMGBdrQplbmRzdHJlYW0KZW5kb2JqCjU0IDAgb2JqCjU3MzgKZW5kb2JqCjU1IDAg
+	b2JqCjw8IC9UeXBlIC9Gb250RGVzY3JpcHRvciAvQXNjZW50IDc3MCAvQ2FwSGVpZ2h0
+	IDY4NCAvRGVzY2VudCAtMjMwIC9GbGFncyAzMgovRm9udEJCb3ggWy0xMDE4IC00ODEg
+	MTQzNiAxMTU5XSAvRm9udE5hbWUgL0ZVQkpTSStIZWx2ZXRpY2EtQm9sZCAvSXRhbGlj
+	QW5nbGUKMCAvU3RlbVYgMCAvTWF4V2lkdGggMTUwMCAvWEhlaWdodCA1MTMgL0ZvbnRG
+	aWxlMiA1MyAwIFIgPj4KZW5kb2JqCjU2IDAgb2JqClsgNzIyIDAgNzIyIDAgNjY3IDAg
+	MCAwIDI3OCAwIDAgMCAwIDAgMCAwIDAgNzIyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw
+	IDAKMCA1NTYgMCA1NTYgNjExIDU1NiAwIDAgMCAyNzggMCAwIDI3OCA4ODkgNjExIDAg
+	MCAwIDM4OSA1NTYgMzMzIDAgNTU2IF0KZW5kb2JqCjE2IDAgb2JqCjw8IC9UeXBlIC9G
+	b250IC9TdWJ0eXBlIC9UcnVlVHlwZSAvQmFzZUZvbnQgL0ZVQkpTSStIZWx2ZXRpY2Et
+	Qm9sZCAvRm9udERlc2NyaXB0b3IKNTUgMCBSIC9XaWR0aHMgNTYgMCBSIC9GaXJzdENo
+	YXIgNjUgL0xhc3RDaGFyIDExOCAvRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4K
+	ZW5kb2JqCjU3IDAgb2JqCihVbnRpdGxlZCkKZW5kb2JqCjU4IDAgb2JqCihNYWMgT1Mg
+	WCAxMC42LjggUXVhcnR6IFBERkNvbnRleHQpCmVuZG9iago1OSAwIG9iagooS2F0aWUg
+	TWNDb3JtaWNrKQplbmRvYmoKNjAgMCBvYmoKKE9tbmlHcmFmZmxlIFByb2Zlc3Npb25h
+	bCkKZW5kb2JqCjYxIDAgb2JqCihEOjIwMTExMDIwMjIwOTQyWjAwJzAwJykKZW5kb2Jq
+	CjEgMCBvYmoKPDwgL1RpdGxlIDU3IDAgUiAvQXV0aG9yIDU5IDAgUiAvUHJvZHVjZXIg
+	NTggMCBSIC9DcmVhdG9yIDYwIDAgUiAvQ3JlYXRpb25EYXRlCjYxIDAgUiAvTW9kRGF0
+	ZSA2MSAwIFIgPj4KZW5kb2JqCnhyZWYKMCA2MgowMDAwMDAwMDAwIDY1NTM1IGYgCjAw
+	MDAwMzM0MDYgMDAwMDAgbiAKMDAwMDAxODk5NCAwMDAwMCBuIAowMDAwMDAyNTg1IDAw
+	MDAwIG4gCjAwMDAwMTU2OTAgMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAw
+	MDAyNTY1IDAwMDAwIG4gCjAwMDAwMDI2ODkgMDAwMDAgbiAKMDAwMDAwODY3NSAwMDAw
+	MCBuIAowMDAwMDAzNzU1IDAwMDAwIG4gCjAwMDAwMDQyNTggMDAwMDAgbiAKMDAwMDAw
+	NDI3OCAwMDAwMCBuIAowMDAwMDA0ODEzIDAwMDAwIG4gCjAwMDAwMTU2NTMgMDAwMDAg
+	biAKMDAwMDAyNjYxMSAwMDAwMCBuIAowMDAwMDAzMTExIDAwMDAwIG4gCjAwMDAwMzMw
+	MjggMDAwMDAgbiAKMDAwMDAwMjk1MCAwMDAwMCBuIAowMDAwMDAzMjcyIDAwMDAwIG4g
+	CjAwMDAwMDM0MzMgMDAwMDAgbiAKMDAwMDAwMzU5NCAwMDAwMCBuIAowMDAwMDA3Nzc4
+	IDAwMDAwIG4gCjAwMDAwMTgzNDkgMDAwMDAgbiAKMDAwMDAxNzY1OCAwMDAwMCBuIAow
+	MDAwMDE2OTY3IDAwMDAwIG4gCjAwMDAwMTYyNzYgMDAwMDAgbiAKMDAwMDAxNTg1MyAw
+	MDAwMCBuIAowMDAwMDE0Nzg4IDAwMDAwIG4gCjAwMDAwMDU5MjkgMDAwMDAgbiAKMDAw
+	MDAwNjg5OCAwMDAwMCBuIAowMDAwMDA0ODMzIDAwMDAwIG4gCjAwMDAwMDU5MDkgMDAw
+	MDAgbiAKMDAwMDAwNjkxOCAwMDAwMCBuIAowMDAwMDA3NzU4IDAwMDAwIG4gCjAwMDAw
+	MDc4MTUgMDAwMDAgbiAKMDAwMDAwODY1NSAwMDAwMCBuIAowMDAwMDA4NzExIDAwMDAw
+	IG4gCjAwMDAwMTQ3NjcgMDAwMDAgbiAKMDAwMDAxNDgyNSAwMDAwMCBuIAowMDAwMDE1
+	NjMzIDAwMDAwIG4gCjAwMDAwMTU3NzMgMDAwMDAgbiAKMDAwMDAxNjI1NiAwMDAwMCBu
+	IAowMDAwMDE2OTQ3IDAwMDAwIG4gCjAwMDAwMTc2MzggMDAwMDAgbiAKMDAwMDAxODMy
+	OSAwMDAwMCBuIAowMDAwMDE4OTc0IDAwMDAwIG4gCjAwMDAwMTkxNTcgMDAwMDAgbiAK
+	MDAwMDAxOTA0MiAwMDAwMCBuIAowMDAwMDE5MTM1IDAwMDAwIG4gCjAwMDAwMTkyNTAg
+	MDAwMDAgbiAKMDAwMDAyNjE1MyAwMDAwMCBuIAowMDAwMDI2MTc0IDAwMDAwIG4gCjAw
+	MDAwMjYzOTkgMDAwMDAgbiAKMDAwMDAyNjc4NiAwMDAwMCBuIAowMDAwMDMyNjE0IDAw
+	MDAwIG4gCjAwMDAwMzI2MzUgMDAwMDAgbiAKMDAwMDAzMjg2NiAwMDAwMCBuIAowMDAw
+	MDMzMjA4IDAwMDAwIG4gCjAwMDAwMzMyMzUgMDAwMDAgbiAKMDAwMDAzMzI4NyAwMDAw
+	MCBuIAowMDAwMDMzMzIxIDAwMDAwIG4gCjAwMDAwMzMzNjQgMDAwMDAgbiAKdHJhaWxl
+	cgo8PCAvU2l6ZSA2MiAvUm9vdCA0MCAwIFIgL0luZm8gMSAwIFIgL0lEIFsgPDQ3NmJj
+	NzlkZDc0MDQwZDE3MjBiNTkyNTY2YzIzYWYxPgo8NDc2YmM3OWRkNzQwNDBkMTcyMGI1
+	OTI1NjZjMjNhZjE+IF0gPj4Kc3RhcnR4cmVmCjMzNTI2CiUlRU9GCjEgMCBvYmoKPDwv
+	QXV0aG9yIChLYXRpZSBNY0Nvcm1pY2spL0NyZWF0aW9uRGF0ZSAoRDoyMDExMTAxMjE4
+	MzQwMFopL0NyZWF0b3IgKE9tbmlHcmFmZmxlIFByb2Zlc3Npb25hbCA1LjIpL01vZERh
+	dGUgKEQ6MjAxMTEwMjAyMjA5MDBaKS9Qcm9kdWNlciA1OCAwIFIgL1RpdGxlIChDYWxl
+	bmRhci1kYXRhbW9kZWwtbmV3LmdyYWZmbGUpPj4KZW5kb2JqCnhyZWYKMSAxCjAwMDAw
+	MzQ5MjQgMDAwMDAgbiAKdHJhaWxlcgo8PC9JRCBbPDQ3NmJjNzlkZDc0MDQwZDE3MjBi
+	NTkyNTY2YzIzYWYxPiA8NDc2YmM3OWRkNzQwNDBkMTcyMGI1OTI1NjZjMjNhZjE+XSAv
+	SW5mbyAxIDAgUiAvUHJldiAzMzUyNiAvUm9vdCA0MCAwIFIgL1NpemUgNjI+PgpzdGFy
+	dHhyZWYKMzUxMjUKJSVFT0YK
+	</data>
+	<key>QuickLookThumbnail</key>
+	<data>
+	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
+	DgAAAbJydVJVAAAAJAAAAcBzdlNFAAAAEAAAAeR6aFRXAAAADgAAAfRkZURFAAAAEAAA
+	AgJmaUZJAAAAEAAAAhJpdElUAAAAFAAAAiJrb0tSAAAADAAAAjYASwBsAGUAdQByAGUA
+	bgAtAEwAQwBEAEwAQwBEAC0AZgBhAHIAdgBlAHMAawDmAHIAbQBLAG8AbABvAHIAIABM
+	AEMARABDAG8AbABvAHIAIABMAEMARABGAGEAcgBnAGUALQBMAEMARABMAEMARAAgAGMA
+	bwB1AGwAZQB1AHIATABDAEQAIABDAG8AbABvAHIAaQBkAG8ATABDAEQAIABhACAAQwBv
+	AHIAZQBzX2mCcgAgAEwAQwBEAEwAQwBEACAAYwBvAGwAbwByMKsw6TD8ACAATABDAEQE
+	JgQyBDUEQgQ9BD4EOQAgBBYEGgAtBDQEOARBBD8EOwQ1BDkARgDkAHIAZwAtAEwAQwBE
+	X2mCcm2yZnaYb3k6VmgARgBhAHIAYgAtAEwAQwBEAFYA5AByAGkALQBMAEMARABMAEMA
+	RAAgAGMAbwBsAG8AcgBpzuy37AAgAEwAQwBEAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBs
+	ZSwgSW5jLiwgMjAxMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNSAAEAAAAB
+	Fs9YWVogAAAAAAAAba8AADhpAAABXlhZWiAAAAAAAABikAAAui0AAAarWFlaIAAAAAAA
+	ACaWAAANagAAyyRjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADYAOwBA
+	AEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8AowCoAK0AsgC3ALwA
+	wQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFS
+	AVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQC
+	HQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMW
+	AyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgE
+	VQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXF
+	BdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QH
+	hgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5
+	CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7AL
+	yAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5J
+	DmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMR
+	MRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJ
+	FGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X
+	0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuK
+	G7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qf
+	vx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQf
+	JE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQp
+	Bik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4W
+	Lkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38z
+	uDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/
+	Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/
+	4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZn
+	RqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpN
+	k03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1Tb
+	VShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc
+	1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTp
+	ZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBt
+	uW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnab
+	dvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WA
+	R4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+
+	imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCU
+	ipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8d
+	n4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyq
+	j6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYB
+	tnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePC
+	X8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62
+	zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724Dc
+	BdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG
+	6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3
+	ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//3BhcmEAAAAAAAMAAAACZmYAAPKn
+	AAANWQAAE9AAAAoOdmNndAAAAAAAAAAAAAMBAAACAAAAVgEuAesCnQNeBCUE6gXABpgH
+	cAhSCUUKNgsvDC4NKw44D0sQYBF1EpUTuRThFgwXQRhyGa0a6xwpHWoesB/4IUQikCPi
+	JTEmhyfdKTUqkCvsLUUuoy/+MVwyujQaNXg21TgzOY467DxHPaA++kBSQaVC+URLRZpG
+	6Eg0SXtKvkwBTUBOek+wUONSEVM9VGRVhVagV7NYv1nDWsBbuVyvXaZenF+QYIJhcWJe
+	Y0xkN2UiZg1m92fhaMppsmqaa4JsaW1QbjVvF2/3cNNxq3J/c090H3Tvdb52jndceCt4
+	+nnKepp7aXw4fQZ9036ff2yAQoEkghSDD4QQhRGGEIcNiAmJBIn/ivmL8ozrjeKO2o/S
+	kMuRwpK5k66Uo5WZlo6Xg5h7mXmagpuYnLWd0J7in+yg8KHwovCj76Tupe2m66foqOSp
+	4arjq/GtEa5Dr36wt7Hfsvi0B7UTth+3Krg1uT+6SbtTvGK9eL6Yv8HA6MIEwxPEGsUg
+	xirHN8hCyULKKMrvy4rMGcyhzT/N7M6tz3LQOdEB0c3SntNx1EXVGdXu1sPXl9ho2TbZ
+	/9rA23rcM9zs3a3ec9884Abg0uGc4mbjMeP75MbllOZl5zroEujq6b7qjOtX7CHs6e2x
+	7nrvQvAL8NXxrfKe87T09/Zm99r5QPqU++D9M/6U//8AAABWASMBsAJZAxIDyASGBUsG
+	FQbdB7MIjAlsClULRAwzDSkOJQ8oEC8RNRJGE1YUbhWEFqMXxBjrGhEbPhxpHZoezB//
+	ITgidCOuJOomKydoKKgp6ystLHIttS75MD8xgTLHNAs1TDaON9E5EzpQO448yj4GPz9A
+	dkGoQttEC0U6RmJHiUirSctK6UwCTRdOJ08zUDpROlIzUyRUDlT1VdpWwFekWIpZblpT
+	WzdcG1z/XeJexF+mYIZhZGJAYxxj92TRZatmhWdeaDdpEGnoar9rl2xubUVuGm7tb79w
+	jnFaciJy6XOwdHd1OnX9dr53f3hAeQR5yHqNe1B8E3zVfZd+W38jf/CAw4GfgoODboRa
+	hUeGNIchiAyI94niisyLtoygjYiOco9dkEyRP5I1ky6UKJUilhyXF5gRmQqaBJr8m/Sc
+	653gntef0aDQodWi36PrpPimA6cOqBmpJKowqzysRq1PrlmvZbB2sYyyqLPEtN618bcB
+	uBC5Ibozu0a8W71wvoa/m8Cpwa3CpMOQxHTFVMYyxxHH8cjUybnKn8uFzGvNUc44zyHQ
+	C9D40ePSzdOy1JfVfdZj10vYNNkd2gXa7NvU3Lvdo96N33zgcOFr4m3jdOR95Ybmkeeb
+	6KXpsOq668Psze3b7vjwOfGk80L1C/b0+Oj60vyi/ln//wAAAFYBHAGNAigCywNtBBsE
+	ywWCBj4G+Ae9CIcJWQozCw4L6AzJDbMOng+NEIMRehJ2E3kUeRV9FoYXjxidGa8axBvY
+	HO4eDR8kIEIhYCKDI6MkxSXpJw4oMSlVKnsrnyzELekvETA3MVoyezOeNL813jb+OBs5
+	OTpSO2k8fj2RPqM/sUC8QcVCykPMRMtFx0a/R7NIokmKSm5LS0wgTPRNxk6XT2lQOVEH
+	UdZSpVNzVEBVDFXXVqRXcFg7WQZZ0FqaW2VcLlz2Xb5ehl9OYBNg12GaYl5jH2PgZKBl
+	YGYfZt9noGhgaR9p3mqda1lsE2zObYluRW8Bb7twdHEncdhyiHM3c+d0lnVEdfJ2oHdO
+	d/t4qXlWegJ6r3tbfAV8sH1bfgV+sH9egBSA0YGWgmWDOIQOhOWFvYaUh2uIQYkXie2K
+	wYuUjGaNN44KjuCPuJCSkXKSU5M1lBmU/pXklsqXr5iTmXaaWZs6nBqc953VnrWfm6CN
+	oYaihKOFpIelh6aFp32obalYqkWrO6w9rUuuYa98sJixtLLNs+W0+7YRtya4PLlRume7
+	fryVvaq+vL/HwMrBycLFw8HEvcW4xrPHrcinyZ/KmcuSzIzNhs6Dz4XQkdGo0snT8dUd
+	1knXdtii2c7a+dwk3VPej9/g4WnjGOT15wXpfuzD8ZP4JP//AABuZGluAAAAAAAABjYA
+	AKZFAABWgAAAUf8AAKhRAAAllAAADLkAAFANAABUOQACa4UAAhHrAAGcKAADAQAAAgAA
+	AAEABAAJABAAGQAjAC8APQBLAFsAbAB+AJIApgC7ANEA6QEBARoBNAFPAWsBhwGlAcMB
+	4gICAiMCRQJnAosCrwLUAvoDIQNIA3EDmgPEA+8EGwRHBHUEowTTBQMFNAVnBZoFzgYD
+	BjkGcAaoBuIHHAdYB5QH0ggRCFEIkwjVCRkJXwmmCe4KOAqDCtALHgtuC8AMFAxqDMEN
+	Gw13DdUONg6ZDv8PZw/SEEEQsxEqEaYSJxKvEzsTzBRfFPQVjRYqFssXcBgXGMMZcRoi
+	GtYbjRxIHQYdxh6KH1EgHCDtIcQioyOLJHolbSZkJ18oXilgKmUrbSx5LYkuni+6MNcx
+	6jLuM+Q01DXDNrY3rjiqOak6qjuwPLg9xD7TP+VA+UIPQylERkVnRotHsUjbSgdLMkxX
+	TXJOg0+PUJ5Rt1LbVAlVPlZ3V7NY8lo0W3hcwV4NX1xgqWHsYx1kP2VXZm1niGiyae1r
+	N2yJbd9vNnCQce5zT3SydhV3dHjKehd7Xnyoff9/aIDhgmGD34VZhtWIWYn8i+iOjpGd
+	lBqWSphwmpicuJ7OoOGi9qUOpympS6t4rbqwHrKitSu3nrn/vFy+u8Egw4rF+choytPN
+	NM+L0ePUTdbO2WDb+d6X4Tjj3+aE6PvrIuz+7qTwJPGf8xn0ovY+9+f5mPtC/N7+cv//
+	AAAAAQAFAAsAEwAdACkANwBGAFcAaQB8AJEApwC+ANYA7wEKASUBQgFfAX4BngG+AeAC
+	AgImAkoCcAKWAr4C5gMQAzoDZQORA78D7QQcBE0EfgSxBOQFGQVOBYUFvQX2BjAGbAao
+	BuYHJQdmB6gH6wgvCHUIvQkGCVAJnQnqCjoKiwrfCzQLiwvkDD8MnQz9DWANxQ4tDpcP
+	BQ92D+sQYxDgEWIR6hJ5Ew8TqhRHFOgVixYxFtoXhhg0GOYZmxpUGxAb0hyYHWIeLx8A
+	H9UgrSGJImcjSiQxJRsmCCb7J/Qo9Cn8Kw0sIy0+LmAviTC5MeozHDRQNYs2zDgROVc6
+	mTvTPQE+Jj9GQGZBiEKtQ9VFAkYyR2ZInUnXSxZMVk2WTtNQDlFHUn9TulT3VjZXeFi9
+	WgVbUFyfXfJfSmCkYf1jUWSgZepnM2h9actrHWxxbcZvHXB2cdNzNHSXdfx3X3i+ehh7
+	bnzGfiN/ioD4gmqD3YVQhsOIN4mtiyKMmo4Xj5+ROpLtlLiWl5iCmnGcX55KoDSiH6QO
+	pf+n8qnmq9ityK+8sbmzwbXPt92567v5vgrAIMI6xFjGecibyrrM0M7b0NjSzNS81qzY
+	ndqR3Ifef+B54nfkeOZ76HjqXewW7abvF/Bp8aPy1fP39Rf2M/dQ+HP5mfrN/Af9Uf6k
+	//8AAAABAAYADQAXACMAMQBCAFQAaAB9AJQArQDHAOIA/wEdATwBXQF+AaEBxgHrAhIC
+	OgJjAo0CuALlAxMDQQNyA6MD1gQJBD4EdQSsBOUFHwVbBZgF1gYWBlcGmgbeByMHagez
+	B/4ISgiYCOgJOgmNCeMKOgqUCvALTwuwDBMMeQziDU4NvQ4wDqUPHw+cEB4QpBExEcQS
+	XxMCE6oUVxUHFbsWdBcwF/AYtBl9GkkbGBvsHMQdoB5/H2MgTCE5IiojISQfJSEmKSc2
+	KEkpXyp5K5csui3iLxIwSjGGMsM0BTVRNq04Ezl/OvE8aT3oP2xA9kKGRBxFukdfSQtK
+	vExpTgVPi1EAUm9T3VVOVsJYO1m4WzlcwF5OX+FheGMPZKNmNGfAaUtq12xjbfFvgXEV
+	cq90TXXwd5l5SnsBfLh+Y3/+gY6DGISihi2HvYlUiviMro5ukCqR05NqlPOWdZf1mXea
+	/JyGnhSfpqE7otOkbaYKp6ipSKrprIyuNK/ksaGzbLVEtyK5BLrpvNG+vcCtwqLEmsaU
+	yJHKj8yPzovQfdJe1DDV9dey2W3bKdzm3qXgZuIq4/HlvOeF6UTq8eyI7fLvSfCM8bfy
+	3fPs9Pn14/bJ95L4PPjm+YT5+fpu+uP7WPu//BT8afy+/RT9af2+/gj+UP6Y/t//J/9v
+	/7f//wAAc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGxt
+	bW9kAAAAAAAABhAAAJy7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+	</data>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<false/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<integer>0</integer>
+		<key>ExpandedCanvases</key>
+		<array>
+			<dict>
+				<key>name</key>
+				<string>Canvas 1</string>
+			</dict>
+		</array>
+		<key>Frame</key>
+		<string>{{34, 76}, {710, 887}}</string>
+		<key>ListView</key>
+		<true/>
+		<key>OutlineWidth</key>
+		<integer>142</integer>
+		<key>RightSidebar</key>
+		<false/>
+		<key>ShowRuler</key>
+		<true/>
+		<key>Sidebar</key>
+		<true/>
+		<key>SidebarWidth</key>
+		<integer>120</integer>
+		<key>VisibleRegion</key>
+		<string>{{0, 0}, {575, 733}}</string>
+		<key>Zoom</key>
+		<real>1</real>
+		<key>ZoomValues</key>
+		<array>
+			<array>
+				<string>Canvas 1</string>
+				<real>1</real>
+				<real>1</real>
+			</array>
+		</array>
+	</dict>
+	<key>saveQuickLookFiles</key>
+	<string>YES</string>
+</dict>
+</plist>
diff --git a/docs/html/images/providers/datamodel.png b/docs/html/images/providers/datamodel.png
new file mode 100644
index 0000000..a14c328
--- /dev/null
+++ b/docs/html/images/providers/datamodel.png
Binary files differ
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index 9089937..07a0e43 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.2,90.8" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.8,90.2" />
 
 <table>
 <tr>
@@ -66,14 +66,14 @@
 </tr>
 <tr>
 <td>1.1</th>
-<td>9.2%</td>
+<td>9.8%</td>
 </tr>
 <tr>
 <td>2.0</th>
-<td>90.8%</td>
+<td>90.2%</td>
 </tr>
 </table>
 
-<p><em>Data collected during a 7-day period ending on October 3, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on November 3, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 135c6f2..8041096 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="470"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.1,1.4,11.7,45.3,0.5,38.2,0.2,0.9,0.7&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.9,1.4,10.7,40.7,0.5,43.9,0.1,0.9,0.9&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
@@ -61,21 +61,21 @@
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>1.1%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.9%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.4%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>11.7%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>45.3%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>10.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>40.7%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3 -<br/>
                              Android 2.3.2</a></td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.5%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.3 -<br/>
-      Android 2.3.7</a></td><!-- Gingerbread -->                                       <td>10</td><td>38.2%</td></tr>
+      Android 2.3.7</a></td><!-- Gingerbread -->                                       <td>10</td><td>43.9%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0</a></td>
-                                                   <td rowspan="3">Honeycomb</td>      <td>11</td><td>0.2%</td></tr>
+                                                   <td rowspan="3">Honeycomb</td>      <td>11</td><td>0.1%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>0.9%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.7%</td></tr> 
+<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.9%</td></tr> 
 </table>
 
-<p><em>Data collected during a 14-day period ending on October 3, 2011</em></p>
+<p><em>Data collected during a 14-day period ending on November 3, 2011</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -104,9 +104,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.7,99.6,99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.5,98.5,98.2|97.0,97.1,97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5,97.5,97.1|93.5,93.9,94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.7,95.8,95.6|66.4,68.0,69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4,83.3,83.8|2.5,3.1,4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.2,34.7,38.3|1.7,2.2,3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.6,34.1,37.8&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,5,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.5,98.5,98.2,98.1,98.0|97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5,97.5,97.1,97.1,97.1|94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.7,95.8,95.6,95.9,95.7|69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4,83.3,83.8,84.9,85.0|4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.2,34.7,38.3,41.3,44.0|3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.6,34.1,37.8,40.8,43.5&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,3,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on October 3, 2011</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on November 3, 2011</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index 67b47d0..ec3034d 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -60,7 +60,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A2.6,0.1,3.0,71.9,0.9,17.6,2.7,1.2" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A2.9,0.1,3.1,70.8,1.0,17.7,3.0,1.3" />
 
 <table>
 <tr>
@@ -71,31 +71,31 @@
 <th scope="col">xhdpi</th>
 </tr>
 <tr><th scope="row">small</th> 
-<td>1.2%</td>     <!-- small/ldpi -->
+<td>1.3%</td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>2.7%</td> <!-- small/hdpi -->
+<td>3.0%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
-<td>0.9%</td>  <!-- normal/ldpi -->
-<td>17.6%</td> <!-- normal/mdpi -->
-<td>71.9%</td> <!-- normal/hdpi -->
+<td>1.0%</td>  <!-- normal/ldpi -->
+<td>17.7%</td> <!-- normal/mdpi -->
+<td>70.8%</td> <!-- normal/hdpi -->
 <td></td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
 <td>0.1%</td>     <!-- large/ldpi -->
-<td>3.0%</td> <!-- large/mdpi -->
+<td>3.1%</td> <!-- large/mdpi -->
 <td></td>     <!-- large/hdpi -->
 <td></td>     <!-- large/xhdpi -->
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
-<td>2.6%</td> <!-- xlarge/mdpi -->
+<td>2.9%</td> <!-- xlarge/mdpi -->
 <td></td>     <!-- xlarge/hdpi -->
 <td></td>     <!-- xlarge/xhdpi -->
 </tr> 
 </table>
 
-<p><em>Data collected during a 7-day period ending on October 3, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on November 3, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 237e18c..41a5a51 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -578,7 +578,7 @@
     }
   },
   {
-    tags: ['sample', 'newfeature', 'performance', 'gamedev', 'gl'],
+    tags: ['sample', 'newfeature', 'performance', 'gamedev', 'gl', 'updated'],
     path: 'samples/RenderScript/index.html',
     title: {
       en: 'RenderScript'
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index f87e1f6..afbad57 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -1,18 +1,19 @@
 ndk=true
 
-ndk.win_download=android-ndk-r6b-windows.zip
-ndk.win_bytes=67670219
-ndk.win_checksum=f496b48fffb6d341303de170a081b812
+ndk.win_download=android-ndk-r7-windows.zip
+ndk.win_bytes=81270552
+ndk.win_checksum=55483482cf2b75e8dd1a5d9a7caeb6e5
 
-ndk.mac_download=android-ndk-r6b-darwin-x86.tar.bz2
-ndk.mac_bytes=52798843
-ndk.mac_checksum=65f2589ac1b08aabe3183f9ed1a8ce8e
+ndk.mac_download=android-ndk-r7-darwin-x86.tar.bz2
+ndk.mac_bytes=71262092
+ndk.mac_checksum=817ca5675a1dd44078098e43070f19b6
 
-ndk.linux_download=android-ndk-r6b-linux-x86.tar.bz2
-ndk.linux_bytes=46532436
-ndk.linux_checksum=309f35e49b64313cfb20ac428df4cec2
+ndk.linux_download=android-ndk-r7-linux-x86.tar.bz2
+ndk.linux_bytes=64884365
+ndk.linux_checksum=bf15e6b47bf50824c4b96849bf003ca3
 
 page.title=Android NDK
+
 @jd:body
 
 <h2 id="notes">Revisions</h2>
@@ -61,6 +62,310 @@
 <div class="toggleable open">
   <a href="#" onclick="return toggleDiv(this)"><img src=
   "{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px">
+  Android NDK, Revision 7</a> <em>(November 2011)</em>
+
+  <div class="toggleme">
+    <p>This release of the NDK includes new features to support the Android 4.0 platform as well
+    as many other additions and improvements:</p>
+
+    <dl>
+      <dt>New features</dt>
+
+      <dd>
+        <ul>
+          <li>Added official NDK APIs for Android 4.0 (API level 14), which adds the following
+          native features to the platform:
+
+            <ul>
+              <li>Added native multimedia API based on the Khronos Group OpenMAX AL™ 1.0.1
+              standard. The new <code>&lt;OMXAL/OpenMAXAL.h&gt;</code> and
+              <code>&lt;OMXAL/OpenMAXAL_Android.h&gt;</code> headers allow applications targeting
+              API level 14 to perform multimedia output directly from native code by using a new
+              Android-specific buffer queue interface. For more details, see
+              <code>docs/openmaxal/index.html</code> and <a href=
+              "http://www.khronos.org/openmax/">http://www.khronos.org/openmax/</a>.</li>
+
+              <li>Updated the native audio API based on the Khronos Group OpenSL ES 1.0.1™
+              standard. With API Level 14, you can now decode compressed audio (e.g. MP3, AAC,
+              Vorbis) to PCM. For more details, see <code>docs/opensles/index.html</code> and
+              <a href=
+              "http://www.khronos.org/opensles">http://www.khronos.org/opensles/</a>.</li>
+            </ul>
+          </li>
+
+          <li>Added CCache support. To speed up large rebuilds, define the
+          <code>NDK_CCACHE</code> environment variable to <code>ccache</code> (or the path to
+          your <code>ccache</code> binary). When declared, the NDK build system automatically
+          uses CCache when compiling any source file. For example:
+            <pre>
+export NDK_CCACHE=ccache
+</pre>
+          <p class="note"><strong>Note:</strong> CCache is not included in the NDK release
+          so you must have it installed prior to using it. For more information about CCache, see
+          <a href="http://ccache.samba.org">http://ccache.samba.org</a>.</p>
+          </li>
+
+          <li>Added support for setting <code>APP_ABI</code> to <code>all</code> to indicate that
+          you want to build your NDK modules for all the ABIs supported by your given NDK
+          release. This means that either one of the following two lines in your
+          <code>Application.mk</code> are equivalent with this release:
+            <pre>
+APP_ABI := all
+APP_ABI := armeabi armeabi-v7a x86
+</pre>
+
+            <p>This also works if you define <code>APP_ABI</code> when calling
+            <code>ndk-build</code> from the command-line, which is a quick way to check that your
+            project builds for all supported ABIs without changing the project's
+            <code>Application.mk file</code>. For example:</p>
+            <pre>
+ndk-build APP_ABI=all
+</pre>
+          </li>
+
+          <li>Added a <code>LOCAL_CPP_FEATURES</code> variable in <code>Android.mk</code> that
+          allows you to declare which C++ features (RTTI or Exceptions) your module uses. This
+          ensures that the final linking works correctly if you have prebuilt modules that depend
+          on these features. See <code>docs/ANDROID-MK.html</code> and
+          <code>docs/CPLUSPLUS-SUPPORT.html</code> for more details.</li>
+
+          <li>Shortened paths to source and object files that are used in build commands. When
+          invoking <code>$NDK/ndk-build</code> from your project path, the paths to the source,
+          object, and binary files that are passed to the build commands are significantly
+          shorter now, because they are passed relative to the current directory. This is useful
+          when building projects with a lot of source files, to avoid limits on the maximum
+          command line length supported by your host operating system. The behavior is unchanged
+          if you invoke <code>ndk-build</code> from a sub-directory of your project tree, or if
+          you define <code>NDK_PROJECT_PATH</code> to point to a specific directory.</li>
+        </ul>
+      </dd>
+
+      <dt>Experimental features</dt>
+
+      <dd>
+        You can now build your NDK source files on Windows <em>without</em> Cygwin by calling the
+        <code>ndk-build.cmd</code> script from the command line from your project path. The
+        script takes exactly the same arguments as the original <code>ndk-build</code> script.
+        The Windows NDK package comes with its own prebuilt binaries for GNU Make, Awk and other
+        tools required by the build. You should not need to install anything else to get a
+        working build system.
+
+        <p class="caution"><strong>Important:</strong> <code>ndk-gdb</code> does not work on
+        Windows, so you still need Cygwin to debug.</p>
+
+        <p>This feature is still experimental, so feel free to try it and report issues on the
+        <a href="http://b.android.com">public bug database</a> or <a href=
+        "http://groups.google.com/group/android-ndk">public forum</a>. All samples and unit tests
+        shipped with the NDK succesfully compile with this feature.</p>
+      </dd>
+
+      <dt>Important bug fixes</dt>
+
+      <dd>
+        <ul>
+          <li>Imported shared libraries are now installed by default to the target installation
+          location (<code>libs/&lt;abi&gt;</code>) if <code>APP_MODULES</code> is not defined in
+          your <code>Application.mk</code>. For example, if a top-level module <code>foo</code>
+          imports a module <code>bar</code>, then both <code>libfoo.so</code> and
+          <code>libbar.so</code> are copied to the install location. Previously, only
+          <code>libfoo.so</code> was copied, unless you listed <code>bar</code> in your
+          <code>APP_MODULES</code> too. If you define <code>APP_MODULES</code> explicitly, the
+          behavior is unchanged.</li>
+
+          <li><code>ndk-gdb</code> now works correctly for activities with multiple categories in
+          their MAIN intent filters.</li>
+
+          <li>Static library imports are now properly transitive. For example, if a top-level
+          module <code>foo</code> imports static library <code>bar</code> that imports static
+          library <code>zoo</code>, the <code>libfoo.so</code> will now be linked against both
+          <code>libbar.a</code> and <code>libzoo.a</code>.</li>
+        </ul>
+      </dd>
+
+      <dt>Other changes</dt>
+
+      <dd>
+        <ul>
+          <li><code>docs/NATIVE-ACTIVITY.HTML</code>: Fixed typo. The minimum API level should be
+          9, not 8 for native activities.</li>
+
+          <li><code>docs/STABLE-APIS.html</code>: Added missing documentation listing EGL as a
+          supported stable API, starting from API level 9.</li>
+
+          <li><code>download-toolchain-sources.sh</code>: Updated to download the toolchain
+          sources from <a href="http://android.googlesource.com">android.googlesource.com</a>,
+          which is the new location for the AOSP servers.</li>
+
+          <li>Added a new C++ support runtime named <code>gabi++</code>. More details about it
+          are available in the updated <code>docs/CPLUSPLUS-SUPPORT.html</code>.</li>
+
+          <li>Added a new C++ support runtime named <code>gnustl_shared</code> that corresponds
+          to the shared library version of GNU libstdc++ v3 (GPLv3 license). See more info at
+          <code>docs/CPLUSPLUS-SUPPORT.html</code></li>
+
+          <li>Added support for RTTI in the STLport C++ runtimes (no support for
+          exceptions).</li>
+
+          <li>Added support for multiple file extensions in <code>LOCAL_CPP_EXTENSION</code>. For
+          example, to compile both <code>foo.cpp</code> and <code>bar.cxx</code> as C++ sources,
+          declare the following:
+            <pre>
+LOCAL_CPP_EXTENSION := .cpp .cxx
+</pre>
+          </li>
+
+          <li>Removed many unwanted exported symbols from the link-time shared system libraries
+          provided by the NDK. This ensures that code generated with the standalone toolchain
+          doesn't risk to accidentally depend on a non-stable ABI symbol (e.g. any libgcc.a
+          symbol that changes each time the toolchain used to build the platform is changed)</li>
+
+          <li>Refreshed the EGL and OpenGLES Khronos headers to support more extensions. Note
+          that this does <em>not</em> change the NDK ABIs for the corresponding libraries,
+          because each extension must be probed at runtime by the client application.
+
+            <p>The extensions that are available depend on your actual device and GPU drivers,
+            not the platform version the device runs on. The header changes simply add new
+            constants and types to make it easier to use the extensions when they have been
+            probed with <code>eglGetProcAddress()</code> or <code>glGetProcAddress()</code>. The
+            following list describes the newly supported extensions:</p>
+
+            <dl>
+              <dt>GLES 1.x</dt>
+
+              <dd>
+                <ul>
+                  <li><code>GL_OES_vertex_array_object</code></li>
+
+                  <li><code>GL_OES_EGL_image_external</code></li>
+
+                  <li><code>GL_APPLE_texture_2D_limited_npot</code></li>
+
+                  <li><code>GL_EXT_blend_minmax</code></li>
+
+                  <li><code>GL_EXT_discard_framebuffer</code></li>
+
+                  <li><code>GL_EXT_multi_draw_arrays</code></li>
+
+                  <li><code>GL_EXT_read_format_bgra</code></li>
+
+                  <li><code>GL_EXT_texture_filter_anisotropic</code></li>
+
+                  <li><code>GL_EXT_texture_format_BGRA8888</code></li>
+
+                  <li><code>GL_EXT_texture_lod_bias</code></li>
+
+                  <li><code>GL_IMG_read_format</code></li>
+
+                  <li><code>GL_IMG_texture_compression_pvrtc</code></li>
+
+                  <li><code>GL_IMG_texture_env_enhanced_fixed_function</code></li>
+
+                  <li><code>GL_IMG_user_clip_plane</code></li>
+
+                  <li><code>GL_IMG_multisampled_render_to_texture</code></li>
+
+                  <li><code>GL_NV_fence</code></li>
+
+                  <li><code>GL_QCOM_driver_control</code></li>
+
+                  <li><code>GL_QCOM_extended_get</code></li>
+
+                  <li><code>GL_QCOM_extended_get2</code></li>
+
+                  <li><code>GL_QCOM_perfmon_global_mode</code></li>
+
+                  <li><code>GL_QCOM_writeonly_rendering</code></li>
+
+                  <li><code>GL_QCOM_tiled_rendering</code></li>
+                </ul>
+              </dd>
+
+              <dt>GLES 2.0</dt>
+
+              <dd>
+                <ul>
+                  <li><code>GL_OES_element_index_uint</code></li>
+
+                  <li><code>GL_OES_get_program_binary</code></li>
+
+                  <li><code>GL_OES_mapbuffer</code></li>
+
+                  <li><code>GL_OES_packed_depth_stencil</code></li>
+
+                  <li><code>GL_OES_texture_3D</code></li>
+
+                  <li><code>GL_OES_texture_float</code></li>
+
+                  <li><code>GL_OES_texture_float_linear</code></li>
+
+                  <li><code>GL_OES_texture_half_float_linear</code></li>
+
+                  <li><code>GL_OES_texture_npot</code></li>
+
+                  <li><code>GL_OES_vertex_array_object</code></li>
+
+                  <li><code>GL_OES_EGL_image_external</code></li>
+
+                  <li><code>GL_AMD_program_binary_Z400</code></li>
+
+                  <li><code>GL_EXT_blend_minmax</code></li>
+
+                  <li><code>GL_EXT_discard_framebuffer</code></li>
+
+                  <li><code>GL_EXT_multi_draw_arrays</code></li>
+
+                  <li><code>GL_EXT_read_format_bgra</code></li>
+
+                  <li><code>GL_EXT_texture_format_BGRA8888</code></li>
+
+                  <li><code>GL_EXT_texture_compression_dxt1</code></li>
+
+                  <li><code>GL_IMG_program_binary</code></li>
+
+                  <li><code>GL_IMG_read_format</code></li>
+
+                  <li><code>GL_IMG_shader_binary</code></li>
+
+                  <li><code>GL_IMG_texture_compression_pvrtc</code></li>
+
+                  <li><code>GL_IMG_multisampled_render_to_texture</code></li>
+
+                  <li><code>GL_NV_coverage_sample</code></li>
+
+                  <li><code>GL_NV_depth_nonlinear</code></li>
+
+                  <li><code>GL_QCOM_extended_get</code></li>
+
+                  <li><code>GL_QCOM_extended_get2</code></li>
+
+                  <li><code>GL_QCOM_writeonly_rendering</code></li>
+
+                  <li><code>GL_QCOM_tiled_rendering</code></li>
+                </ul>
+              </dd>
+
+              <dt>EGL</dt>
+
+              <dd>
+                <ul>
+                  <li><code>EGL_ANDROID_recordable</code></li>
+
+                  <li><code>EGL_NV_system_time</code></li>
+                </ul>
+              </dd>
+            </dl>
+          </li>
+        </ul>
+      </dd>
+    </dl>
+  </div>
+</div>
+
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)"><img src=
+  "{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px">
   Android NDK, Revision 6b</a> <em>(August 2011)</em>
 
    <div class="toggleme">
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 9a18f7da..afe6a6e 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -192,7 +192,8 @@
       <span style="display:none" class="zh-TW"></span>
     </h2>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6b</a>
+      <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r7</a>
+        <span class="new">new!</span>
         </li>
       <li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li>
     </ul>
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index ef4cf5c..7edf6b4 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -644,15 +644,17 @@
     // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
     // set.
     //
-    // If applications call CameraHardwareInterface.autoFocus in this mode, the
-    // focus callback will immediately return with a boolean that indicates
-    // whether the focus is sharp or not. The apps can then decide if they want
-    // to take a picture immediately or to change the focus mode to auto, and
-    // run a full autofocus cycle. The focus position is locked after autoFocus
-    // call. If applications want to resume the continuous focus,
-    // cancelAutoFocus must be called. Restarting the preview will not resume
-    // the continuous autofocus. To stop continuous focus, applications should
-    // change the focus mode to other modes.
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. If
+    // the autofocus is in the middle of scanning, the focus callback will
+    // return when it completes. If the autofocus is not scanning, focus
+    // callback will immediately return with a boolean that indicates whether
+    // the focus is sharp or not. The apps can then decide if they want to take
+    // a picture immediately or to change the focus mode to auto, and run a full
+    // autofocus cycle. The focus position is locked after autoFocus call. If
+    // applications want to resume the continuous focus, cancelAutoFocus must be
+    // called. Restarting the preview will not resume the continuous autofocus.
+    // To stop continuous focus, applications should change the focus mode to
+    // other modes.
     static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
 
 private:
diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp
index 1b85a71..60681c4 100644
--- a/libs/binder/CursorWindow.cpp
+++ b/libs/binder/CursorWindow.cpp
@@ -211,7 +211,7 @@
     uint32_t offset = mHeader->freeOffset + padding;
     uint32_t nextFreeOffset = offset + size;
     if (nextFreeOffset > mSize) {
-        LOGE("Window is full: requested allocation %d bytes, "
+        LOGW("Window is full: requested allocation %d bytes, "
                 "free space %d bytes, window size %d bytes",
                 size, freeSpace(), mSize);
         return 0;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 948ecf9..5291a1f 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -359,6 +359,7 @@
     mTargetSdkVersion = 14;
     mDPI = 96;
     mIsContextLite = false;
+    memset(&watchdog, 0, sizeof(watchdog));
 }
 
 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 07e347e..61a7ba4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -379,7 +379,7 @@
         LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
     }
 
-    entry->mNotifyConsumed->setInt32("render", true);
+    entry->mNotifyConsumed->setInt32("render", !tooLate);
     entry->mNotifyConsumed->post();
     mVideoQueue.erase(mVideoQueue.begin());
     entry = NULL;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 2e1803e..2be35b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -118,15 +118,20 @@
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.OPAQUE);
+                // We use a pixel format of RGB565 for the status bar to save memory bandwidth and
+                // to ensure that the layer can be handled by HWComposer.  On some devices the
+                // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
+                PixelFormat.RGB_565);
         
         // the status bar should be in an overlay if possible
         final Display defaultDisplay 
             = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
-        if (ActivityManager.isHighEndGfx(defaultDisplay)) {
-            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-        }
+
+        // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
+        // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
+        // for the status bar, we prevent the GPU from having to wake up just to do these small
+        // updates, which should help keep power consumption down.
 
         lp.gravity = getStatusBarGravity();
         lp.setTitle("StatusBar");
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 81e1901..0f21bdb 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -360,8 +360,7 @@
                 mHasOverlay = true;
 
                 // Continue showing FaceLock area until dialer comes up or call is resumed
-                if (mLockPatternUtils.usingBiometricWeak() &&
-                        mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) {
+                if (usingFaceLock() && mFaceLockServiceRunning) {
                     showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
                 }
 
@@ -582,8 +581,7 @@
             bindToFaceLock();
             // Show FaceLock area, but only for a little bit so lockpattern will become visible if
             // FaceLock fails to start or crashes
-            if (mLockPatternUtils.usingBiometricWeak() &&
-                    mLockPatternUtils.isBiometricWeakInstalled()) {
+            if (usingFaceLock()) {
                 showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
             }
         } else {
@@ -653,11 +651,10 @@
             ((KeyguardScreen) mUnlockScreen).onResume();
         }
 
-        if (mLockPatternUtils.usingBiometricWeak() &&
-            mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
+        if (usingFaceLock() && !mHasOverlay) {
             // Note that show() gets called before the screen turns off to set it up for next time
             // it is turned on.  We don't want to set a timeout on the FaceLock area here because it
-            // may be gone by the time the screen is turned on again.  We set the timout when the
+            // may be gone by the time the screen is turned on again.  We set the timeout when the
             // screen turns on instead.
             showFaceLockArea();
         } else {
@@ -854,7 +851,9 @@
         if (mode == Mode.UnlockScreen) {
             final UnlockMode unlockMode = getUnlockMode();
             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
+                boolean restartFaceLock = stopFaceLockIfRunning();
                 recreateUnlockScreen(unlockMode);
+                if (restartFaceLock) activateFaceLockIfAble();
             }
         }
 
@@ -1147,28 +1146,33 @@
 
     // Everything below pertains to FaceLock - might want to separate this out
 
-    // Take care of FaceLock area when layout is created
+    // Indicates whether FaceLock is in use
+    private boolean usingFaceLock() {
+        return (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled());
+    }
+
+    // Takes care of FaceLock area when layout is created
     private void initializeFaceLockAreaView(View view) {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
             if (mFaceLockAreaView == null) {
                 Log.e(TAG, "Layout does not have faceLockAreaView and FaceLock is enabled");
-            } else {
-                if (mBoundToFaceLockService) {
-                    // If we are creating a layout when we are already bound to FaceLock, then we
-                    // are undergoing an orientation change.  Stop FaceLock and restart it in the
-                    // new location.
-                    if (DEBUG) Log.d(TAG, "Restarting FL - creating view while already bound");
-                    stopAndUnbindFromFaceLock();
-                    activateFaceLockIfAble();
-                }
             }
         } else {
             mFaceLockAreaView = null; // Set to null if not using FaceLock
         }
     }
 
+    // Stops FaceLock if it is running and reports back whether it was running or not
+    private boolean stopFaceLockIfRunning() {
+        if (usingFaceLock() && mBoundToFaceLockService) {
+            stopAndUnbindFromFaceLock();
+            return true;
+        }
+        return false;
+    }
+
     // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
     // This needs to be done in a handler because the call could be coming from a callback from the
     // FaceLock service that is in a thread that can't modify the UI
@@ -1221,8 +1225,7 @@
     // Binds to FaceLock service.  This call does not tell it to start, but it causes the service
     // to call the onServiceConnected callback, which then starts FaceLock.
     public void bindToFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             if (!mBoundToFaceLockService) {
                 if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
                 mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1238,8 +1241,7 @@
 
     // Tells FaceLock to stop and then unbinds from the FaceLock service
     public void stopAndUnbindFromFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             stopFaceLock();
 
             if (mBoundToFaceLockService) {
@@ -1300,8 +1302,7 @@
     // Tells the FaceLock service to start displaying its UI and perform recognition
     public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
     {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             synchronized (mFaceLockServiceRunningLock) {
                 if (!mFaceLockServiceRunning) {
                     if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1322,8 +1323,7 @@
     // Tells the FaceLock service to stop displaying its UI and stop recognition
     public void stopFaceLock()
     {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             // Note that attempting to stop FaceLock when it's not running is not an issue.
             // FaceLock can return, which stops it and then we try to stop it when the
             // screen is turned off.  That's why we check.
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 851cb33..8c42f31 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -171,6 +171,12 @@
     private static final int ENABLED  = 1;
     private static final int DISABLED = 0;
 
+    private static final boolean ADD = true;
+    private static final boolean REMOVE = false;
+
+    private static final boolean TO_DEFAULT_TABLE = true;
+    private static final boolean TO_SECONDARY_TABLE = false;
+
     // Share the event space with NetworkStateTracker (which can't see this
     // internal class but sends us events).  If you change these, change
     // NetworkStateTracker.java too.
@@ -501,7 +507,7 @@
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
 
-        mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
+        mTethering = new Tethering(mContext, nmService, statsService, this, mHandler.getLooper());
         mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
                                   mTethering.getTetherableWifiRegexs().length != 0 ||
                                   mTethering.getTetherableBluetoothRegexs().length != 0) &&
@@ -1146,23 +1152,24 @@
         return false;
     }
 
-    private boolean addRoute(LinkProperties p, RouteInfo r) {
-        return modifyRoute(p.getInterfaceName(), p, r, 0, true);
+    private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
+        return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable);
     }
 
-    private boolean removeRoute(LinkProperties p, RouteInfo r) {
-        return modifyRoute(p.getInterfaceName(), p, r, 0, false);
+    private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
+        return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable);
     }
 
     private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, true);
+        return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE);
     }
 
     private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, false);
+        return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE);
     }
 
-    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
+    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
+            boolean toDefaultTable) {
         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
         if (bestRoute == null) {
             bestRoute = RouteInfo.makeHostRoute(addr);
@@ -1176,15 +1183,15 @@
                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
             }
         }
-        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
+        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable);
     }
 
     private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
-            boolean doAdd) {
+            boolean doAdd, boolean toDefaultTable) {
         if ((ifaceName == null) || (lp == null) || (r == null)) return false;
 
         if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
-            loge("Error adding route - too much recursion");
+            loge("Error modifying route - too much recursion");
             return false;
         }
 
@@ -1199,14 +1206,18 @@
                     // route to it's gateway
                     bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
                 }
-                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
+                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable);
             }
         }
         if (doAdd) {
             if (VDBG) log("Adding " + r + " for interface " + ifaceName);
-            mAddedRoutes.add(r);
             try {
-                mNetd.addRoute(ifaceName, r);
+                if (toDefaultTable) {
+                    mAddedRoutes.add(r);  // only track default table - only one apps can effect
+                    mNetd.addRoute(ifaceName, r);
+                } else {
+                    mNetd.addSecondaryRoute(ifaceName, r);
+                }
             } catch (Exception e) {
                 // never crash - catch them all
                 if (VDBG) loge("Exception trying to add a route: " + e);
@@ -1215,18 +1226,29 @@
         } else {
             // if we remove this one and there are no more like it, then refcount==0 and
             // we can remove it from the table
-            mAddedRoutes.remove(r);
-            if (mAddedRoutes.contains(r) == false) {
+            if (toDefaultTable) {
+                mAddedRoutes.remove(r);
+                if (mAddedRoutes.contains(r) == false) {
+                    if (VDBG) log("Removing " + r + " for interface " + ifaceName);
+                    try {
+                        mNetd.removeRoute(ifaceName, r);
+                    } catch (Exception e) {
+                        // never crash - catch them all
+                        if (VDBG) loge("Exception trying to remove a route: " + e);
+                        return false;
+                    }
+                } else {
+                    if (VDBG) log("not removing " + r + " as it's still in use");
+                }
+            } else {
                 if (VDBG) log("Removing " + r + " for interface " + ifaceName);
                 try {
-                    mNetd.removeRoute(ifaceName, r);
+                    mNetd.removeSecondaryRoute(ifaceName, r);
                 } catch (Exception e) {
                     // never crash - catch them all
                     if (VDBG) loge("Exception trying to remove a route: " + e);
                     return false;
                 }
-            } else {
-                if (VDBG) log("not removing " + r + " as it's still in use");
             }
         }
         return true;
@@ -1862,14 +1884,21 @@
 
         for (RouteInfo r : routeDiff.removed) {
             if (isLinkDefault || ! r.isDefaultRoute()) {
-                removeRoute(curLp, r);
+                removeRoute(curLp, r, TO_DEFAULT_TABLE);
+            }
+            if (isLinkDefault == false) {
+                // remove from a secondary route table
+                removeRoute(curLp, r, TO_SECONDARY_TABLE);
             }
         }
 
         for (RouteInfo r :  routeDiff.added) {
             if (isLinkDefault || ! r.isDefaultRoute()) {
-                addRoute(newLp, r);
+                addRoute(newLp, r, TO_DEFAULT_TABLE);
             } else {
+                // add to a secondary route table
+                addRoute(newLp, r, TO_SECONDARY_TABLE);
+
                 // many radios add a default route even when we don't want one.
                 // remove the default route unless somebody else has asked for it
                 String ifaceName = newLp.getInterfaceName();
@@ -2450,12 +2479,6 @@
         int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
         boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
-        // Short term disabling of Tethering if DUN is required.
-        // TODO - fix multi-connection tethering using policy-base routing
-        int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes();
-        for (int i : upstreamConnTypes) {
-            if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false;
-        }
         return tetherEnabledInSettings && mTetheringConfigValid;
     }
 
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index fb13b75..4c26dbb 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -59,7 +59,11 @@
 import java.io.PrintWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
@@ -77,6 +81,9 @@
     private static final int ADD = 1;
     private static final int REMOVE = 2;
 
+    private static final String DEFAULT = "default";
+    private static final String SECONDARY = "secondary";
+
     /**
      * Name representing {@link #setGlobalAlert(long)} limit when delivered to
      * {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -500,15 +507,25 @@
 
     public void addRoute(String interfaceName, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        modifyRoute(interfaceName, ADD, route);
+        modifyRoute(interfaceName, ADD, route, DEFAULT);
     }
 
     public void removeRoute(String interfaceName, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        modifyRoute(interfaceName, REMOVE, route);
+        modifyRoute(interfaceName, REMOVE, route, DEFAULT);
     }
 
-    private void modifyRoute(String interfaceName, int action, RouteInfo route) {
+    public void addSecondaryRoute(String interfaceName, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+        modifyRoute(interfaceName, ADD, route, SECONDARY);
+    }
+
+    public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+        modifyRoute(interfaceName, REMOVE, route, SECONDARY);
+    }
+
+    private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) {
         ArrayList<String> rsp;
 
         StringBuilder cmd;
@@ -516,12 +533,12 @@
         switch (action) {
             case ADD:
             {
-                cmd = new StringBuilder("interface route add " + interfaceName);
+                cmd = new StringBuilder("interface route add " + interfaceName + " " + type);
                 break;
             }
             case REMOVE:
             {
-                cmd = new StringBuilder("interface route remove " + interfaceName);
+                cmd = new StringBuilder("interface route remove " + interfaceName + " " + type);
                 break;
             }
             default:
@@ -828,14 +845,33 @@
         }
     }
 
+    private void modifyNat(String cmd, String internalInterface, String externalInterface)
+            throws SocketException {
+        cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface);
+
+        NetworkInterface internalNetworkInterface =
+                NetworkInterface.getByName(internalInterface);
+        Collection<InterfaceAddress>interfaceAddresses =
+                internalNetworkInterface.getInterfaceAddresses();
+        cmd += " " + interfaceAddresses.size();
+        for (InterfaceAddress ia : interfaceAddresses) {
+            InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
+                    ia.getNetworkPrefixLength());
+            cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+        }
+
+        mConnector.doCommand(cmd);
+    }
+
     public void enableNat(String internalInterface, String externalInterface)
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
-            mConnector.doCommand(
-                    String.format("nat enable %s %s", internalInterface, externalInterface));
-        } catch (NativeDaemonConnectorException e) {
+            modifyNat("enable", internalInterface, externalInterface);
+        } catch (Exception e) {
+            Log.e(TAG, "enableNat got Exception " + e.toString());
             throw new IllegalStateException(
                     "Unable to communicate to native daemon for enabling NAT interface");
         }
@@ -845,10 +881,11 @@
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
-            mConnector.doCommand(
-                    String.format("nat disable %s %s", internalInterface, externalInterface));
-        } catch (NativeDaemonConnectorException e) {
+            modifyNat("disable", internalInterface, externalInterface);
+        } catch (Exception e) {
+            Log.e(TAG, "disableNat got Exception " + e.toString());
             throw new IllegalStateException(
                     "Unable to communicate to native daemon for disabling NAT interface");
         }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0d6f405..2a867af 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -120,6 +120,7 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -128,8 +129,10 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.lang.IllegalStateException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -844,9 +847,11 @@
     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
     static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
     static final int DISPATCH_PROCESS_DIED = 32;
+    static final int REPORT_MEM_USAGE = 33;
 
     AlertDialog mUidAlert;
     CompatModeDialog mCompatModeDialog;
+    long mLastMemUsageReportTime = 0;
 
     final Handler mHandler = new Handler() {
         //public Handler() {
@@ -1186,6 +1191,56 @@
                 dispatchProcessDied(pid, uid);
                 break;
             }
+            case REPORT_MEM_USAGE: {
+                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+                if (!isDebuggable) {
+                    return;
+                }
+                synchronized (ActivityManagerService.this) {
+                    long now = SystemClock.uptimeMillis();
+                    if (now < (mLastMemUsageReportTime+10000)) {
+                        // Don't report more than every 10 seconds to somewhat
+                        // avoid spamming.
+                        return;
+                    }
+                    mLastMemUsageReportTime = now;
+                }
+                Thread thread = new Thread() {
+                    @Override public void run() {
+                        try {
+                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
+                                    "procrank", });
+                            final InputStreamReader converter = new InputStreamReader(
+                                    proc.getInputStream());
+                            BufferedReader in = new BufferedReader(converter);
+                            String line;
+                            while (true) {
+                                line = in.readLine();
+                                if (line == null) {
+                                    break;
+                                }
+                                if (line.length() > 0) {
+                                    Slog.i(TAG, line);
+                                }
+                            }
+                            converter.close();
+                        } catch (IOException e) {
+                        }
+                        StringWriter sw = new StringWriter();
+                        PrintWriter pw = new PrintWriter(sw);
+                        dumpApplicationMemoryUsage(null, pw, "  ", new String[] { }, true);
+                        Slog.i(TAG, sw.toString());
+                        synchronized (ActivityManagerService.this) {
+                            long now = SystemClock.uptimeMillis();
+                            if (mLastMemUsageReportTime < now) {
+                                mLastMemUsageReportTime = now;
+                            }
+                        }
+                    }
+                };
+                thread.start();
+                break;
+            }
             }
         }
     };
@@ -1326,7 +1381,7 @@
                 return;
             }
 
-            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
+            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false);
         }
     }
 
@@ -2755,6 +2810,7 @@
                             addProcessToGcListLocked(rec);
                         }
                     }
+                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
                     scheduleAppGcsLocked();
                 }
             }
@@ -9216,7 +9272,7 @@
     }
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
-            PrintWriter pw, String prefix, String[] args) {
+            PrintWriter pw, String prefix, String[] args, boolean brief) {
         boolean dumpAll = false;
         
         int opti = 0;
@@ -9354,15 +9410,19 @@
                 }
             }
 
-            pw.println();
-            pw.println("Total PSS by process:");
-            dumpMemItems(pw, "  ", procMems, true);
-            pw.println();
+            if (!brief) {
+                pw.println();
+                pw.println("Total PSS by process:");
+                dumpMemItems(pw, "  ", procMems, true);
+                pw.println();
+            }
             pw.println("Total PSS by OOM adjustment:");
             dumpMemItems(pw, "  ", oomMems, false);
-            pw.println();
-            pw.println("Total PSS by category:");
-            dumpMemItems(pw, "  ", catMems, true);
+            if (!brief) {
+                pw.println();
+                pw.println("Total PSS by category:");
+                dumpMemItems(pw, "  ", catMems, true);
+            }
             pw.println();
             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
         }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 7bd29d9..423a78f 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -81,6 +81,9 @@
     private String[] mTetherableBluetoothRegexs;
     private Collection<Integer> mUpstreamIfaceTypes;
 
+    // used to synchronize public access to members
+    private Object mPublicSync;
+
     private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE);
     private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI);
     private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN);
@@ -91,6 +94,7 @@
 
     private final INetworkManagementService mNMService;
     private final INetworkStatsService mStatsService;
+    private final IConnectivityManager mConnService;
     private Looper mLooper;
     private HandlerThread mThread;
 
@@ -127,12 +131,15 @@
                                          // when RNDIS is enabled
 
     public Tethering(Context context, INetworkManagementService nmService,
-            INetworkStatsService statsService, Looper looper) {
+            INetworkStatsService statsService, IConnectivityManager connService, Looper looper) {
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
+        mConnService = connService;
         mLooper = looper;
 
+        mPublicSync = new Object();
+
         mIfaces = new HashMap<String, TetherInterfaceSM>();
 
         // make our own thread so we don't anr the system
@@ -170,18 +177,25 @@
     }
 
     void updateConfiguration() {
-        mTetherableUsbRegexs = mContext.getResources().getStringArray(
+        String[] tetherableUsbRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_usb_regexs);
-        mTetherableWifiRegexs = mContext.getResources().getStringArray(
+        String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_wifi_regexs);
-        mTetherableBluetoothRegexs = mContext.getResources().getStringArray(
+        String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_bluetooth_regexs);
 
         int ifaceTypes[] = mContext.getResources().getIntArray(
                 com.android.internal.R.array.config_tether_upstream_types);
-        mUpstreamIfaceTypes = new ArrayList();
+        Collection<Integer> upstreamIfaceTypes = new ArrayList();
         for (int i : ifaceTypes) {
-            mUpstreamIfaceTypes.add(new Integer(i));
+            upstreamIfaceTypes.add(new Integer(i));
+        }
+
+        synchronized (mPublicSync) {
+            mTetherableUsbRegexs = tetherableUsbRegexs;
+            mTetherableWifiRegexs = tetherableWifiRegexs;
+            mTetherableBluetoothRegexs = tetherableBluetoothRegexs;
+            mUpstreamIfaceTypes = upstreamIfaceTypes;
         }
 
         // check if the upstream type list needs to be modified due to secure-settings
@@ -192,17 +206,17 @@
         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
         boolean found = false;
         boolean usb = false;
-        if (isWifi(iface)) {
-            found = true;
-        } else if (isUsb(iface)) {
-            found = true;
-            usb = true;
-        } else if (isBluetooth(iface)) {
-            found = true;
-        }
-        if (found == false) return;
+        synchronized (mPublicSync) {
+            if (isWifi(iface)) {
+                found = true;
+            } else if (isUsb(iface)) {
+                found = true;
+                usb = true;
+            } else if (isBluetooth(iface)) {
+                found = true;
+            }
+            if (found == false) return;
 
-        synchronized (mIfaces) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (up) {
                 if (sm == null) {
@@ -229,46 +243,52 @@
     }
 
     private boolean isUsb(String iface) {
-        for (String regex : mTetherableUsbRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableUsbRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public boolean isWifi(String iface) {
-        for (String regex : mTetherableWifiRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableWifiRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public boolean isBluetooth(String iface) {
-        for (String regex : mTetherableBluetoothRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableBluetoothRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public void interfaceAdded(String iface) {
         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
         boolean found = false;
         boolean usb = false;
-        if (isWifi(iface)) {
-            found = true;
-        }
-        if (isUsb(iface)) {
-            found = true;
-            usb = true;
-        }
-        if (isBluetooth(iface)) {
-            found = true;
-        }
-        if (found == false) {
-            if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
-            return;
-        }
+        synchronized (mPublicSync) {
+            if (isWifi(iface)) {
+                found = true;
+            }
+            if (isUsb(iface)) {
+                found = true;
+                usb = true;
+            }
+            if (isBluetooth(iface)) {
+                found = true;
+            }
+            if (found == false) {
+                if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
+                return;
+            }
 
-        synchronized (mIfaces) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (sm != null) {
                 if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
@@ -283,7 +303,7 @@
 
     public void interfaceRemoved(String iface) {
         if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (sm == null) {
                 if (VDBG) {
@@ -301,7 +321,7 @@
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
         }
         if (sm == null) {
@@ -319,7 +339,7 @@
     public int untether(String iface) {
         if (DBG) Log.d(TAG, "Untethering " + iface);
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
         }
         if (sm == null) {
@@ -336,21 +356,22 @@
 
     public int getLastTetherError(String iface) {
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
+            if (sm == null) {
+                Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
+                        ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
+            }
+            return sm.getLastError();
         }
-        if (sm == null) {
-            Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
-        }
-        return sm.getLastError();
     }
 
+    // TODO - move all private methods used only by the state machine into the state machine
+    // to clarify what needs synchronized protection.
     private void sendTetherStateChangedBroadcast() {
-        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-        IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
         try {
-            if (!cm.isTetheringSupported()) return;
+            if (!mConnService.isTetheringSupported()) return;
         } catch (RemoteException e) {
             return;
         }
@@ -363,7 +384,7 @@
         boolean usbTethered = false;
         boolean bluetoothTethered = false;
 
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set ifaces = mIfaces.keySet();
             for (Object iface : ifaces) {
                 TetherInterfaceSM sm = mIfaces.get(iface);
@@ -469,7 +490,7 @@
         public void onReceive(Context content, Intent intent) {
             String action = intent.getAction();
             if (action.equals(UsbManager.ACTION_USB_STATE)) {
-                synchronized (Tethering.this) {
+                synchronized (Tethering.this.mPublicSync) {
                     boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
                     mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
                     // start tethering if we have a request pending
@@ -545,6 +566,7 @@
         return true;
     }
 
+    // TODO - return copies so people can't tamper
     public String[] getTetherableUsbRegexs() {
         return mTetherableUsbRegexs;
     }
@@ -561,7 +583,7 @@
         if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
         UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
 
-        synchronized (this) {
+        synchronized (mPublicSync) {
             if (enable) {
                 if (mRndisEnabled) {
                     tetherUsb(true);
@@ -581,11 +603,14 @@
     }
 
     public int[] getUpstreamIfaceTypes() {
-        updateConfiguration();
-        int values[] = new int[mUpstreamIfaceTypes.size()];
-        Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
-        for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
-            values[i] = iterator.next();
+        int values[];
+        synchronized (mPublicSync) {
+            updateConfiguration();
+            values = new int[mUpstreamIfaceTypes.size()];
+            Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
+            for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
+                values[i] = iterator.next();
+            }
         }
         return values;
     }
@@ -593,43 +618,46 @@
     public void checkDunRequired() {
         int secureSetting = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.TETHER_DUN_REQUIRED, 2);
-        // 2 = not set, 0 = DUN not required, 1 = DUN required
-        if (secureSetting != 2) {
-            int requiredApn = (secureSetting == 1 ?
-                    ConnectivityManager.TYPE_MOBILE_DUN :
-                    ConnectivityManager.TYPE_MOBILE_HIPRI);
-            if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
-                while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
-                    mUpstreamIfaceTypes.remove(MOBILE_TYPE);
-                }
-                while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
-                    mUpstreamIfaceTypes.remove(HIPRI_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(DUN_TYPE);
-                }
-            } else {
-                while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
-                    mUpstreamIfaceTypes.remove(DUN_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(MOBILE_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(HIPRI_TYPE);
+        synchronized (mPublicSync) {
+            // 2 = not set, 0 = DUN not required, 1 = DUN required
+            if (secureSetting != 2) {
+                int requiredApn = (secureSetting == 1 ?
+                        ConnectivityManager.TYPE_MOBILE_DUN :
+                        ConnectivityManager.TYPE_MOBILE_HIPRI);
+                if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
+                    while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
+                        mUpstreamIfaceTypes.remove(MOBILE_TYPE);
+                    }
+                    while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
+                        mUpstreamIfaceTypes.remove(HIPRI_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(DUN_TYPE);
+                    }
+                } else {
+                    while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+                        mUpstreamIfaceTypes.remove(DUN_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(MOBILE_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(HIPRI_TYPE);
+                    }
                 }
             }
-        }
-        if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
-            mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
-        } else {
-            mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+            if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+                mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
+            } else {
+                mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+            }
         }
     }
 
+    // TODO review API - maybe return ArrayList<String> here and below?
     public String[] getTetheredIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -647,7 +675,7 @@
 
     public String[] getTetheredIfacePairs() {
         final ArrayList<String> list = Lists.newArrayList();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             for (TetherInterfaceSM sm : mIfaces.values()) {
                 if (sm.isTethered()) {
                     list.add(sm.mMyUpstreamIfaceName);
@@ -660,7 +688,7 @@
 
     public String[] getTetherableIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -678,7 +706,7 @@
 
     public String[] getErroredIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -777,43 +805,54 @@
             return res;
         }
 
-        public synchronized int getLastError() {
-            return mLastError;
+        public int getLastError() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mLastError;
+            }
         }
 
-        private synchronized void setLastError(int error) {
-            mLastError = error;
+        private void setLastError(int error) {
+            synchronized (Tethering.this.mPublicSync) {
+                mLastError = error;
 
-            if (isErrored()) {
-                if (mUsb) {
-                    // note everything's been unwound by this point so nothing to do on
-                    // further error..
-                    Tethering.this.configureUsbIface(false);
+                if (isErrored()) {
+                    if (mUsb) {
+                        // note everything's been unwound by this point so nothing to do on
+                        // further error..
+                        Tethering.this.configureUsbIface(false);
+                    }
                 }
             }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isAvailable() {
-            return mAvailable;
+        public boolean isAvailable() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mAvailable;
+            }
         }
 
-        private synchronized void setAvailable(boolean available) {
-            mAvailable = available;
+        private void setAvailable(boolean available) {
+            synchronized (Tethering.this.mPublicSync) {
+                mAvailable = available;
+            }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isTethered() {
-            return mTethered;
+        public boolean isTethered() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mTethered;
+            }
         }
 
-        private synchronized void setTethered(boolean tethered) {
-            mTethered = tethered;
+        private void setTethered(boolean tethered) {
+            synchronized (Tethering.this.mPublicSync) {
+                mTethered = tethered;
+            }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isErrored() {
-            return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+        public boolean isErrored() {
+            synchronized (Tethering.this.mPublicSync) {
+                return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+            }
         }
 
         class InitialState extends State {
@@ -910,6 +949,7 @@
                 try {
                     mNMService.tetherInterface(mIfaceName);
                 } catch (Exception e) {
+                    Log.e(TAG, "Error Tethering: " + e.toString());
                     setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR);
 
                     transitionTo(mInitialState);
@@ -921,7 +961,7 @@
                 sendTetherStateChangedBroadcast();
             }
 
-            void cleanupUpstream() {
+            private void cleanupUpstream() {
                 if (mMyUpstreamIfaceName != null) {
                     // note that we don't care about errors here.
                     // sometimes interfaces are gone before we get
@@ -987,6 +1027,7 @@
                             try {
                                 mNMService.enableNat(mIfaceName, newUpstreamIfaceName);
                             } catch (Exception e) {
+                                Log.e(TAG, "Exception enabling Nat: " + e.toString());
                                 try {
                                     mNMService.untetherInterface(mIfaceName);
                                 } catch (Exception ee) {}
@@ -1150,13 +1191,11 @@
                 boolean retValue = true;
                 if (apnType == ConnectivityManager.TYPE_NONE) return false;
                 if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
-                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                 int result = Phone.APN_REQUEST_FAILED;
                 String enableString = enableString(apnType);
                 if (enableString == null) return false;
                 try {
-                    result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                    result = mConnService.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                             enableString, new Binder());
                 } catch (Exception e) {
                 }
@@ -1178,10 +1217,8 @@
             }
             protected boolean turnOffUpstreamMobileConnection() {
                 if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) {
-                    IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                    IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                     try {
-                        cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                        mConnService.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                                 enableString(mMobileApnReserved));
                     } catch (Exception e) {
                         return false;
@@ -1234,28 +1271,28 @@
             }
 
             protected void chooseUpstreamType(boolean tryCell) {
-                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                 int upType = ConnectivityManager.TYPE_NONE;
                 String iface = null;
 
                 updateConfiguration();
 
-                if (VDBG) {
-                    Log.d(TAG, "chooseUpstreamType has upstream iface types:");
-                    for (Integer netType : mUpstreamIfaceTypes) {
-                        Log.d(TAG, " " + netType);
+                synchronized (mPublicSync) {
+                    if (VDBG) {
+                        Log.d(TAG, "chooseUpstreamType has upstream iface types:");
+                        for (Integer netType : mUpstreamIfaceTypes) {
+                            Log.d(TAG, " " + netType);
+                        }
                     }
-                }
 
-                for (Integer netType : mUpstreamIfaceTypes) {
-                    NetworkInfo info = null;
-                    try {
-                        info = cm.getNetworkInfo(netType.intValue());
-                    } catch (RemoteException e) { }
-                    if ((info != null) && info.isConnected()) {
-                        upType = netType.intValue();
-                        break;
+                    for (Integer netType : mUpstreamIfaceTypes) {
+                        NetworkInfo info = null;
+                        try {
+                            info = mConnService.getNetworkInfo(netType.intValue());
+                        } catch (RemoteException e) { }
+                        if ((info != null) && info.isConnected()) {
+                            upType = netType.intValue();
+                            break;
+                        }
                     }
                 }
 
@@ -1283,7 +1320,7 @@
                 } else {
                     LinkProperties linkProperties = null;
                     try {
-                        linkProperties = cm.getLinkProperties(upType);
+                        linkProperties = mConnService.getLinkProperties(upType);
                     } catch (RemoteException e) { }
                     if (linkProperties != null) iface = linkProperties.getInterfaceName();
                 }
@@ -1483,14 +1520,14 @@
                     return;
         }
 
-        pw.println("mUpstreamIfaceTypes: ");
-        for (Integer netType : mUpstreamIfaceTypes) {
-            pw.println(" " + netType);
-        }
+        synchronized (mPublicSync) {
+            pw.println("mUpstreamIfaceTypes: ");
+            for (Integer netType : mUpstreamIfaceTypes) {
+                pw.println(" " + netType);
+            }
 
-        pw.println();
-        pw.println("Tether state:");
-        synchronized (mIfaces) {
+            pw.println();
+            pw.println("Tether state:");
             for (Object o : mIfaces.values()) {
                 pw.println(" "+o.toString());
             }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index a199a7e..122d515 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8660,7 +8660,8 @@
         if (needRelayout) {
             requestAnimationLocked(0);
         } else if (animating) {
-            requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
+            final int refreshTimeUs = (int)(1000 / mDisplay.getRefreshRate());
+            requestAnimationLocked(currentTime + refreshTimeUs - SystemClock.uptimeMillis());
         }
 
         // Finally update all input windows now that the window changes have stabilized.
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index b9f2c1f..2ceb535 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -141,10 +141,10 @@
         return -1;
     }
     
-    size_t count = read(fd, buf, size);
+    ssize_t count = read(fd, buf, size);
     if (count > 0) {
-        count = (count < size) ? count : size - 1;
-        while (count > 0 && buf[count-1] == '\n') count--;
+        while (count > 0 && buf[count-1] == '\n')
+            count--;
         buf[count] = '\0';
     } else {
         buf[0] = '\0';
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 61a8358..53502db 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -30,6 +30,10 @@
 	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
 endif
 
+ifneq (,$(findstring $(TARGET_DEVICE),tuna toro maguro))
+	LOCAL_CFLAGS += -DREFRESH_RATE=59
+endif
+
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f4be168..329c052 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -141,6 +141,17 @@
     mDpiY = mNativeWindow->ydpi;
     mRefreshRate = fbDev->fps;
 
+
+/* FIXME: this is a temporary HACK until we are able to report the refresh rate
+ * properly from the HAL. The WindowManagerService now relies on this value.
+ */
+#ifndef REFRESH_RATE
+    mRefreshRate = fbDev->fps;
+#else
+    mRefreshRate = REFRESH_RATE;
+#warning "refresh rate set via makefile to REFRESH_RATE"
+#endif
+
     EGLint w, h, dummy;
     EGLint numConfigs=0;
     EGLSurface surface;
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 34f8848..f2ccb5b 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1513,14 +1513,65 @@
     static final int MIN_MATCH = 7;
 
     /**
-     * isEmergencyNumber: checks a given number against the list of
-     *   emergency numbers provided by the RIL and SIM card.
+     * Checks a given number against the list of
+     * emergency numbers provided by the RIL and SIM card.
      *
      * @param number the number to look up.
-     * @return if the number is in the list of emergency numbers
-     * listed in the ril / sim, then return true, otherwise false.
+     * @return true if the number is in the list of emergency numbers
+     *         listed in the RIL / SIM, otherwise return false.
      */
     public static boolean isEmergencyNumber(String number) {
+        // Return true only if the specified number *exactly* matches
+        // one of the emergency numbers listed by the RIL / SIM.
+        return isEmergencyNumberInternal(number, true /* useExactMatch */);
+    }
+
+    /**
+     * Checks if given number might *potentially* result in
+     * a call to an emergency service on the current network.
+     *
+     * Specifically, this method will return true if the specified number
+     * is an emergency number according to the list managed by the RIL or
+     * SIM, *or* if the specified number simply starts with the same
+     * digits as any of the emergency numbers listed in the RIL / SIM.
+     *
+     * This method is intended for internal use by the phone app when
+     * deciding whether to allow ACTION_CALL intents from 3rd party apps
+     * (where we're required to *not* allow emergency calls to be placed.)
+     *
+     * @param number the number to look up.
+     * @return true if the number is in the list of emergency numbers
+     *         listed in the RIL / SIM, *or* if the number starts with the
+     *         same digits as any of those emergency numbers.
+     *
+     * @hide
+     */
+    public static boolean isPotentialEmergencyNumber(String number) {
+        // Check against the emergency numbers listed by the RIL / SIM,
+        // and *don't* require an exact match.
+        return isEmergencyNumberInternal(number, false /* useExactMatch */);
+    }
+
+    /**
+     * Helper function for isEmergencyNumber(String) and
+     * isPotentialEmergencyNumber(String).
+     *
+     * @param number the number to look up.
+     *
+     * @param useExactMatch if true, consider a number to be an emergency
+     *           number only if it *exactly* matches a number listed in
+     *           the RIL / SIM.  If false, a number is considered to be an
+     *           emergency number if it simply starts with the same digits
+     *           as any of the emergency numbers listed in the RIL / SIM.
+     *           (Setting useExactMatch to false allows you to identify
+     *           number that could *potentially* result in emergency calls
+     *           since many networks will actually ignore trailing digits
+     *           after a valid emergency number.)
+     *
+     * @return true if the number is in the list of emergency numbers
+     *         listed in the RIL / sim, otherwise return false.
+     */
+    private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) {
         // If the number passed in is null, just return false:
         if (number == null) return false;
 
@@ -1540,16 +1591,26 @@
             // searches through the comma-separated list for a match,
             // return true if one is found.
             for (String emergencyNum : numbers.split(",")) {
-                if (number.startsWith(emergencyNum)) {
-                    return true;
+                if (useExactMatch) {
+                    if (number.equals(emergencyNum)) {
+                        return true;
+                    }
+                } else {
+                    if (number.startsWith(emergencyNum)) {
+                        return true;
+                    }
                 }
             }
             // no matches found against the list!
             return false;
         }
 
-        //no ecclist system property, so use our own list.
-        return (number.startsWith("112") || number.startsWith("911"));
+        // No ecclist system property, so use our own list.
+        if (useExactMatch) {
+            return (number.equals("112") || number.equals("911"));
+        } else {
+            return (number.startsWith("112") || number.startsWith("911"));
+        }
     }
 
     /**
@@ -1559,31 +1620,81 @@
      * @param defaultCountryIso the specific country which the number should be checked against
      * @return if the number is an emergency number for the specific country, then return true,
      * otherwise false
+     *
      * @hide
      */
     public static boolean isEmergencyNumber(String number, String defaultCountryIso) {
-      PhoneNumberUtil util = PhoneNumberUtil.getInstance();
-      try {
-        PhoneNumber pn = util.parse(number, defaultCountryIso);
-        // libphonenumber guarantees short numbers such as emergency numbers are classified as
-        // invalid. Therefore, if the number passes the validation test, we believe it is not an
-        // emergency number.
-        // TODO: Compare against a list of country-specific known emergency numbers instead, once
-        // that has been collected.
-        if (util.isValidNumber(pn)) {
-          return false;
-        } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
-          // This is to prevent Brazilian local numbers which start with 911 being incorrectly
-          // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
-          // not possible to append additional digits to an emergency number to dial the number in
-          // Brazil - it won't connect.
-          // TODO: Clean this up once a list of country-specific known emergency numbers is
-          // collected.
-          return false;
+        return isEmergencyNumberInternal(number,
+                                         defaultCountryIso,
+                                         true /* useExactMatch */);
+    }
+
+    /**
+     * Checks if a given number might *potentially* result in a call to an
+     * emergency service, for a specific country.
+     *
+     * Specifically, this method will return true if the specified number
+     * is an emergency number in the specified country, *or* if the number
+     * simply starts with the same digits as any emergency number for that
+     * country.
+     *
+     * This method is intended for internal use by the phone app when
+     * deciding whether to allow ACTION_CALL intents from 3rd party apps
+     * (where we're required to *not* allow emergency calls to be placed.)
+     *
+     * @param number the number to look up.
+     * @param defaultCountryIso the specific country which the number should be checked against
+     * @return true if the number is an emergency number for the specific
+     *         country, *or* if the number starts with the same digits as
+     *         any of those emergency numbers.
+     *
+     * @hide
+     */
+    public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) {
+        return isEmergencyNumberInternal(number,
+                                         defaultCountryIso,
+                                         false /* useExactMatch */);
+    }
+
+    /**
+     * Helper function for isEmergencyNumber(String, String) and
+     * isPotentialEmergencyNumber(String, String).
+     *
+     * @param number the number to look up.
+     * @param defaultCountryIso the specific country which the number should be checked against
+     * @param useExactMatch if true, consider a number to be an emergency
+     *           number only if it *exactly* matches a number listed in
+     *           the RIL / SIM.  If false, a number is considered to be an
+     *           emergency number if it simply starts with the same digits
+     *           as any of the emergency numbers listed in the RIL / SIM.
+     *
+     * @return true if the number is an emergency number for the specified country.
+     */
+    private static boolean isEmergencyNumberInternal(String number,
+                                                     String defaultCountryIso,
+                                                     boolean useExactMatch) {
+        PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+        try {
+            PhoneNumber pn = util.parse(number, defaultCountryIso);
+            // libphonenumber guarantees short numbers such as emergency numbers are classified as
+            // invalid. Therefore, if the number passes the validation test, we believe it is not an
+            // emergency number.
+            // TODO: Compare against a list of country-specific known emergency numbers instead, once
+            // that has been collected.
+            if (util.isValidNumber(pn)) {
+                return false;
+            } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
+                // This is to prevent Brazilian local numbers which start with 911 being incorrectly
+                // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
+                // not possible to append additional digits to an emergency number to dial the number in
+                // Brazil - it won't connect.
+                // TODO: Clean this up once a list of country-specific known emergency numbers is
+                // collected.
+                return false;
+            }
+        } catch (NumberParseException e) {
         }
-      } catch (NumberParseException e) {
-      }
-      return isEmergencyNumber(number);
+        return isEmergencyNumberInternal(number, useExactMatch);
     }
 
     /**
@@ -1592,12 +1703,66 @@
      *
      * @param number the number to look up.
      * @param context the specific context which the number should be checked against
-     * @return if a phone number is an emergency number for a local country, based on the
-     * CountryDetector.
+     * @return true if the specified number is an emergency number for a local country, based on the
+     *              CountryDetector.
+     *
      * @see android.location.CountryDetector
      * @hide
      */
     public static boolean isLocalEmergencyNumber(String number, Context context) {
+        return isLocalEmergencyNumberInternal(number,
+                                              context,
+                                              true /* useExactMatch */);
+    }
+
+    /**
+     * Checks if a given number might *potentially* result in a call to an
+     * emergency service, for the country that the user is in. The current
+     * country is determined using the CountryDetector.
+     *
+     * Specifically, this method will return true if the specified number
+     * is an emergency number in the current country, *or* if the number
+     * simply starts with the same digits as any emergency number for the
+     * current country.
+     *
+     * This method is intended for internal use by the phone app when
+     * deciding whether to allow ACTION_CALL intents from 3rd party apps
+     * (where we're required to *not* allow emergency calls to be placed.)
+     *
+     * @param number the number to look up.
+     * @param context the specific context which the number should be checked against
+     * @return true if the specified number is an emergency number for a local country, based on the
+     *              CountryDetector.
+     *
+     * @see android.location.CountryDetector
+     * @hide
+     */
+    public static boolean isPotentialLocalEmergencyNumber(String number, Context context) {
+        return isLocalEmergencyNumberInternal(number,
+                                              context,
+                                              false /* useExactMatch */);
+    }
+
+    /**
+     * Helper function for isLocalEmergencyNumber() and
+     * isPotentialLocalEmergencyNumber().
+     *
+     * @param number the number to look up.
+     * @param context the specific context which the number should be checked against
+     * @param useExactMatch if true, consider a number to be an emergency
+     *           number only if it *exactly* matches a number listed in
+     *           the RIL / SIM.  If false, a number is considered to be an
+     *           emergency number if it simply starts with the same digits
+     *           as any of the emergency numbers listed in the RIL / SIM.
+     *
+     * @return true if the specified number is an emergency number for a
+     *              local country, based on the CountryDetector.
+     *
+     * @see android.location.CountryDetector
+     */
+    private static boolean isLocalEmergencyNumberInternal(String number,
+                                                          Context context,
+                                                          boolean useExactMatch) {
         String countryIso;
         CountryDetector detector = (CountryDetector) context.getSystemService(
                 Context.COUNTRY_DETECTOR);
@@ -1609,7 +1774,7 @@
             Log.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: "
                     + countryIso);
         }
-        return isEmergencyNumber(number, countryIso);
+        return isEmergencyNumberInternal(number, countryIso, useExactMatch);
     }
 
     /**
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index fc8a145..1410747 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -291,12 +291,31 @@
         // flexibly...
 
         int limit;
-        if (ted.msgCount > 1) {
-            limit = (ted.codeUnitSize == ENCODING_7BIT) ?
-                MAX_USER_DATA_SEPTETS_WITH_HEADER : MAX_USER_DATA_BYTES_WITH_HEADER;
+        if (ted.codeUnitSize == ENCODING_7BIT) {
+            int udhLength;
+            if (ted.languageTable != 0 && ted.languageShiftTable != 0) {
+                udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES;
+            } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) {
+                udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE;
+            } else {
+                udhLength = 0;
+            }
+
+            if (ted.msgCount > 1) {
+                udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE;
+            }
+
+            if (udhLength != 0) {
+                udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH;
+            }
+
+            limit = MAX_USER_DATA_SEPTETS - udhLength;
         } else {
-            limit = (ted.codeUnitSize == ENCODING_7BIT) ?
-                MAX_USER_DATA_SEPTETS : MAX_USER_DATA_BYTES;
+            if (ted.msgCount > 1) {
+                limit = MAX_USER_DATA_BYTES_WITH_HEADER;
+            } else {
+                limit = MAX_USER_DATA_BYTES;
+            }
         }
 
         int pos = 0;  // Index in code units.
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 97e7aa3..43f182a 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -27,12 +27,14 @@
 import android.net.LinkCapabilities;
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
+import android.net.TrafficStats;
 import android.net.wifi.WifiManager;
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
@@ -56,6 +58,7 @@
  */
 public abstract class DataConnectionTracker extends Handler {
     protected static final boolean DBG = true;
+    protected static final boolean VDBG = false;
 
     /**
      * IDLE: ready to start data connection setup, default state
@@ -114,8 +117,8 @@
     protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
     protected static final int EVENT_DISCONNECT_DONE = BASE + 15;
     protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
-    protected static final int EVENT_START_NETSTAT_POLL = BASE + 17;
-    protected static final int EVENT_START_RECOVERY = BASE + 18;
+    protected static final int EVENT_DATA_STALL_ALARM = BASE + 17;
+    protected static final int EVENT_DO_RECOVERY = BASE + 18;
     protected static final int EVENT_APN_CHANGED = BASE + 19;
     protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
     protected static final int EVENT_NV_READY = BASE + 21;
@@ -189,19 +192,16 @@
 
     /**
      * After detecting a potential connection problem, this is the max number
-     * of subsequent polls before attempting a radio reset.  At this point,
-     * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to
-     * poll for about 2 more minutes.
+     * of subsequent polls before attempting recovery.
      */
     protected static final int NO_RECV_POLL_LIMIT = 24;
-
     // 1 sec. default polling interval when screen is on.
     protected static final int POLL_NETSTAT_MILLIS = 1000;
     // 10 min. default polling interval when screen is off.
     protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
     // 2 min for round trip time
     protected static final int POLL_LONGEST_RTT = 120 * 1000;
-    // 10 for packets without ack
+    // Default sent packets without ack which triggers initial recovery steps
     protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
     // how long to wait before switching back to default APN
     protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
@@ -210,6 +210,13 @@
     // represents an invalid IP address
     protected static final String NULL_IP = "0.0.0.0";
 
+    // Default for the data stall alarm
+    protected static final int DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
+    // If attempt is less than this value we're doing first level recovery
+    protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
+    // Tag for tracking stale alarms
+    protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
+
     // TODO: See if we can remove INTENT_RECONNECT_ALARM
     //       having to have different values for GSM and
     //       CDMA. If so we can then remove the need for
@@ -240,11 +247,19 @@
 
     protected long mTxPkts;
     protected long mRxPkts;
-    protected long mSentSinceLastRecv;
     protected int mNetStatPollPeriod;
-    protected int mNoRecvPollCount = 0;
     protected boolean mNetStatPollEnabled = false;
 
+    protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
+    // Used to track stale data stall alarms.
+    protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
+    // The current data stall alarm intent
+    protected PendingIntent mDataStallAlarmIntent = null;
+    // Number of packets sent since the last received packet
+    protected long mSentSinceLastRecv;
+    // Controls when a simple recovery attempt it to be tried
+    protected int mNoRecvPollCount = 0;
+
     // wifi connection status will be updated by sticky intent
     protected boolean mIsWifiConnected = false;
 
@@ -313,7 +328,8 @@
             } else if (action.startsWith(getActionIntentReconnectAlarm())) {
                 log("Reconnect alarm. Previous state was " + mState);
                 onActionIntentReconnectAlarm(intent);
-
+            } else if (action.equals(getActionIntentDataStallAlarm())) {
+                onActionIntentDataStallAlarm(intent);
             } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                 final android.net.NetworkInfo networkInfo = (NetworkInfo)
                         intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
@@ -363,6 +379,71 @@
         }
     }
 
+    /**
+     * Maintian the sum of transmit and receive packets.
+     *
+     * The packet counts are initizlied and reset to -1 and
+     * remain -1 until they can be updated.
+     */
+    public class TxRxSum {
+        public long txPkts;
+        public long rxPkts;
+
+        public TxRxSum() {
+            reset();
+        }
+
+        public TxRxSum(long txPkts, long rxPkts) {
+            this.txPkts = txPkts;
+            this.rxPkts = rxPkts;
+        }
+
+        public TxRxSum(TxRxSum sum) {
+            txPkts = sum.txPkts;
+            rxPkts = sum.rxPkts;
+        }
+
+        public void reset() {
+            txPkts = -1;
+            rxPkts = -1;
+        }
+
+        public String toString() {
+            return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
+        }
+
+        public void updateTxRxSum() {
+            boolean txUpdated = false, rxUpdated = false;
+            long txSum = 0, rxSum = 0;
+            for (ApnContext apnContext : mApnContexts.values()) {
+                if (apnContext.getState() == State.CONNECTED) {
+                    DataConnectionAc dcac = apnContext.getDataConnectionAc();
+                    if (dcac == null) continue;
+
+                    LinkProperties linkProp = dcac.getLinkPropertiesSync();
+                    if (linkProp == null) continue;
+
+                    String iface = linkProp.getInterfaceName();
+
+                    if (iface != null) {
+                        long stats = TrafficStats.getTxPackets(iface);
+                        if (stats > 0) {
+                            txUpdated = true;
+                            txSum += stats;
+                        }
+                        stats = TrafficStats.getRxPackets(iface);
+                        if (stats > 0) {
+                            rxUpdated = true;
+                            rxSum += stats;
+                        }
+                    }
+                }
+            }
+            if (txUpdated) this.txPkts = txSum;
+            if (rxUpdated) this.rxPkts = rxSum;
+        }
+    }
+
     protected boolean isDataSetupCompleteOk(AsyncResult ar) {
         if (ar.exception != null) {
             if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result);
@@ -394,6 +475,13 @@
         sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
     }
 
+    protected void onActionIntentDataStallAlarm(Intent intent) {
+        if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
+        Message msg = obtainMessage(EVENT_DATA_STALL_ALARM, intent.getAction());
+        msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
+        sendMessage(msg);
+    }
+
     /**
      * Default constructor
      */
@@ -529,6 +617,7 @@
 
     // abstract methods
     protected abstract String getActionIntentReconnectAlarm();
+    protected abstract String getActionIntentDataStallAlarm();
     protected abstract void startNetStatPoll();
     protected abstract void stopNetStatPoll();
     protected abstract void restartRadio();
@@ -553,6 +642,10 @@
     protected abstract void onCleanUpAllConnections(String cause);
     protected abstract boolean isDataPossible(String apnType);
 
+    protected void onDataStallAlarm(int tag) {
+        loge("onDataStallAlarm: not impleted tag=" + tag);
+    }
+
     @Override
     public void handleMessage(Message msg) {
         switch (msg.what) {
@@ -575,6 +668,10 @@
                 onTrySetupData(reason);
                 break;
 
+            case EVENT_DATA_STALL_ALARM:
+                onDataStallAlarm(msg.arg1);
+                break;
+
             case EVENT_ROAMING_OFF:
                 if (getDataOnRoamingEnabled() == false) {
                     resetAllRetryCounts();
diff --git a/telephony/java/com/android/internal/telephony/EventLogTags.logtags b/telephony/java/com/android/internal/telephony/EventLogTags.logtags
index 9be7b80..427e5da 100644
--- a/telephony/java/com/android/internal/telephony/EventLogTags.logtags
+++ b/telephony/java/com/android/internal/telephony/EventLogTags.logtags
@@ -56,3 +56,18 @@
 
 # Bad IP address
 50117 bad_ip_address (ip_address|3)
+
+# Data Stall Recovery mode DATA_STALL_RECOVERY_GET_DATA_CALL_LIST
+50118 data_stall_recovery_get_data_call_list (out_packet_count|1|1)
+
+# Data Stall Recovery mode DATA_STALL_RECOVERY_CLEANUP
+50119 data_stall_recovery_cleanup (out_packet_count|1|1)
+
+# Data Stall Recovery mode DATA_STALL_RECOVERY_REREGISTER
+50120 data_stall_recovery_reregister (out_packet_count|1|1)
+
+# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART
+50121 data_stall_recovery_radio_restart (out_packet_count|1|1)
+
+# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP
+50122 data_stall_recovery_radio_restart_with_prop (out_packet_count|1|1)
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 2e99849..25647ac 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -60,25 +60,25 @@
      * all combinations of header elements below will have at least one free bit
      * when padding to the nearest septet boundary.
      */
-    private static final int UDH_SEPTET_COST_LENGTH = 1;
+    public static final int UDH_SEPTET_COST_LENGTH = 1;
 
     /**
      * Using a non-default language locking shift table OR single shift table
      * requires a user data header of 3 octets, or 4 septets, plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
+    public static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
 
     /**
      * Using a non-default language locking shift table AND single shift table
      * requires a user data header of 6 octets, or 7 septets, plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
+    public static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
 
     /**
      * Multi-part messages require a user data header of 5 octets, or 6 septets,
      * plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
+    public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
 
     /**
      * Converts a char to a GSM 7 bit table index.
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
index 9492e0e..c32388f 100644
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ b/telephony/java/com/android/internal/telephony/SmsHeader.java
@@ -190,7 +190,9 @@
     public static byte[] toByteArray(SmsHeader smsHeader) {
         if ((smsHeader.portAddrs == null) &&
             (smsHeader.concatRef == null) &&
-            (smsHeader.miscEltList.size() == 0)) {
+            (smsHeader.miscEltList.isEmpty()) &&
+            (smsHeader.languageShiftTable == 0) &&
+            (smsHeader.languageTable == 0)) {
             return null;
         }
 
diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index 99f662d..e5a2d31 100644
--- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
+ * 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.
@@ -28,6 +28,7 @@
  * {@hide}
  */
 class ComprehensionTlv {
+    private static final String LOG_TAG = "ComprehensionTlv";
     private int mTag;
     private boolean mCr;
     private int mLength;
@@ -88,8 +89,13 @@
         int endIndex = data.length;
         while (startIndex < endIndex) {
             ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex);
-            items.add(ctlv);
-            startIndex = ctlv.mValueIndex + ctlv.mLength;
+            if (ctlv != null) {
+                items.add(ctlv);
+                startIndex = ctlv.mValueIndex + ctlv.mLength;
+            } else {
+                CatLog.d(LOG_TAG, "decodeMany: ctlv is null, stop decoding");
+                break;
+            }
         }
 
         return items;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index f5d05a1..5889372 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -69,6 +69,10 @@
     private static final String INTENT_RECONNECT_ALARM =
         "com.android.internal.telephony.cdma-reconnect";
 
+    private static final String INTENT_DATA_STALL_ALARM =
+        "com.android.internal.telephony.cdma-data-stall";
+
+
     /**
      * Constants for the data connection activity:
      * physical link down/up
@@ -149,6 +153,11 @@
     }
 
     @Override
+    protected String getActionIntentDataStallAlarm() {
+        return INTENT_DATA_STALL_ALARM;
+    }
+
+    @Override
     protected void setState(State s) {
         if (DBG) log ("setState: " + s);
         if (mState != s) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e166401..a837899 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -96,22 +96,37 @@
     private boolean mReregisterOnReconnectFailure = false;
     private ContentResolver mResolver;
 
-    // Count of PDP reset attempts; reset when we see incoming,
-    // call reRegisterNetwork, or pingTest succeeds.
-    private int mPdpResetCount = 0;
-
     // Recovery action taken in case of data stall
-    enum RecoveryAction {REREGISTER, RADIO_RESTART, RADIO_RESET};
-    private RecoveryAction mRecoveryAction = RecoveryAction.REREGISTER;
-
+    class RecoveryAction {
+        public static final int GET_DATA_CALL_LIST      = 0;
+        public static final int CLEANUP                 = 1;
+        public static final int REREGISTER              = 2;
+        public static final int RADIO_RESTART           = 3;
+        public static final int RADIO_RESTART_WITH_PROP = 4;
+    }
+    public int getRecoveryAction() {
+        int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
+                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
+        if (VDBG) log("getRecoveryAction: " + action);
+        return action;
+    }
+    public void putRecoveryAction(int action) {
+        Settings.System.putInt(mPhone.getContext().getContentResolver(),
+                "radio.data.stall.recovery.action", action);
+        if (VDBG) log("putRecoveryAction: " + action);
+    }
 
     //***** Constants
 
     private static final int POLL_PDP_MILLIS = 5 * 1000;
 
-    private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
+    private static final String INTENT_RECONNECT_ALARM =
+        "com.android.internal.telephony.gprs-reconnect";
     private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "type";
 
+    private static final String INTENT_DATA_STALL_ALARM =
+        "com.android.internal.telephony.gprs-data-stall";
+
     static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
     static final String APN_ID = "apn_id";
     private boolean canSetPreferApn = false;
@@ -163,6 +178,11 @@
         p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
                 EVENT_PS_RESTRICT_DISABLED, null);
 
+        // install reconnect intent filter for this data connection.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(INTENT_DATA_STALL_ALARM);
+        p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
+
         mDataConnectionTracker = this;
         mResolver = mPhone.getContext().getContentResolver();
 
@@ -241,6 +261,11 @@
         return INTENT_RECONNECT_ALARM;
     }
 
+    @Override
+    protected String getActionIntentDataStallAlarm() {
+        return INTENT_DATA_STALL_ALARM;
+    }
+
     private ApnContext addApnContext(String type) {
         ApnContext apnContext = new ApnContext(type, LOG_TAG);
         apnContext.setDependencyMet(false);
@@ -552,6 +577,7 @@
          */
         if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
         stopNetStatPoll();
+        stopDataStallAlarm();
         notifyDataConnection(Phone.REASON_DATA_DETACHED);
     }
 
@@ -560,6 +586,7 @@
         if (getOverallState() == State.CONNECTED) {
             if (DBG) log("onDataConnectionAttached: start polling notify attached");
             startNetStatPoll();
+            startDataStallAlarm();
             notifyDataConnection(Phone.REASON_DATA_ATTACHED);
         } else {
             // update APN availability so that APN can be enabled.
@@ -764,6 +791,8 @@
         }
 
         stopNetStatPoll();
+        stopDataStallAlarm();
+
         // TODO: Do we need mRequestedApnType?
         mRequestedApnType = Phone.APN_TYPE_DEFAULT;
     }
@@ -1238,6 +1267,7 @@
         // setState(State.CONNECTED);
         mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
         startNetStatPoll();
+        startDataStallAlarm();
         // reset reconnect timer
         apnContext.getDataConnection().resetRetryCount();
     }
@@ -1252,59 +1282,62 @@
     private void resetPollStats() {
         mTxPkts = -1;
         mRxPkts = -1;
-        mSentSinceLastRecv = 0;
         mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
-        mNoRecvPollCount = 0;
     }
 
     private void doRecovery() {
         if (getOverallState() == State.CONNECTED) {
-            int maxPdpReset = Settings.Secure.getInt(mResolver,
-                    Settings.Secure.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT,
-                    DEFAULT_MAX_PDP_RESET_FAIL);
-            if (mPdpResetCount < maxPdpReset) {
-                mPdpResetCount++;
-                EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
-                if (DBG) log("doRecovery() cleanup all connections mPdpResetCount < max");
+            // Go through a series of recovery steps, each action transitions to the next action
+            int recoveryAction = getRecoveryAction();
+            switch (recoveryAction) {
+            case RecoveryAction.GET_DATA_CALL_LIST:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
+                        mSentSinceLastRecv);
+                if (DBG) log("doRecovery() get data call list");
+                mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED));
+                putRecoveryAction(RecoveryAction.CLEANUP);
+                break;
+            case RecoveryAction.CLEANUP:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
+                if (DBG) log("doRecovery() cleanup all connections");
                 cleanUpAllConnections(true, Phone.REASON_PDP_RESET);
-            } else {
-                mPdpResetCount = 0;
-                switch (mRecoveryAction) {
-                case REREGISTER:
-                    EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, mSentSinceLastRecv);
-                    if (DBG) log("doRecovery() re-register getting preferred network type");
-                    mPhone.getServiceStateTracker().reRegisterNetwork(null);
-                    mRecoveryAction = RecoveryAction.RADIO_RESTART;
-                    break;
-                case RADIO_RESTART:
-                    EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
-                    if (DBG) log("restarting radio");
-                    mRecoveryAction = RecoveryAction.RADIO_RESET;
-                    restartRadio();
-                    break;
-                case RADIO_RESET:
-                    // This is in case radio restart has not recovered the data.
-                    // It will set an additional "gsm.radioreset" property to tell
-                    // RIL or system to take further action.
-                    // The implementation of hard reset recovery action is up to OEM product.
-                    // Once gsm.radioreset property is consumed, it is expected to set back
-                    // to false by RIL.
-                    EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, -1);
-                    if (DBG) log("restarting radio with reset indication");
-                    SystemProperties.set("gsm.radioreset", "true");
-                    // give 1 sec so property change can be notified.
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {}
-                    restartRadio();
-                    break;
-                default:
-                    throw new RuntimeException("doRecovery: Invalid mRecoveryAction " +
-                        mRecoveryAction);
-                }
+                putRecoveryAction(RecoveryAction.REREGISTER);
+                break;
+            case RecoveryAction.REREGISTER:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
+                        mSentSinceLastRecv);
+                if (DBG) log("doRecovery() re-register");
+                mPhone.getServiceStateTracker().reRegisterNetwork(null);
+                putRecoveryAction(RecoveryAction.RADIO_RESTART);
+                break;
+            case RecoveryAction.RADIO_RESTART:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
+                        mSentSinceLastRecv);
+                if (DBG) log("restarting radio");
+                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
+                restartRadio();
+                break;
+            case RecoveryAction.RADIO_RESTART_WITH_PROP:
+                // This is in case radio restart has not recovered the data.
+                // It will set an additional "gsm.radioreset" property to tell
+                // RIL or system to take further action.
+                // The implementation of hard reset recovery action is up to OEM product.
+                // Once gsm.radioreset property is consumed, it is expected to set back
+                // to false by RIL.
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
+                if (DBG) log("restarting radio with gsm.radioreset to true");
+                SystemProperties.set("gsm.radioreset", "true");
+                // give 1 sec so property change can be notified.
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {}
+                restartRadio();
+                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+                break;
+            default:
+                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
+                    recoveryAction);
             }
-        } else {
-            if (DBG) log("doRecovery(): ignore, we're not connected");
         }
     }
 
@@ -1342,119 +1375,130 @@
         SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
     }
 
+
+    private void updateDataStallInfo() {
+        long sent, received;
+
+        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
+        mDataStallTxRxSum.updateTxRxSum();
+
+        if (VDBG) {
+            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
+                    " preTxRxSum=" + preTxRxSum);
+        }
+
+        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
+        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
+
+        if (VDBG) {
+            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
+                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
+                received = 0;
+            }
+        }
+        if ( sent > 0 && received > 0 ) {
+            if (VDBG) log("updateDataStallInfo: IN/OUT");
+            mSentSinceLastRecv = 0;
+            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+        } else if (sent > 0 && received == 0) {
+            if (mPhone.getState() == Phone.State.IDLE) {
+                mSentSinceLastRecv += sent;
+            } else {
+                mSentSinceLastRecv = 0;
+            }
+            if (DBG) {
+                log("updateDataStallInfo: OUT sent=" + sent +
+                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
+            }
+        } else if (sent == 0 && received > 0) {
+            if (VDBG) log("updateDataStallInfo: IN");
+            mSentSinceLastRecv = 0;
+            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+        } else {
+            if (VDBG) log("updateDataStallInfo: NONE");
+        }
+    }
+
+    @Override
+    protected void onDataStallAlarm(int tag) {
+        if (mDataStallAlarmTag != tag) {
+            if (DBG) {
+                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
+            }
+            return;
+        }
+        updateDataStallInfo();
+
+        int hangWatchdogTrigger = Settings.Secure.getInt(mResolver,
+                Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
+                NUMBER_SENT_PACKETS_OF_HANG);
+
+        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
+            if (DBG) {
+                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
+            }
+            sendMessage(obtainMessage(EVENT_DO_RECOVERY));
+        } else {
+            if (VDBG) {
+                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
+                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
+            }
+        }
+        startDataStallAlarm();
+    }
+
+
+    private void updateDataActivity() {
+        long sent, received;
+
+        Activity newActivity;
+
+        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
+        TxRxSum curTxRxSum = new TxRxSum();
+        curTxRxSum.updateTxRxSum();
+        mTxPkts = curTxRxSum.txPkts;
+        mRxPkts = curTxRxSum.rxPkts;
+
+        if (VDBG) {
+            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
+        }
+
+        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
+            sent = mTxPkts - preTxRxSum.txPkts;
+            received = mRxPkts - preTxRxSum.rxPkts;
+
+            if (VDBG) log("updateDataActivity: sent=" + sent + " received=" + received);
+            if ( sent > 0 && received > 0 ) {
+                newActivity = Activity.DATAINANDOUT;
+            } else if (sent > 0 && received == 0) {
+                newActivity = Activity.DATAOUT;
+            } else if (sent == 0 && received > 0) {
+                newActivity = Activity.DATAIN;
+            } else {
+                newActivity = Activity.NONE;
+            }
+
+            if (mActivity != newActivity && mIsScreenOn) {
+                if (VDBG) log("updateDataActivity: newActivity=" + newActivity);
+                mActivity = newActivity;
+                mPhone.notifyDataActivity();
+            }
+        }
+    }
+
     private Runnable mPollNetStat = new Runnable()
     {
-
+        @Override
         public void run() {
-            long sent, received;
-            long preTxPkts = -1, preRxPkts = -1;
+            updateDataActivity();
 
-            Activity newActivity;
-
-            preTxPkts = mTxPkts;
-            preRxPkts = mRxPkts;
-
-            long txSum = 0, rxSum = 0;
-            for (ApnContext apnContext : mApnContexts.values()) {
-                if (apnContext.getState() == State.CONNECTED) {
-                    DataConnectionAc dcac = apnContext.getDataConnectionAc();
-                    if (dcac == null) continue;
-
-                    LinkProperties linkProp = dcac.getLinkPropertiesSync();
-                    if (linkProp == null) continue;
-
-                    String iface = linkProp.getInterfaceName();
-
-                    if (iface != null) {
-                        long stats = TrafficStats.getTxPackets(iface);
-                        if (stats > 0) txSum += stats;
-                        stats = TrafficStats.getRxPackets(iface);
-                        if (stats > 0) rxSum += stats;
-                    }
-                }
-            }
-
-            mTxPkts = txSum;
-            mRxPkts = rxSum;
-
-            // log("tx " + mTxPkts + " rx " + mRxPkts);
-
-            if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
-                sent = mTxPkts - preTxPkts;
-                received = mRxPkts - preRxPkts;
-
-                if ( sent > 0 && received > 0 ) {
-                    mSentSinceLastRecv = 0;
-                    newActivity = Activity.DATAINANDOUT;
-                    mPdpResetCount = 0;
-                    mRecoveryAction = RecoveryAction.REREGISTER;
-                } else if (sent > 0 && received == 0) {
-                    if (mPhone.getState() == Phone.State.IDLE) {
-                        mSentSinceLastRecv += sent;
-                    } else {
-                        mSentSinceLastRecv = 0;
-                    }
-                    newActivity = Activity.DATAOUT;
-                } else if (sent == 0 && received > 0) {
-                    mSentSinceLastRecv = 0;
-                    newActivity = Activity.DATAIN;
-                    mPdpResetCount = 0;
-                    mRecoveryAction = RecoveryAction.REREGISTER;
-                } else if (sent == 0 && received == 0) {
-                    newActivity = Activity.NONE;
-                } else {
-                    mSentSinceLastRecv = 0;
-                    newActivity = Activity.NONE;
-                }
-
-                if (mActivity != newActivity && mIsScreenOn) {
-                    mActivity = newActivity;
-                    mPhone.notifyDataActivity();
-                }
-            }
-
-            int watchdogTrigger = Settings.Secure.getInt(mResolver,
-                    Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
-                    NUMBER_SENT_PACKETS_OF_HANG);
-
-            if (mSentSinceLastRecv >= watchdogTrigger) {
-                // we already have NUMBER_SENT_PACKETS sent without ack
-                if (mNoRecvPollCount == 0) {
-                    EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
-                            mSentSinceLastRecv);
-                }
-
-                int noRecvPollLimit = Settings.Secure.getInt(mResolver,
-                        Settings.Secure.PDP_WATCHDOG_ERROR_POLL_COUNT, NO_RECV_POLL_LIMIT);
-
-                if (mNoRecvPollCount < noRecvPollLimit) {
-                    // It's possible the PDP context went down and we weren't notified.
-                    // Start polling the context list in an attempt to recover.
-                    if (DBG) log("Polling: no DATAIN in a while; polling PDP");
-                    mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED));
-
-                    mNoRecvPollCount++;
-
-                    // Slow down the poll interval to let things happen
-                    mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
-                            Settings.Secure.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
-                            POLL_NETSTAT_SLOW_MILLIS);
-                } else {
-                    if (DBG) log("Polling: Sent " + String.valueOf(mSentSinceLastRecv) +
-                                        " pkts since last received start recovery process");
-                    mNoRecvPollCount = 0;
-                    sendMessage(obtainMessage(EVENT_START_RECOVERY));
-                }
+            if (mIsScreenOn) {
+                mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
+                        Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
             } else {
-                mNoRecvPollCount = 0;
-                if (mIsScreenOn) {
-                    mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
-                            Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
-                } else {
-                    mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
-                            Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
-                            POLL_NETSTAT_SCREEN_OFF_MILLIS);
-                }
+                mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
+                        Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
+                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
             }
 
             if (mNetStatPollEnabled) {
@@ -1566,6 +1610,41 @@
 
     }
 
+    private void startDataStallAlarm() {
+        int delayInMs = Settings.Secure.getInt(mResolver,
+                            Settings.Secure.DATA_STALL_ALARM_DELAY_IN_MS,
+                            DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT);
+        mDataStallAlarmTag += 1;
+        if (DBG) {
+            log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
+                    " delay=" + (delayInMs / 1000) + "s");
+        }
+        AlarmManager am =
+            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
+
+        Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
+        intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
+        mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
+    }
+
+    private void stopDataStallAlarm() {
+        AlarmManager am =
+            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
+
+        if (DBG) {
+            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
+                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
+        }
+        mDataStallAlarmTag += 1;
+        if (mDataStallAlarmIntent != null) {
+            am.cancel(mDataStallAlarmIntent);
+            mDataStallAlarmIntent = null;
+        }
+    }
+
     private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
                               ApnContext apnContext) {
         if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
@@ -1930,6 +2009,7 @@
         if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
             if (DBG) log("onVoiceCallStarted stop polling");
             stopNetStatPoll();
+            stopDataStallAlarm();
             notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
         }
     }
@@ -1940,6 +2020,7 @@
         if (isConnected()) {
             if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                 startNetStatPoll();
+                startDataStallAlarm();
                 notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
             } else {
                 // clean slate after call end.
@@ -2251,11 +2332,7 @@
                 onPollPdp();
                 break;
 
-            case EVENT_START_NETSTAT_POLL:
-                startNetStatPoll();
-                break;
-
-            case EVENT_START_RECOVERY:
+            case EVENT_DO_RECOVERY:
                 doRecovery();
                 break;
 
@@ -2272,6 +2349,7 @@
                  */
                 if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
                 stopNetStatPoll();
+                stopDataStallAlarm();
                 mIsPsRestricted = true;
                 break;
 
@@ -2284,6 +2362,7 @@
                 mIsPsRestricted  = false;
                 if (isConnected()) {
                     startNetStatPoll();
+                    startDataStallAlarm();
                 } else {
                     // TODO: Should all PDN states be checked to fail?
                     if (mState == State.FAILED) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index c1553d8..093c220 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -197,7 +197,11 @@
             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
         SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
                 scAddr, destAddr, destPort, data, (deliveryIntent != null));
-        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        if (pdu != null) {
+            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        } else {
+            Log.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null");
+        }
     }
 
     /** {@inheritDoc} */
@@ -206,7 +210,11 @@
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
                 scAddr, destAddr, text, (deliveryIntent != null));
-        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        if (pdu != null) {
+            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        } else {
+            Log.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null");
+        }
     }
 
     /** {@inheritDoc} */
@@ -224,7 +232,11 @@
         SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
                 message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
                 encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
-        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        if (pdu != null) {
+            sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+        } else {
+            Log.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null");
+        }
     }
 
     /** {@inheritDoc} */
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 2da9642..d9a5f5d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -16,22 +16,22 @@
 
 package com.android.internal.telephony.gsm;
 
-import android.os.Parcel;
 import android.telephony.PhoneNumberUtils;
 import android.text.format.Time;
 import android.util.Log;
-import com.android.internal.telephony.IccUtils;
+
 import com.android.internal.telephony.EncodeException;
 import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.IccUtils;
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 
+import static android.telephony.SmsMessage.ENCODING_16BIT;
 import static android.telephony.SmsMessage.ENCODING_7BIT;
 import static android.telephony.SmsMessage.ENCODING_8BIT;
-import static android.telephony.SmsMessage.ENCODING_16BIT;
 import static android.telephony.SmsMessage.ENCODING_KSC5601;
 import static android.telephony.SmsMessage.ENCODING_UNKNOWN;
 import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
@@ -240,18 +240,43 @@
             return null;
         }
 
+        if (encoding == ENCODING_UNKNOWN) {
+            // Find the best encoding to use
+            TextEncodingDetails ted = calculateLength(message, false);
+            encoding = ted.codeUnitSize;
+            languageTable = ted.languageTable;
+            languageShiftTable = ted.languageShiftTable;
+
+            if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) {
+                if (header != null) {
+                    SmsHeader smsHeader = SmsHeader.fromByteArray(header);
+                    if (smsHeader.languageTable != languageTable
+                            || smsHeader.languageShiftTable != languageShiftTable) {
+                        Log.w(LOG_TAG, "Updating language table in SMS header: "
+                                + smsHeader.languageTable + " -> " + languageTable + ", "
+                                + smsHeader.languageShiftTable + " -> " + languageShiftTable);
+                        smsHeader.languageTable = languageTable;
+                        smsHeader.languageShiftTable = languageShiftTable;
+                        header = SmsHeader.toByteArray(smsHeader);
+                    }
+                } else {
+                    SmsHeader smsHeader = new SmsHeader();
+                    smsHeader.languageTable = languageTable;
+                    smsHeader.languageShiftTable = languageShiftTable;
+                    header = SmsHeader.toByteArray(smsHeader);
+                }
+            }
+        }
+
         SubmitPdu ret = new SubmitPdu();
         // MTI = SMS-SUBMIT, UDHI = header != null
         byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
         ByteArrayOutputStream bo = getSubmitPduHead(
                 scAddress, destinationAddress, mtiByte,
                 statusReportRequested, ret);
+
         // User Data (and length)
         byte[] userData;
-        if (encoding == ENCODING_UNKNOWN) {
-            // First, try encoding it with the GSM alphabet
-            encoding = ENCODING_7BIT;
-        }
         try {
             if (encoding == ENCODING_7BIT) {
                 userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,
@@ -283,6 +308,7 @@
         if (encoding == ENCODING_7BIT) {
             if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
                 // Message too long
+                Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)");
                 return null;
             }
             // TP-Data-Coding-Scheme
@@ -297,6 +323,7 @@
         } else { // assume UCS-2
             if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) {
                 // Message too long
+                Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)");
                 return null;
             }
             // TP-Data-Coding-Scheme
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
index 41a719e..5950669 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
@@ -16,11 +16,14 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.internal.telephony.gsm.SmsMessage;
 import com.android.internal.util.HexDump;
 
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import java.util.ArrayList;
 
 public class GsmSmsTest extends AndroidTestCase {
 
@@ -232,6 +235,110 @@
     };
 
     @SmallTest
+    public void testFragmentText() throws Exception {
+        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
+                TelephonyManager.PHONE_TYPE_GSM);
+
+        // Valid 160 character 7-bit text.
+        String text = "123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890";
+        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
+        assertEquals(1, ted.msgCount);
+        assertEquals(160, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(0, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(1, fragments.size());
+        }
+
+        // Valid 161 character 7-bit text.
+        text = "123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(2, ted.msgCount);
+        assertEquals(161, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(0, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(2, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1));
+            assertEquals(153, fragments.get(0).length());
+            assertEquals(8, fragments.get(1).length());
+        }
+    }
+
+    @SmallTest
+    public void testFragmentTurkishText() throws Exception {
+        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
+                TelephonyManager.PHONE_TYPE_GSM);
+
+        int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables();
+        int[] turkishTable = { 1 };
+        GsmAlphabet.setEnabledSingleShiftTables(turkishTable);
+
+        // Valid 77 character text with Turkish characters.
+        String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğş";
+        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
+        assertEquals(1, ted.msgCount);
+        assertEquals(154, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(1, fragments.size());
+            assertEquals(text, fragments.get(0));
+            assertEquals(77, fragments.get(0).length());
+        }
+
+        // Valid 78 character text with Turkish characters.
+        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşı";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(2, ted.msgCount);
+        assertEquals(156, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(2, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1));
+            assertEquals(74, fragments.get(0).length());
+            assertEquals(4, fragments.get(1).length());
+        }
+
+        // Valid 160 character text with Turkish characters.
+        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(3, ted.msgCount);
+        assertEquals(320, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(3, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2));
+            assertEquals(74, fragments.get(0).length());
+            assertEquals(74, fragments.get(1).length());
+            assertEquals(12, fragments.get(2).length());
+        }
+
+        GsmAlphabet.setEnabledSingleShiftTables(oldTables);
+    }
+
+
+    @SmallTest
     public void testDecode() throws Exception {
         decodeSingle(0);    // default table
         decodeSingle(1);    // Turkish locking shift table
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index e2349af..d34a7c5 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -550,21 +550,51 @@
     }
     @SmallTest
     public void testIsEmergencyNumber() {
-      assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
-      assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
-      // The next two numbers are not valid phone numbers in the US, but can be used to trick the
-      // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
-      // addressing that, they are also classified as emergency numbers in the US.
-      assertTrue(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
-      assertTrue(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
-      // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
-      // in Singapore, as 911 is not an emergency number there.
-      assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
-      // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
-      // in Brazil, as 112 is not an emergency number there.
-      assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
-      // A valid local phone number from Brazil shouldn't be classified as an emergency number in
-      // Brazil.
-      assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
+        // There are two parallel sets of tests here: one for the
+        // regular isEmergencyNumber() method, and the other for
+        // isPotentialEmergencyNumber().
+        //
+        // (The difference is that isEmergencyNumber() will return true
+        // only if the specified number exactly matches an actual
+        // emergency number, but isPotentialEmergencyNumber() will
+        // return true if the specified number simply starts with the
+        // same digits as any actual emergency number.)
+
+        // Tests for isEmergencyNumber():
+        assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
+        assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
+        // The next two numbers are not valid phone numbers in the US,
+        // so do not count as emergency numbers (but they *are* "potential"
+        // emergency numbers; see below.)
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
+        // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
+        // in Singapore, as 911 is not an emergency number there.
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
+        // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
+        // in Brazil, as 112 is not an emergency number there.
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
+        // A valid local phone number from Brazil shouldn't be classified as an emergency number in
+        // Brazil.
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
+
+        // Tests for isPotentialEmergencyNumber():
+        // These first two are obviously emergency numbers:
+        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US"));
+        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US"));
+        // The next two numbers are not valid phone numbers in the US, but can be used to trick the
+        // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
+        // addressing that, they are also classified as "potential" emergency numbers in the US.
+        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
+        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
+        // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
+        // in Singapore, as 911 is not an emergency number there.
+        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
+        // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
+        // in Brazil, as 112 is not an emergency number there.
+        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
+        // A valid local phone number from Brazil shouldn't be classified as an emergency number in
+        // Brazil.
+        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR"));
     }
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 1b02774..6bb22a4 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -81,7 +81,7 @@
  */
 public class WifiP2pService extends IWifiP2pManager.Stub {
     private static final String TAG = "WifiP2pService";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final String NETWORKTYPE = "WIFI_P2P";
 
     private Context mContext;
@@ -131,12 +131,22 @@
     /* User rejected to disable Wi-Fi in order to enable p2p */
     private static final int WIFI_DISABLE_USER_REJECT       =   BASE + 5;
 
+    /* User accepted a group negotiation request */
+    private static final int GROUP_NEGOTIATION_USER_ACCEPT  =   BASE + 6;
+    /* User rejected a group negotiation request */
+    private static final int GROUP_NEGOTIATION_USER_REJECT  =   BASE + 7;
+
+    /* User accepted a group invitation request */
+    private static final int GROUP_INVITATION_USER_ACCEPT   =   BASE + 8;
+    /* User rejected a group invitation request */
+    private static final int GROUP_INVITATION_USER_REJECT   =   BASE + 9;
+
     /* Airplane mode changed */
-    private static final int AIRPLANE_MODE_CHANGED          =   BASE + 6;
+    private static final int AIRPLANE_MODE_CHANGED          =   BASE + 10;
     /* Emergency callback mode */
-    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 7;
-    private static final int WPS_PBC                        =   BASE + 8;
-    private static final int WPS_PIN                        =   BASE + 9;
+    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 11;
+    private static final int WPS_PBC                        =   BASE + 12;
+    private static final int WPS_PIN                        =   BASE + 13;
 
     private final boolean mP2pSupported;
 
@@ -260,6 +270,10 @@
         private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
         // Inactive is when p2p is enabled with no connectivity
         private InactiveState mInactiveState = new InactiveState();
+        private UserAuthorizingGroupNegotiationState mUserAuthorizingGroupNegotiationState
+                = new UserAuthorizingGroupNegotiationState();
+        private UserAuthorizingGroupInvitationState mUserAuthorizingGroupInvitationState
+                = new UserAuthorizingGroupInvitationState();
         private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
         private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
 
@@ -290,6 +304,8 @@
                 addState(mP2pEnablingState, mDefaultState);
                 addState(mP2pEnabledState, mDefaultState);
                     addState(mInactiveState, mP2pEnabledState);
+                        addState(mUserAuthorizingGroupNegotiationState, mInactiveState);
+                        addState(mUserAuthorizingGroupInvitationState, mInactiveState);
                     addState(mGroupNegotiationState, mP2pEnabledState);
                     addState(mGroupCreatedState, mP2pEnabledState);
 
@@ -379,6 +395,10 @@
                     // Ignore
                 case WIFI_DISABLE_USER_ACCEPT:
                 case WIFI_DISABLE_USER_REJECT:
+                case GROUP_NEGOTIATION_USER_ACCEPT:
+                case GROUP_NEGOTIATION_USER_REJECT:
+                case GROUP_INVITATION_USER_ACCEPT:
+                case GROUP_INVITATION_USER_REJECT:
                 case GROUP_NEGOTIATION_TIMED_OUT:
                     break;
                 default:
@@ -747,6 +767,7 @@
                 case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
                     mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj;
                     notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
+                    transitionTo(mUserAuthorizingGroupNegotiationState);
                     break;
                 case WifiP2pManager.CREATE_GROUP:
                     mPersistGroup = true;
@@ -761,6 +782,7 @@
                 case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
                     WifiP2pGroup group = (WifiP2pGroup) message.obj;
                     notifyP2pInvitationReceived(group);
+                    transitionTo(mUserAuthorizingGroupInvitationState);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -769,6 +791,70 @@
         }
     }
 
+    class UserAuthorizingGroupNegotiationState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
+                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
+                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
+                    //Ignore additional connection requests
+                    break;
+                case GROUP_NEGOTIATION_USER_ACCEPT:
+                    sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
+                    mSavedGoNegotiationConfig = null;
+                    break;
+                case GROUP_NEGOTIATION_USER_REJECT:
+                    if (DBG) logd("User rejected incoming negotiation request");
+                    mSavedGoNegotiationConfig = null;
+                    transitionTo(mInactiveState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+    class UserAuthorizingGroupInvitationState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
+                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
+                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
+                    //Ignore additional connection requests
+                    break;
+                case GROUP_INVITATION_USER_ACCEPT:
+                    if (DBG) logd(getName() + " connect to invited group");
+                    WifiP2pConfig config = new WifiP2pConfig();
+                    config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
+                    sendMessage(WifiP2pManager.CONNECT, config);
+                    mSavedP2pGroup = null;
+                    break;
+                case GROUP_INVITATION_USER_REJECT:
+                    if (DBG) logd("User rejected incoming invitation request");
+                    mSavedP2pGroup = null;
+                    transitionTo(mInactiveState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+
     class GroupNegotiationState extends State {
         @Override
         public void enter() {
@@ -1091,15 +1177,14 @@
                                 mSavedGoNegotiationConfig.wps.setup = WpsInfo.KEYPAD;
                                 mSavedGoNegotiationConfig.wps.pin = pin.getText().toString();
                             }
-                            sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
-                            mSavedGoNegotiationConfig = null;
+                            sendMessage(GROUP_NEGOTIATION_USER_ACCEPT);
                         }
                     })
             .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
                             if (DBG) logd(getName() + " ignore connect");
-                            mSavedGoNegotiationConfig = null;
+                            sendMessage(GROUP_NEGOTIATION_USER_REJECT);
                         }
                     })
             .create();
@@ -1180,14 +1265,16 @@
             .setView(textEntryView)
             .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
-                                WifiP2pConfig config = new WifiP2pConfig();
-                                config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
-                                if (DBG) logd(getName() + " connect to invited group");
-                                sendMessage(WifiP2pManager.CONNECT, config);
-                                mSavedP2pGroup = null;
+                            sendMessage(GROUP_INVITATION_USER_ACCEPT);
                         }
                     })
-            .setNegativeButton(r.getString(R.string.cancel), null)
+            .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            if (DBG) logd(getName() + " ignore invite");
+                            sendMessage(GROUP_INVITATION_USER_REJECT);
+                        }
+                    })
             .create();
 
         pin.setVisibility(View.GONE);