am b8814dce: Merge "Allow sniffers to return a packet of opaque data that the corresponding extractor can take advantage of to not duplicate work already done sniffing. The mp3 extractor takes advantage of this now." into gingerbread

Merge commit 'b8814dce287552c1bdf13fa999296ebc7387776d' into gingerbread-plus-aosp

* commit 'b8814dce287552c1bdf13fa999296ebc7387776d':
  Allow sniffers to return a packet of opaque data that the corresponding extractor can take advantage of to not duplicate work already done sniffing. The mp3 extractor takes advantage of this now.
diff --git a/api/current.xml b/api/current.xml
index 38756d3..fefaaea 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -22877,6 +22877,18 @@
 <parameter name="context" type="android.content.Context">
 </parameter>
 </constructor>
+<constructor name="AlertDialog.Builder"
+ type="android.app.AlertDialog.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="theme" type="int">
+</parameter>
+</constructor>
 <method name="create"
  return="android.app.AlertDialog"
  abstract="false"
@@ -56505,6 +56517,42 @@
 <parameter name="table" type="java.lang.String">
 </parameter>
 </method>
+<method name="queryNumEntries"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="db" type="android.database.sqlite.SQLiteDatabase">
+</parameter>
+<parameter name="table" type="java.lang.String">
+</parameter>
+<parameter name="selection" type="java.lang.String">
+</parameter>
+</method>
+<method name="queryNumEntries"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="db" type="android.database.sqlite.SQLiteDatabase">
+</parameter>
+<parameter name="table" type="java.lang.String">
+</parameter>
+<parameter name="selection" type="java.lang.String">
+</parameter>
+<parameter name="selectionArgs" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="readExceptionFromParcel"
  return="void"
  abstract="false"
@@ -208453,6 +208501,32 @@
 <parameter name="object" type="T">
 </parameter>
 </method>
+<method name="addAll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="collection" type="java.util.Collection&lt;? extends T&gt;">
+</parameter>
+</method>
+<method name="addAll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="items" type="T...">
+</parameter>
+</method>
 <method name="clear"
  return="void"
  abstract="false"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 7a7f8ed..9fe1fb8 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -49,6 +49,9 @@
 
 #include "BootAnimation.h"
 
+#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
+#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
+
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -244,12 +247,12 @@
     mFlingerSurfaceControl = control;
     mFlingerSurface = s;
 
-    mAndroidAnimation = false;
-    status_t err = mZip.open("/data/local/bootanimation.zip");
-    if (err != NO_ERROR) {
-        err = mZip.open("/system/media/bootanimation.zip");
-        if (err != NO_ERROR) {
-            mAndroidAnimation = true;
+    mAndroidAnimation = true;
+    if ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) ||
+        (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0)) {
+        if ((mZip.open(USER_BOOTANIMATION_FILE) != NO_ERROR) ||
+            (mZip.open(SYSTEM_BOOTANIMATION_FILE) != NO_ERROR)) {
+            mAndroidAnimation = false;
         }
     }
 
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 2714de5..61a8fc3 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -265,12 +265,22 @@
     
     public static class Builder {
         private final AlertController.AlertParams P;
+        private int mTheme;
         
         /**
          * Constructor using a context for this builder and the {@link AlertDialog} it creates.
          */
         public Builder(Context context) {
+            this(context, com.android.internal.R.style.Theme_Dialog_Alert);
+        }
+
+        /**
+         * Constructor using a context and theme for this builder and
+         * the {@link AlertDialog} it creates.
+         */
+        public Builder(Context context, int theme) {
             P = new AlertController.AlertParams(context);
+            mTheme = theme;
         }
         
         /**
@@ -783,7 +793,7 @@
          * to do and want this to be created and displayed.
          */
         public AlertDialog create() {
-            final AlertDialog dialog = new AlertDialog(P.mContext);
+            final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
             P.apply(dialog.mAlert);
             dialog.setCancelable(P.mCancelable);
             dialog.setOnCancelListener(P.mOnCancelListener);
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 8f940d5..2382596 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -188,7 +188,7 @@
     /**
      * Return activity in receiverPackage that handles ACTION_APP_ERROR.
      *
-     * @param pm PackageManager isntance
+     * @param pm PackageManager instance
      * @param errorPackage package which caused the error
      * @param receiverPackage candidate package to receive the error
      * @return activity component within receiverPackage which handles
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 2870c50..e7eb03e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -53,7 +53,6 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageParser.Package;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -86,11 +85,9 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.StatFs;
 import android.os.Vibrator;
 import android.os.FileUtils.FileStatus;
 import android.os.storage.StorageManager;
-import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.ClipboardManager;
 import android.util.AndroidRuntimeException;
@@ -210,7 +207,7 @@
     private File mCacheDir;
     private File mExternalFilesDir;
     private File mExternalCacheDir;
-    
+
     private static long sInstanceCount = 0;
 
     private static final String[] EMPTY_FILE_LIST = {};
@@ -262,18 +259,18 @@
     public Looper getMainLooper() {
         return mMainThread.getLooper();
     }
-    
+
     @Override
     public Context getApplicationContext() {
         return (mPackageInfo != null) ?
                 mPackageInfo.getApplication() : mMainThread.getApplication();
     }
-    
+
     @Override
     public void setTheme(int resid) {
         mThemeResource = resid;
     }
-    
+
     @Override
     public Resources.Theme getTheme() {
         if (mTheme == null) {
@@ -323,7 +320,7 @@
         }
         throw new RuntimeException("Not supported in system context");
     }
-    
+
     private static File makeBackupFile(File prefsFile) {
         return new File(prefsFile.getPath() + ".bak");
     }
@@ -343,7 +340,7 @@
                 return sp;
             }
         }
-        
+
         FileInputStream str = null;
         File backup = makeBackupFile(f);
         if (backup.exists()) {
@@ -355,7 +352,7 @@
         if (f.exists() && !f.canRead()) {
             Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
         }
-        
+
         Map map = null;
         if (f.exists() && f.canRead()) {
             try {
@@ -439,7 +436,7 @@
             }
             if (!mFilesDir.exists()) {
                 if(!mFilesDir.mkdirs()) {
-                    Log.w(TAG, "Unable to create files directory");
+                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
                     return null;
                 }
                 FileUtils.setPermissions(
@@ -450,7 +447,7 @@
             return mFilesDir;
         }
     }
-    
+
     @Override
     public File getExternalFilesDir(String type) {
         synchronized (mSync) {
@@ -482,7 +479,7 @@
             return dir;
         }
     }
-    
+
     @Override
     public File getCacheDir() {
         synchronized (mSync) {
@@ -502,7 +499,7 @@
         }
         return mCacheDir;
     }
-    
+
     @Override
     public File getExternalCacheDir() {
         synchronized (mSync) {
@@ -524,7 +521,7 @@
             return mExternalCacheDir;
         }
     }
-    
+
     @Override
     public File getFileStreamPath(String name) {
         return makeFilename(getFilesDir(), name);
@@ -565,7 +562,7 @@
         return (list != null) ? list : EMPTY_FILE_LIST;
     }
 
-    
+
     private File getDatabasesDir() {
         synchronized (mSync) {
             if (mDatabasesDir == null) {
@@ -577,7 +574,7 @@
             return mDatabasesDir;
         }
     }
-    
+
     @Override
     public Drawable getWallpaper() {
         return getWallpaperManager().getDrawable();
@@ -645,7 +642,7 @@
         } catch (RemoteException e) {
         }
     }
-    
+
     @Override
     public void sendBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
@@ -1558,15 +1555,15 @@
     final void setActivityToken(IBinder token) {
         mActivityToken = token;
     }
-    
+
     final void setOuterContext(Context context) {
         mOuterContext = context;
     }
-    
+
     final Context getOuterContext() {
         return mOuterContext;
     }
-    
+
     final IBinder getActivityToken() {
         return mActivityToken;
     }
@@ -1643,7 +1640,7 @@
         {
             return mMainThread.releaseProvider(provider);
         }
-        
+
         private final ActivityThread mMainThread;
     }
 
@@ -1676,7 +1673,7 @@
                 throw new RuntimeException("Package manager has died", e);
             }
         }
-        
+
         @Override
         public String[] canonicalToCurrentPackageNames(String[] names) {
             try {
@@ -1685,7 +1682,7 @@
                 throw new RuntimeException("Package manager has died", e);
             }
         }
-        
+
         @Override
         public Intent getLaunchIntentForPackage(String packageName) {
             // First see if the package has an INFO activity; the existence of
@@ -1707,8 +1704,9 @@
             if (resolveInfo == null) {
                 return null;
             }
-            Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName(packageName, resolveInfo.activityInfo.name);
+            Intent intent = new Intent(intentToResolve);
+            intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
+                                resolveInfo.activityInfo.name);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             return intent;
         }
@@ -1859,7 +1857,7 @@
                 throw new RuntimeException("Package manager has died", e);
             }
         }
-        
+
         @Override
         public boolean hasSystemFeature(String name) {
             try {
@@ -1868,7 +1866,7 @@
                 throw new RuntimeException("Package manager has died", e);
             }
         }
-        
+
         @Override
         public int checkPermission(String permName, String pkgName) {
             try {
@@ -1940,9 +1938,9 @@
                 throw new RuntimeException("Package manager has died", e);
             }
         }
-        
+
         @Override
-        public int getUidForSharedUser(String sharedUserName) 
+        public int getUidForSharedUser(String sharedUserName)
                 throws NameNotFoundException {
             try {
                 int uid = mPM.getUidForSharedUser(sharedUserName);
@@ -2346,7 +2344,7 @@
                 }
             }
         }
-        
+
         private static final class ResourceName {
             final String packageName;
             final int iconId;
@@ -2518,7 +2516,7 @@
             }
         }
         @Override
-        public void clearApplicationUserData(String packageName, 
+        public void clearApplicationUserData(String packageName,
                 IPackageDataObserver observer) {
             try {
                 mPM.clearApplicationUserData(packageName, observer);
@@ -2527,7 +2525,7 @@
             }
         }
         @Override
-        public void deleteApplicationCacheFiles(String packageName, 
+        public void deleteApplicationCacheFiles(String packageName,
                 IPackageDataObserver observer) {
             try {
                 mPM.deleteApplicationCacheFiles(packageName, observer);
@@ -2552,9 +2550,9 @@
                 // Should never happen!
             }
         }
-        
+
         @Override
-        public void getPackageSizeInfo(String packageName, 
+        public void getPackageSizeInfo(String packageName,
                 IPackageStatsObserver observer) {
             try {
                 mPM.getPackageSizeInfo(packageName, observer);
@@ -2599,7 +2597,7 @@
                 // Should never happen!
             }
         }
-        
+
         @Override
         public void replacePreferredActivity(IntentFilter filter,
                 int match, ComponentName[] set, ComponentName activity) {
@@ -2618,7 +2616,7 @@
                 // Should never happen!
             }
         }
-        
+
         @Override
         public int getPreferredActivities(List<IntentFilter> outFilters,
                 List<ComponentName> outActivities, String packageName) {
@@ -2629,7 +2627,7 @@
             }
             return 0;
         }
-        
+
         @Override
         public void setComponentEnabledSetting(ComponentName componentName,
                 int newState, int flags) {
@@ -2659,7 +2657,7 @@
                 // Should never happen!
             }
         }
-        
+
         @Override
         public int getApplicationEnabledSetting(String packageName) {
             try {
@@ -2725,7 +2723,7 @@
                 return mTimestamp != mFileStatus.mtime;
             }
         }
-        
+
         public void replace(Map newContents) {
             if (newContents != null) {
                 synchronized (this) {
@@ -2733,7 +2731,7 @@
                 }
             }
         }
-        
+
         public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
             synchronized(this) {
                 mListeners.put(listener, mContent);
@@ -2914,7 +2912,7 @@
         public Editor edit() {
             return new EditorImpl();
         }
-        
+
         private FileOutputStream createFileOutputStream(File file) {
             FileOutputStream str = null;
             try {
@@ -2958,7 +2956,7 @@
                     mFile.delete();
                 }
             }
-            
+
             // Attempt to write the file, delete the backup and return true as atomically as
             // possible.  If any exception occurs, delete the new file; next time we will restore
             // from the backup.
@@ -2973,7 +2971,7 @@
                 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
                     mTimestamp = mFileStatus.mtime;
                 }
-                
+
                 // Writing was successful, delete the backup file if there is one.
                 mBackupFile.delete();
                 return true;
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 009671f..8ba480d 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -21,7 +21,6 @@
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
 import android.text.TextUtils.TruncateAt;
-import android.text.format.DateFormat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.DatePicker;
@@ -39,13 +38,13 @@
  * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
  * tutorial</a>.</p>
  */
-public class DatePickerDialog extends AlertDialog implements OnClickListener, 
+public class DatePickerDialog extends AlertDialog implements OnClickListener,
         OnDateChangedListener {
 
     private static final String YEAR = "year";
     private static final String MONTH = "month";
     private static final String DAY = "day";
-    
+
     private final DatePicker mDatePicker;
     private final OnDateSetListener mCallBack;
     private final Calendar mCalendar;
@@ -83,7 +82,7 @@
             int year,
             int monthOfYear,
             int dayOfMonth) {
-        this(context, com.android.internal.R.style.Theme_Dialog_Alert, 
+        this(context, com.android.internal.R.style.Theme_Dialog_Alert,
                 callBack, year, monthOfYear, dayOfMonth);
     }
 
@@ -109,17 +108,17 @@
         mInitialDay = dayOfMonth;
         DateFormatSymbols symbols = new DateFormatSymbols();
         mWeekDays = symbols.getShortWeekdays();
-        
+
         mTitleDateFormat = java.text.DateFormat.
                                 getDateInstance(java.text.DateFormat.FULL);
         mCalendar = Calendar.getInstance();
         updateTitle(mInitialYear, mInitialMonth, mInitialDay);
-        
-        setButton(context.getText(R.string.date_time_set), this);
-        setButton2(context.getText(R.string.cancel), (OnClickListener) null);
+
+        setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
+        setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), (OnClickListener) null);
         setIcon(R.drawable.ic_dialog_time);
-        
-        LayoutInflater inflater = 
+
+        LayoutInflater inflater =
                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = inflater.inflate(R.layout.date_picker_dialog, null);
         setView(view);
@@ -139,20 +138,20 @@
         title.setSingleLine();
         title.setEllipsize(TruncateAt.END);
     }
-    
+
     public void onClick(DialogInterface dialog, int which) {
         if (mCallBack != null) {
             mDatePicker.clearFocus();
-            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), 
+            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
                     mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
         }
     }
-    
+
     public void onDateChanged(DatePicker view, int year,
             int month, int day) {
         updateTitle(year, month, day);
     }
-    
+
     public void updateDate(int year, int monthOfYear, int dayOfMonth) {
         mInitialYear = year;
         mInitialMonth = monthOfYear;
@@ -166,7 +165,7 @@
         mCalendar.set(Calendar.DAY_OF_MONTH, day);
         setTitle(mTitleDateFormat.format(mCalendar.getTime()));
     }
-    
+
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
@@ -175,7 +174,7 @@
         state.putInt(DAY, mDatePicker.getDayOfMonth());
         return state;
     }
-    
+
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 7625c04..2fb746c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1131,7 +1131,7 @@
         try {
             // If the intent was created from a suggestion, it will always have an explicit
             // component here.
-            Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI());
+            Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toUri(0));
             getContext().startActivity(intent);
             // If the search switches to a different activity,
             // SearchDialogWrapper#performActivityResuming
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 62d3f7d..521d41c 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -36,7 +36,7 @@
  * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
  * tutorial</a>.</p>
  */
-public class TimePickerDialog extends AlertDialog implements OnClickListener, 
+public class TimePickerDialog extends AlertDialog implements OnClickListener,
         OnTimeChangedListener {
 
     /**
@@ -56,12 +56,12 @@
     private static final String HOUR = "hour";
     private static final String MINUTE = "minute";
     private static final String IS_24_HOUR = "is24hour";
-    
+
     private final TimePicker mTimePicker;
     private final OnTimeSetListener mCallback;
     private final Calendar mCalendar;
     private final java.text.DateFormat mDateFormat;
-    
+
     int mInitialHourOfDay;
     int mInitialMinute;
     boolean mIs24HourView;
@@ -101,12 +101,13 @@
         mDateFormat = DateFormat.getTimeFormat(context);
         mCalendar = Calendar.getInstance();
         updateTitle(mInitialHourOfDay, mInitialMinute);
-        
-        setButton(context.getText(R.string.date_time_set), this);
-        setButton2(context.getText(R.string.cancel), (OnClickListener) null);
+
+        setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
+        setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel),
+                (OnClickListener) null);
         setIcon(R.drawable.ic_dialog_time);
-        
-        LayoutInflater inflater = 
+
+        LayoutInflater inflater =
                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = inflater.inflate(R.layout.time_picker_dialog, null);
         setView(view);
@@ -118,11 +119,11 @@
         mTimePicker.setIs24HourView(mIs24HourView);
         mTimePicker.setOnTimeChangedListener(this);
     }
-    
+
     public void onClick(DialogInterface dialog, int which) {
         if (mCallback != null) {
             mTimePicker.clearFocus();
-            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), 
+            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                     mTimePicker.getCurrentMinute());
         }
     }
@@ -130,7 +131,7 @@
     public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
         updateTitle(hourOfDay, minute);
     }
-    
+
     public void updateTime(int hourOfDay, int minutOfHour) {
         mTimePicker.setCurrentHour(hourOfDay);
         mTimePicker.setCurrentMinute(minutOfHour);
@@ -141,7 +142,7 @@
         mCalendar.set(Calendar.MINUTE, minute);
         setTitle(mDateFormat.format(mCalendar.getTime()));
     }
-    
+
     @Override
     public Bundle onSaveInstanceState() {
         Bundle state = super.onSaveInstanceState();
@@ -150,7 +151,7 @@
         state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
         return state;
     }
-    
+
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d4ce6a1..d2ab85e 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -22,7 +22,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
 import android.widget.RemoteViews;
 
@@ -149,7 +148,7 @@
      *     instances as possible.</td>
      *  </tr>
      * </table>
-     * 
+     *
      * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
      */
     public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
@@ -163,7 +162,7 @@
 
     /**
      * Sent when an instance of an AppWidget is removed from the last host.
-     * 
+     *
      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
      */
     public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
@@ -172,7 +171,7 @@
      * Sent when an instance of an AppWidget is added to a host for the first time.
      * This broadcast is sent at boot time if there is a AppWidgetHost installed with
      * an instance for this provider.
-     * 
+     *
      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
      */
     public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
@@ -183,20 +182,21 @@
      * @see AppWidgetProviderInfo
      */
     public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
-    
+
     /**
      * Field for the manifest meta-data tag used to indicate any previous name for the
      * app widget receiver.
      *
      * @see AppWidgetProviderInfo
-     * 
+     *
      * @hide Pending API approval
      */
     public static final String META_DATA_APPWIDGET_OLD_NAME = "android.appwidget.oldName";
 
-    static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache = new WeakHashMap();
+    static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
+        new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
     static IAppWidgetService sService;
-    
+
     Context mContext;
 
     private DisplayMetrics mDisplayMetrics;
@@ -219,7 +219,7 @@
             }
             if (result == null) {
                 result = new AppWidgetManager(context);
-                sManagerCache.put(context, new WeakReference(result));
+                sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
             }
             return result;
         }
@@ -310,7 +310,7 @@
             AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId);
             if (info != null) {
                 // Converting complex to dp.
-                info.minWidth = 
+                info.minWidth =
                         TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
                 info.minHeight =
                         TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
@@ -344,7 +344,7 @@
     /**
      * Get the list of appWidgetIds that have been bound to the given AppWidget
      * provider.
-     * 
+     *
      * @param provider The {@link android.content.BroadcastReceiver} that is the
      *            AppWidget provider to find appWidgetIds for.
      */
diff --git a/core/java/android/bluetooth/AtCommandHandler.java b/core/java/android/bluetooth/AtCommandHandler.java
index 8de2133..6deab34 100644
--- a/core/java/android/bluetooth/AtCommandHandler.java
+++ b/core/java/android/bluetooth/AtCommandHandler.java
@@ -73,7 +73,7 @@
      *             least one element in this array.
      * @return     The result of this command.
      */
-    // Typically used to set this paramter
+    // Typically used to set this parameter
     public AtCommandResult handleSetCommand(Object[] args) {
         return new AtCommandResult(AtCommandResult.ERROR);
     }
@@ -83,11 +83,12 @@
      * Test commands are part of the Extended command syntax, and are typically
      * used to request an indication of the range of legal values that "FOO"
      * can take.<p>
-     * By defualt we return an OK result, to indicate that this command is at
+     * By default we return an OK result, to indicate that this command is at
      * least recognized.<p>
      * @return The result of this command.
      */
     public AtCommandResult handleTestCommand() {
         return new AtCommandResult(AtCommandResult.OK);
     }
+
 }
diff --git a/core/java/android/bluetooth/BluetoothAssignedNumbers.java b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
new file mode 100644
index 0000000..55bc814
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+/**
+ * Bluetooth Assigned Numbers.
+ * <p>
+ * For now we only include Company ID values.
+ * @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm">
+ * The Official Bluetooth SIG Member Website | Company Identifiers</a>
+ *
+ * @hide
+ */
+public class BluetoothAssignedNumbers {
+
+    //// Bluetooth SIG Company ID values
+
+    /*
+     * Ericsson Technology Licensing.
+     */
+    public static final int ERICSSON_TECHNOLOGY = 0x0000;
+
+    /*
+     * Nokia Mobile Phones.
+     */
+    public static final int NOKIA_MOBILE_PHONES = 0x0001;
+
+    /*
+     * Intel Corp.
+     */
+    public static final int INTEL = 0x0002;
+
+    /*
+     * IBM Corp.
+     */
+    public static final int IBM = 0x0003;
+
+    /*
+     * Toshiba Corp.
+     */
+    public static final int TOSHIBA = 0x0004;
+
+    /*
+     * 3Com.
+     */
+    public static final int THREECOM = 0x0005;
+
+    /*
+     * Microsoft.
+     */
+    public static final int MICROSOFT = 0x0006;
+
+    /*
+     * Lucent.
+     */
+    public static final int LUCENT = 0x0007;
+
+    /*
+     * Motorola.
+     */
+    public static final int MOTOROLA = 0x0008;
+
+    /*
+     * Infineon Technologies AG.
+     */
+    public static final int INFINEON_TECHNOLOGIES = 0x0009;
+
+    /*
+     * Cambridge Silicon Radio.
+     */
+    public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
+
+    /*
+     * Silicon Wave.
+     */
+    public static final int SILICON_WAVE = 0x000B;
+
+    /*
+     * Digianswer A/S.
+     */
+    public static final int DIGIANSWER = 0x000C;
+
+    /*
+     * Texas Instruments Inc.
+     */
+    public static final int TEXAS_INSTRUMENTS = 0x000D;
+
+    /*
+     * Parthus Technologies Inc.
+     */
+    public static final int PARTHUS_TECHNOLOGIES = 0x000E;
+
+    /*
+     * Broadcom Corporation.
+     */
+    public static final int BROADCOM = 0x000F;
+
+    /*
+     * Mitel Semiconductor.
+     */
+    public static final int MITEL_SEMICONDUCTOR = 0x0010;
+
+    /*
+     * Widcomm, Inc.
+     */
+    public static final int WIDCOMM = 0x0011;
+
+    /*
+     * Zeevo, Inc.
+     */
+    public static final int ZEEVO = 0x0012;
+
+    /*
+     * Atmel Corporation.
+     */
+    public static final int ATMEL = 0x0013;
+
+    /*
+     * Mitsubishi Electric Corporation.
+     */
+    public static final int MITSUBISHI_ELECTRIC = 0x0014;
+
+    /*
+     * RTX Telecom A/S.
+     */
+    public static final int RTX_TELECOM = 0x0015;
+
+    /*
+     * KC Technology Inc.
+     */
+    public static final int KC_TECHNOLOGY = 0x0016;
+
+    /*
+     * Newlogic.
+     */
+    public static final int NEWLOGIC = 0x0017;
+
+    /*
+     * Transilica, Inc.
+     */
+    public static final int TRANSILICA = 0x0018;
+
+    /*
+     * Rohde & Schwarz GmbH & Co. KG.
+     */
+    public static final int ROHDE_AND_SCHWARZ = 0x0019;
+
+    /*
+     * TTPCom Limited.
+     */
+    public static final int TTPCOM = 0x001A;
+
+    /*
+     * Signia Technologies, Inc.
+     */
+    public static final int SIGNIA_TECHNOLOGIES = 0x001B;
+
+    /*
+     * Conexant Systems Inc.
+     */
+    public static final int CONEXANT_SYSTEMS = 0x001C;
+
+    /*
+     * Qualcomm.
+     */
+    public static final int QUALCOMM = 0x001D;
+
+    /*
+     * Inventel.
+     */
+    public static final int INVENTEL = 0x001E;
+
+    /*
+     * AVM Berlin.
+     */
+    public static final int AVM_BERLIN = 0x001F;
+
+    /*
+     * BandSpeed, Inc.
+     */
+    public static final int BANDSPEED = 0x0020;
+
+    /*
+     * Mansella Ltd.
+     */
+    public static final int MANSELLA = 0x0021;
+
+    /*
+     * NEC Corporation.
+     */
+    public static final int NEC = 0x0022;
+
+    /*
+     * WavePlus Technology Co., Ltd.
+     */
+    public static final int WAVEPLUS_TECHNOLOGY = 0x0023;
+
+    /*
+     * Alcatel.
+     */
+    public static final int ALCATEL = 0x0024;
+
+    /*
+     * Philips Semiconductors.
+     */
+    public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
+
+    /*
+     * C Technologies.
+     */
+    public static final int C_TECHNOLOGIES = 0x0026;
+
+    /*
+     * Open Interface.
+     */
+    public static final int OPEN_INTERFACE = 0x0027;
+
+    /*
+     * R F Micro Devices.
+     */
+    public static final int RF_MICRO_DEVICES = 0x0028;
+
+    /*
+     * Hitachi Ltd.
+     */
+    public static final int HITACHI = 0x0029;
+
+    /*
+     * Symbol Technologies, Inc.
+     */
+    public static final int SYMBOL_TECHNOLOGIES = 0x002A;
+
+    /*
+     * Tenovis.
+     */
+    public static final int TENOVIS = 0x002B;
+
+    /*
+     * Macronix International Co. Ltd.
+     */
+    public static final int MACRONIX = 0x002C;
+
+    /*
+     * GCT Semiconductor.
+     */
+    public static final int GCT_SEMICONDUCTOR = 0x002D;
+
+    /*
+     * Norwood Systems.
+     */
+    public static final int NORWOOD_SYSTEMS = 0x002E;
+
+    /*
+     * MewTel Technology Inc.
+     */
+    public static final int MEWTEL_TECHNOLOGY = 0x002F;
+
+    /*
+     * ST Microelectronics.
+     */
+    public static final int ST_MICROELECTRONICS = 0x0030;
+
+    /*
+     * Synopsys.
+     */
+    public static final int SYNOPSYS = 0x0031;
+
+    /*
+     * Red-M (Communications) Ltd.
+     */
+    public static final int RED_M = 0x0032;
+
+    /*
+     * Commil Ltd.
+     */
+    public static final int COMMIL = 0x0033;
+
+    /*
+     * Computer Access Technology Corporation (CATC).
+     */
+    public static final int CATC = 0x0034;
+
+    /*
+     * Eclipse (HQ Espana) S.L.
+     */
+    public static final int ECLIPSE = 0x0035;
+
+    /*
+     * Renesas Technology Corp.
+     */
+    public static final int RENESAS_TECHNOLOGY = 0x0036;
+
+    /*
+     * Mobilian Corporation.
+     */
+    public static final int MOBILIAN_CORPORATION = 0x0037;
+
+    /*
+     * Terax.
+     */
+    public static final int TERAX = 0x0038;
+
+    /*
+     * Integrated System Solution Corp.
+     */
+    public static final int INTEGRATED_SYSTEM_SOLUTION = 0x0039;
+
+    /*
+     * Matsushita Electric Industrial Co., Ltd.
+     */
+    public static final int MATSUSHITA_ELECTRIC = 0x003A;
+
+    /*
+     * Gennum Corporation.
+     */
+    public static final int GENNUM = 0x003B;
+
+    /*
+     * Research In Motion.
+     */
+    public static final int RESEARCH_IN_MOTION = 0x003C;
+
+    /*
+     * IPextreme, Inc.
+     */
+    public static final int IPEXTREME = 0x003D;
+
+    /*
+     * Systems and Chips, Inc.
+     */
+    public static final int SYSTEMS_AND_CHIPS = 0x003E;
+
+    /*
+     * Bluetooth SIG, Inc.
+     */
+    public static final int BLUETOOTH_SIG = 0x003F;
+
+    /*
+     * Seiko Epson Corporation.
+     */
+    public static final int SEIKO_EPSON = 0x0040;
+
+    /*
+     * Integrated Silicon Solution Taiwan, Inc.
+     */
+    public static final int INTEGRATED_SILICON_SOLUTION = 0x0041;
+
+    /*
+     * CONWISE Technology Corporation Ltd.
+     */
+    public static final int CONWISE_TECHNOLOGY = 0x0042;
+
+    /*
+     * PARROT SA.
+     */
+    public static final int PARROT = 0x0043;
+
+    /*
+     * Socket Mobile.
+     */
+    public static final int SOCKET_MOBILE = 0x0044;
+
+    /*
+     * Atheros Communications, Inc.
+     */
+    public static final int ATHEROS_COMMUNICATIONS = 0x0045;
+
+    /*
+     * MediaTek, Inc.
+     */
+    public static final int MEDIATEK = 0x0046;
+
+    /*
+     * Bluegiga.
+     */
+    public static final int BLUEGIGA = 0x0047;
+
+    /*
+     * Marvell Technology Group Ltd.
+     */
+    public static final int MARVELL = 0x0048;
+
+    /*
+     * 3DSP Corporation.
+     */
+    public static final int THREE_DSP = 0x0049;
+
+    /*
+     * Accel Semiconductor Ltd.
+     */
+    public static final int ACCEL_SEMICONDUCTOR = 0x004A;
+
+    /*
+     * Continental Automotive Systems.
+     */
+    public static final int CONTINENTAL_AUTOMOTIVE = 0x004B;
+
+    /*
+     * Apple, Inc.
+     */
+    public static final int APPLE = 0x004C;
+
+    /*
+     * Staccato Communications, Inc.
+     */
+    public static final int STACCATO_COMMUNICATIONS = 0x004D;
+
+    /*
+     * Avago Technologies.
+     */
+    public static final int AVAGO = 0x004E;
+
+    /*
+     * APT Licensing Ltd.
+     */
+    public static final int APT_LICENSING = 0x004F;
+
+    /*
+     * SiRF Technology, Inc.
+     */
+    public static final int SIRF_TECHNOLOGY = 0x0050;
+
+    /*
+     * Tzero Technologies, Inc.
+     */
+    public static final int TZERO_TECHNOLOGIES = 0x0051;
+
+    /*
+     * J&M Corporation.
+     */
+    public static final int J_AND_M = 0x0052;
+
+    /*
+     * Free2move AB.
+     */
+    public static final int FREE2MOVE = 0x0053;
+
+    /*
+     * 3DiJoy Corporation.
+     */
+    public static final int THREE_DIJOY = 0x0054;
+
+    /*
+     * Plantronics, Inc.
+     */
+    public static final int PLANTRONICS = 0x0055;
+
+    /*
+     * Sony Ericsson Mobile Communications.
+     */
+    public static final int SONY_ERICSSON = 0x0056;
+
+    /*
+     * Harman International Industries, Inc.
+     */
+    public static final int HARMAN_INTERNATIONAL = 0x0057;
+
+    /*
+     * Vizio, Inc.
+     */
+    public static final int VIZIO = 0x0058;
+
+    /*
+     * Nordic Semiconductor ASA.
+     */
+    public static final int NORDIC_SEMICONDUCTOR = 0x0059;
+
+    /*
+     * EM Microelectronic-Marin SA.
+     */
+    public static final int EM_MICROELECTRONIC_MARIN = 0x005A;
+
+    /*
+     * Ralink Technology Corporation.
+     */
+    public static final int RALINK_TECHNOLOGY = 0x005B;
+
+    /*
+     * Belkin International, Inc.
+     */
+    public static final int BELKIN_INTERNATIONAL = 0x005C;
+
+    /*
+     * Realtek Semiconductor Corporation.
+     */
+    public static final int REALTEK_SEMICONDUCTOR = 0x005D;
+
+    /*
+     * Stonestreet One, LLC.
+     */
+    public static final int STONESTREET_ONE = 0x005E;
+
+    /*
+     * Wicentric, Inc.
+     */
+    public static final int WICENTRIC = 0x005F;
+
+    /*
+     * RivieraWaves S.A.S.
+     */
+    public static final int RIVIERAWAVES = 0x0060;
+
+    /*
+     * You can't instantiate one of these.
+     */
+    private BluetoothAssignedNumbers() {
+    }
+
+}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 4a91a8c..53d6a37 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -45,7 +45,7 @@
  * This BluetoothHeadset object is not immediately bound to the
  * BluetoothHeadset service. Use the ServiceListener interface to obtain a
  * notification when it is bound, this is especially important if you wish to
- * immediately call methods on BluetootHeadset after construction.
+ * immediately call methods on BluetoothHeadset after construction.
  *
  * Android only supports one connected Bluetooth Headset at a time.
  *
@@ -85,6 +85,43 @@
             "android.bluetooth.headset.extra.DISCONNECT_INITIATOR";
 
     /**
+     * Broadcast Action: Indicates a headset has posted a vendor-specific event.
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE},
+     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD}, and
+     * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
+            "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
+
+    /**
+     * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
+     * intents that contains the name of the vendor-specific command.
+     */
+    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
+            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
+
+    /**
+     * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
+     * intents that contains the Company ID of the vendor defining the vendor-specific
+     * command.
+     * @see <a href="https://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm">
+     * Bluetooth SIG Assigned Numbers - Company Identifiers</a>
+     */
+    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID =
+            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID";
+
+    /**
+     * A Parcelable String array extra field in
+     * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
+     * the arguments to the vendor-specific command.
+     */
+    public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
+            "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
+
+
+    /**
      * TODO(API release): Consider incorporating as new state in
      * HEADSET_STATE_CHANGED
      */
@@ -108,7 +145,7 @@
 
     public static final int RESULT_FAILURE = 0;
     public static final int RESULT_SUCCESS = 1;
-    /** Connection canceled before completetion. */
+    /** Connection canceled before completion. */
     public static final int RESULT_CANCELED = 2;
 
     /** Values for {@link #EXTRA_DISCONNECT_INITIATOR} */
diff --git a/core/java/android/bluetooth/HeadsetBase.java b/core/java/android/bluetooth/HeadsetBase.java
index e2935c9..9ef2eb5 100644
--- a/core/java/android/bluetooth/HeadsetBase.java
+++ b/core/java/android/bluetooth/HeadsetBase.java
@@ -74,8 +74,8 @@
 
     private native void cleanupNativeDataNative();
 
-    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
-            int rfcommChannel) {
+    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
+                       BluetoothDevice device, int rfcommChannel) {
         mDirection = DIRECTION_OUTGOING;
         mConnectTimestamp = System.currentTimeMillis();
         mAdapter = adapter;
@@ -89,9 +89,10 @@
         initializeNativeDataNative(-1);
     }
 
-    /* Create from an already exisiting rfcomm connection */
-    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
-            int socketFd, int rfcommChannel, Handler handler) {
+    /* Create from an existing rfcomm connection */
+    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
+                       BluetoothDevice device,
+                       int socketFd, int rfcommChannel, Handler handler) {
         mDirection = DIRECTION_INCOMING;
         mConnectTimestamp = System.currentTimeMillis();
         mAdapter = adapter;
@@ -128,7 +129,7 @@
                        (System.currentTimeMillis() - timestamp) + " ms");
 
         if (result.getResultCode() == AtCommandResult.ERROR) {
-            Log.i(TAG, "Error pocessing <" + input + ">");
+            Log.i(TAG, "Error processing <" + input + ">");
         }
 
         sendURC(result.toString());
@@ -142,8 +143,9 @@
      */
     protected void initializeAtParser() {
         mAtParser = new AtParser();
-        //TODO(): Get rid of this as there are no parsers registered. But because of dependencies,
-        //it needs to be done as part of refactoring HeadsetBase and BluetoothHandsfree
+
+        //TODO(): Get rid of this as there are no parsers registered. But because of dependencies
+        // it needs to be done as part of refactoring HeadsetBase and BluetoothHandsfree
     }
 
     public AtParser getAtParser() {
@@ -159,8 +161,7 @@
                         String input = readNative(500);
                         if (input != null) {
                             handleInput(input);
-                        }
-                        else {
+                        } else {
                             last_read_error = getLastReadStatusNative();
                             if (last_read_error != 0) {
                                 Log.i(TAG, "headset read error " + last_read_error);
@@ -179,8 +180,6 @@
         mEventThread.start();
     }
 
-
-
     private native String readNative(int timeout_ms);
     private native int getLastReadStatusNative();
 
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
old mode 100644
new mode 100755
index 9bb3b75..a6513aa
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -25,6 +25,7 @@
 import android.graphics.Movie;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable.ConstantState;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.SystemProperties;
@@ -66,6 +67,8 @@
             = new LongSparseArray<Drawable.ConstantState>();
     private static final SparseArray<ColorStateList> mPreloadedColorStateLists
             = new SparseArray<ColorStateList>();
+    private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
+            = new LongSparseArray<Drawable.ConstantState>();
     private static boolean mPreloaded;
 
     /*package*/ final TypedValue mTmpValue = new TypedValue();
@@ -75,6 +78,8 @@
             = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
     private final SparseArray<WeakReference<ColorStateList> > mColorStateListCache
             = new SparseArray<WeakReference<ColorStateList> >();
+    private final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
+            = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
     private boolean mPreloading;
 
     /*package*/ TypedArray mCachedStyledAttributes = null;
@@ -1299,37 +1304,13 @@
                     (int)(mMetrics.density*160), mConfiguration.keyboard,
                     keyboardHidden, mConfiguration.navigation, width, height,
                     mConfiguration.screenLayout, mConfiguration.uiMode, sSdkVersion);
-            int N = mDrawableCache.size();
-            if (DEBUG_CONFIG) {
-                Log.d(TAG, "Cleaning up drawables config changes: 0x"
-                        + Integer.toHexString(configChanges));
-            }
-            for (int i=0; i<N; i++) {
-                WeakReference<Drawable.ConstantState> ref = mDrawableCache.valueAt(i);
-                if (ref != null) {
-                    Drawable.ConstantState cs = ref.get();
-                    if (cs != null) {
-                        if (Configuration.needNewResources(
-                                configChanges, cs.getChangingConfigurations())) {
-                            if (DEBUG_CONFIG) {
-                                Log.d(TAG, "FLUSHING #0x"
-                                        + Long.toHexString(mDrawableCache.keyAt(i))
-                                        + " / " + cs + " with changes: 0x"
-                                        + Integer.toHexString(cs.getChangingConfigurations()));
-                            }
-                            mDrawableCache.setValueAt(i, null);
-                        } else if (DEBUG_CONFIG) {
-                            Log.d(TAG, "(Keeping #0x"
-                                    + Long.toHexString(mDrawableCache.keyAt(i))
-                                    + " / " + cs + " with changes: 0x"
-                                    + Integer.toHexString(cs.getChangingConfigurations())
-                                    + ")");
-                        }
-                    }
-                }
-            }
-            mDrawableCache.clear();
+
+            clearDrawableCache(mDrawableCache, configChanges);
+            clearDrawableCache(mColorDrawableCache, configChanges);
+
             mColorStateListCache.clear();
+
+
             flushLayoutCache();
         }
         synchronized (mSync) {
@@ -1339,6 +1320,41 @@
         }
     }
 
+    private void clearDrawableCache(
+            LongSparseArray<WeakReference<ConstantState>> cache,
+            int configChanges) {
+        int N = cache.size();
+        if (DEBUG_CONFIG) {
+            Log.d(TAG, "Cleaning up drawables config changes: 0x"
+                    + Integer.toHexString(configChanges));
+        }
+        for (int i=0; i<N; i++) {
+            WeakReference<Drawable.ConstantState> ref = cache.valueAt(i);
+            if (ref != null) {
+                Drawable.ConstantState cs = ref.get();
+                if (cs != null) {
+                    if (Configuration.needNewResources(
+                            configChanges, cs.getChangingConfigurations())) {
+                        if (DEBUG_CONFIG) {
+                            Log.d(TAG, "FLUSHING #0x"
+                                    + Long.toHexString(mDrawableCache.keyAt(i))
+                                    + " / " + cs + " with changes: 0x"
+                                    + Integer.toHexString(cs.getChangingConfigurations()));
+                        }
+                        cache.setValueAt(i, null);
+                    } else if (DEBUG_CONFIG) {
+                        Log.d(TAG, "(Keeping #0x"
+                                + Long.toHexString(cache.keyAt(i))
+                                + " / " + cs + " with changes: 0x"
+                                + Integer.toHexString(cs.getChangingConfigurations())
+                                + ")");
+                    }
+                }
+            }
+        }
+        cache.clear();
+    }
+
     /**
      * Update the system resources configuration if they have previously
      * been initialized.
@@ -1661,13 +1677,18 @@
         }
 
         final long key = (((long) value.assetCookie) << 32) | value.data;
-        Drawable dr = getCachedDrawable(key);
+        boolean isColorDrawable = false;
+        if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
+                value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+            isColorDrawable = true;
+        }
+        Drawable dr = getCachedDrawable(isColorDrawable ? mColorDrawableCache : mDrawableCache, key);
 
         if (dr != null) {
             return dr;
         }
 
-        Drawable.ConstantState cs = sPreloadedDrawables.get(key);
+        Drawable.ConstantState cs = isColorDrawable ? sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
         if (cs != null) {
             dr = cs.newDrawable(this);
         } else {
@@ -1726,13 +1747,21 @@
             cs = dr.getConstantState();
             if (cs != null) {
                 if (mPreloading) {
-                    sPreloadedDrawables.put(key, cs);
+                    if (isColorDrawable) {
+                        sPreloadedColorDrawables.put(key, cs);
+                    } else {
+                        sPreloadedDrawables.put(key, cs);
+                    }
                 } else {
                     synchronized (mTmpValue) {
                         //Log.i(TAG, "Saving cached drawable @ #" +
                         //        Integer.toHexString(key.intValue())
                         //        + " in " + this + ": " + cs);
-                        mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+                        if (isColorDrawable) {
+                            mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+                        } else {
+                            mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+                        }
                     }
                 }
             }
@@ -1741,9 +1770,11 @@
         return dr;
     }
 
-    private Drawable getCachedDrawable(long key) {
+    private Drawable getCachedDrawable(
+            LongSparseArray<WeakReference<ConstantState>> drawableCache,
+            long key) {
         synchronized (mTmpValue) {
-            WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
+            WeakReference<Drawable.ConstantState> wr = drawableCache.get(key);
             if (wr != null) {   // we have the key
                 Drawable.ConstantState entry = wr.get();
                 if (entry != null) {
@@ -1753,7 +1784,7 @@
                     return entry.newDrawable(this);
                 }
                 else {  // our entry has been purged
-                    mDrawableCache.delete(key);
+                    drawableCache.delete(key);
                 }
             }
         }
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 038eedf..a5e5e46 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -204,7 +204,7 @@
      * @param window
      */
     public void fillWindow(int position, CursorWindow window) {
-        if (position < 0 || position > getCount()) {
+        if (position < 0 || position >= getCount()) {
             return;
         }
         window.acquireReference();
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 66406ca..95fc1fd 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -50,8 +50,6 @@
     private static final boolean DEBUG = false;
     private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
 
-    private static final String[] countProjection = new String[]{"count(*)"};
-
     /**
      * Special function for writing an exception result at the header of
      * a parcel, to be used when returning an exception from a transaction.
@@ -604,14 +602,40 @@
      * @return the number of rows in the table
      */
     public static long queryNumEntries(SQLiteDatabase db, String table) {
-        Cursor cursor = db.query(table, countProjection,
-                null, null, null, null, null);
-        try {
-            cursor.moveToFirst();
-            return cursor.getLong(0);
-        } finally {
-            cursor.close();
-        }
+        return queryNumEntries(db, table, null, null);
+    }
+
+    /**
+     * Query the table for the number of rows in the table.
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @param selection A filter declaring which rows to return,
+     *              formatted as an SQL WHERE clause (excluding the WHERE itself).
+     *              Passing null will count all rows for the given table
+     * @return the number of rows in the table filtered by the selection
+     */
+    public static long queryNumEntries(SQLiteDatabase db, String table, String selection) {
+        return queryNumEntries(db, table, selection, null);
+    }
+
+    /**
+     * Query the table for the number of rows in the table.
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @param selection A filter declaring which rows to return,
+     *              formatted as an SQL WHERE clause (excluding the WHERE itself).
+     *              Passing null will count all rows for the given table
+     * @param selectionArgs You may include ?s in selection,
+     *              which will be replaced by the values from selectionArgs,
+     *              in order that they appear in the selection.
+     *              The values will be bound as Strings.
+     * @return the number of rows in the table filtered by the selection
+     */
+    public static long queryNumEntries(SQLiteDatabase db, String table, String selection,
+            String[] selectionArgs) {
+        String s = (!TextUtils.isEmpty(selection)) ? " where " + selection : "";
+        return longForQuery(db, "select count(*) from " + table + s,
+                    selectionArgs);
     }
 
     /**
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 66eefb2..22c30a5 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -16,12 +16,18 @@
 
 package android.net;
 
+import org.apache.http.HttpHost;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Log;
 
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+
 import junit.framework.Assert;
 
 /**
@@ -120,4 +126,73 @@
         }
     }
 
+    /**
+     * Returns the preferred proxy to be used by clients. This is a wrapper
+     * around {@link android.net.Proxy#getHost()}. Currently no proxy will
+     * be returned for localhost or if the active network is Wi-Fi.
+     *
+     * @param context the context which will be passed to
+     * {@link android.net.Proxy#getHost()}
+     * @param url the target URL for the request
+     * @note Calling this method requires permission
+     * android.permission.ACCESS_NETWORK_STATE
+     * @return The preferred proxy to be used by clients, or null if there
+     * is no proxy.
+     *
+     * {@hide}
+     */
+    static final public HttpHost getPreferredHttpHost(Context context,
+            String url) {
+        if (!isLocalHost(url) && !isNetworkWifi(context)) {
+            final String proxyHost = Proxy.getHost(context);
+            if (proxyHost != null) {
+                return new HttpHost(proxyHost, Proxy.getPort(context), "http");
+            }
+        }
+
+        return null;
+    }
+
+    static final private boolean isLocalHost(String url) {
+        if (url == null) {
+            return false;
+        }
+
+        try {
+            final URI uri = URI.create(url);
+            final String host = uri.getHost();
+            if (host != null) {
+                if (host.equalsIgnoreCase("localhost")) {
+                    return true;
+                }
+                if (InetAddress.getByName(host).isLoopbackAddress()) {
+                    return true;
+                }
+            }
+        } catch (UnknownHostException uex) {
+            // Ignore (INetworkSystem.ipStringToByteArray)
+        } catch (IllegalArgumentException iex) {
+            // Ignore (URI.create)
+        }
+
+        return false;
+    }
+
+    static final private boolean isNetworkWifi(Context context) {
+        if (context == null) {
+            return false;
+        }
+
+        final ConnectivityManager connectivity = (ConnectivityManager)
+            context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        if (connectivity != null) {
+            final NetworkInfo info = connectivity.getActiveNetworkInfo();
+            if (info != null &&
+                    info.getType() == ConnectivityManager.TYPE_WIFI) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 };
diff --git a/core/java/android/net/http/Headers.java b/core/java/android/net/http/Headers.java
index 09f6f4f..74c0de8 100644
--- a/core/java/android/net/http/Headers.java
+++ b/core/java/android/net/http/Headers.java
@@ -262,7 +262,14 @@
             break;
         case HASH_CACHE_CONTROL:
             if (name.equals(CACHE_CONTROL)) {
-                mHeaders[IDX_CACHE_CONTROL] = val;
+                // In case where we receive more than one header, create a ',' separated list.
+                // This should be ok, according to RFC 2616 chapter 4.2
+                if (mHeaders[IDX_CACHE_CONTROL] != null &&
+                    mHeaders[IDX_CACHE_CONTROL].length() > 0) {
+                    mHeaders[IDX_CACHE_CONTROL] += (',' + val);
+                } else {
+                    mHeaders[IDX_CACHE_CONTROL] = val;
+                }
             }
             break;
         case HASH_LAST_MODIFIED:
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 8c9d013f..cefa997 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -204,10 +204,13 @@
                 BasicHttpRequest proxyReq = new BasicHttpRequest
                     ("CONNECT", mHost.toHostString());
 
-                // add all 'proxy' headers from the original request
+                // add all 'proxy' headers from the original request, we also need
+                // to add 'host' header unless we want proxy to answer us with a
+                // 400 Bad Request
                 for (Header h : req.mHttpRequest.getAllHeaders()) {
                     String headerName = h.getName().toLowerCase();
-                    if (headerName.startsWith("proxy") || headerName.equals("keep-alive")) {
+                    if (headerName.startsWith("proxy") || headerName.equals("keep-alive")
+                            || headerName.equals("host")) {
                         proxyReq.addHeader(h);
                     }
                 }
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2e14667..86f9a6b 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -94,7 +94,8 @@
     /**
      * Default trace file path and file
      */
-    private static final String DEFAULT_TRACE_PATH_PREFIX = "/sdcard/";
+    private static final String DEFAULT_TRACE_PATH_PREFIX =
+        Environment.getExternalStorageDirectory().getPath() + "/";
     private static final String DEFAULT_TRACE_BODY = "dmtrace";
     private static final String DEFAULT_TRACE_EXTENSION = ".trace";
     private static final String DEFAULT_TRACE_FILE_PATH =
@@ -127,7 +128,7 @@
         public int otherPrivateDirty;
         /** The shared dirty pages used by everything else. */
         public int otherSharedDirty;
-        
+
         public MemoryInfo() {
         }
 
@@ -137,21 +138,21 @@
         public int getTotalPss() {
             return dalvikPss + nativePss + otherPss;
         }
-        
+
         /**
          * Return total private dirty memory usage in kB.
          */
         public int getTotalPrivateDirty() {
             return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
         }
-        
+
         /**
          * Return total shared dirty memory usage in kB.
          */
         public int getTotalSharedDirty() {
             return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
         }
-        
+
         public int describeContents() {
             return 0;
         }
@@ -179,7 +180,7 @@
             otherPrivateDirty = source.readInt();
             otherSharedDirty = source.readInt();
         }
-        
+
         public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
             public MemoryInfo createFromParcel(Parcel source) {
                 return new MemoryInfo(source);
@@ -460,7 +461,7 @@
      * Like startMethodTracing(String, int, int), but taking an already-opened
      * FileDescriptor in which the trace is written.  The file name is also
      * supplied simply for logging.  Makes a dup of the file descriptor.
-     * 
+     *
      * Not exposed in the SDK unless we are really comfortable with supporting
      * this and find it would be useful.
      * @hide
@@ -1070,7 +1071,7 @@
      *    static {
      *        // Sets all the fields
      *        Debug.setFieldsOn(MyDebugVars.class);
-     * 
+     *
      *        // Sets only the fields annotated with @Debug.DebugProperty
      *        // Debug.setFieldsOn(MyDebugVars.class, true);
      *    }
diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java
index f842d75..f44cbe4 100644
--- a/core/java/android/preference/ListPreference.java
+++ b/core/java/android/preference/ListPreference.java
@@ -39,6 +39,7 @@
     private CharSequence[] mEntries;
     private CharSequence[] mEntryValues;
     private String mValue;
+    private String mSummary;
     private int mClickedDialogEntryIndex;
     
     public ListPreference(Context context, AttributeSet attrs) {
@@ -49,8 +50,16 @@
         mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
         mEntryValues = a.getTextArray(com.android.internal.R.styleable.ListPreference_entryValues);
         a.recycle();
+
+        /* Retrieve the Preference summary attribute since it's private
+         * in the Preference class.
+         */
+        a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.Preference, 0, 0);
+        mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
+        a.recycle();
     }
-    
+
     public ListPreference(Context context) {
         this(context, null);
     }
@@ -127,6 +136,43 @@
     }
 
     /**
+     * Returns the summary of this ListPreference. If the summary
+     * has a {@linkplain java.lang.String#format String formatting}
+     * marker in it (i.e. "%s" or "%1$s"), then the current entry
+     * value will be substituted in its place.
+     *
+     * @return the summary with appropriate string substitution
+     */
+    @Override
+    public CharSequence getSummary() {
+        final CharSequence entry = getEntry();
+        if (mSummary == null || entry == null) {
+            return super.getSummary();
+        } else {
+            return String.format(mSummary, entry);
+        }
+    }
+
+    /**
+     * Sets the summary for this Preference with a CharSequence.
+     * If the summary has a
+     * {@linkplain java.lang.String#format String formatting}
+     * marker in it (i.e. "%s" or "%1$s"), then the current entry
+     * value will be substituted in its place when it's retrieved.
+     *
+     * @param summary The summary for the preference.
+     */
+    @Override
+    public void setSummary(CharSequence summary) {
+        super.setSummary(summary);
+        if (summary == null && mSummary != null) {
+            mSummary = null;
+        } else if (summary != null && !summary.equals(mSummary)) {
+            mSummary = summary.toString();
+        }
+    }
+
+    /**
      * Sets the value to the given index from the entry values.
      * 
      * @param index The index of the value to set.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ea26207..ebc85d3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3542,7 +3542,7 @@
                 while (intent == null && c.moveToNext()) {
                     try {
                         String intentURI = c.getString(c.getColumnIndexOrThrow(INTENT));
-                        intent = Intent.getIntent(intentURI);
+                        intent = Intent.parseUri(intentURI, 0);
                     } catch (java.net.URISyntaxException e) {
                         // The stored URL is bad...  ignore it.
                     } catch (IllegalArgumentException e) {
@@ -3600,7 +3600,7 @@
             ContentValues values = new ContentValues();
             if (title != null) values.put(TITLE, title);
             if (folder != null) values.put(FOLDER, folder);
-            values.put(INTENT, intent.toURI());
+            values.put(INTENT, intent.toUri(0));
             if (shortcut != 0) values.put(SHORTCUT, (int) shortcut);
             values.put(ORDERING, ordering);
             return cr.insert(CONTENT_URI, values);
@@ -3652,7 +3652,7 @@
 
             Intent intent;
             try {
-                intent = Intent.getIntent(intentUri);
+                intent = Intent.parseUri(intentUri, 0);
             } catch (URISyntaxException e) {
                 return "";
             }
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index bf9e854..fa5cd8b 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -25,6 +25,7 @@
 import android.database.Cursor;
 import android.database.sqlite.SqliteWrapper;
 import android.net.Uri;
+import android.os.Environment;
 import android.telephony.SmsMessage;
 import android.text.TextUtils;
 import android.util.Config;
@@ -561,15 +562,24 @@
              * values:</p>
              *
              * <ul>
-             *   <li><em>transactionId (Integer)</em> - The WAP transaction
-             *    ID</li>
+             *   <li><em>transactionId (Integer)</em> - The WAP transaction ID</li>
              *   <li><em>pduType (Integer)</em> - The WAP PDU type</li>
              *   <li><em>header (byte[])</em> - The header of the message</li>
              *   <li><em>data (byte[])</em> - The data payload of the message</li>
+             *   <li><em>contentTypeParameters (HashMap&lt;String,String&gt;)</em>
+             *   - Any parameters associated with the content type
+             *   (decoded from the WSP Content-Type header)</li>
              * </ul>
              *
              * <p>If a BroadcastReceiver encounters an error while processing
              * this intent it should set the result code appropriately.</p>
+             *
+             * <p>The contentTypeParameters extra value is map of content parameters keyed by
+             * their names.</p>
+             *
+             * <p>If any unassigned well-known parameters are encountered, the key of the map will
+             * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter.  If
+             * a parameter has No-Value the value in the map will be null.</p>
              */
             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
             public static final String WAP_PUSH_RECEIVED_ACTION =
@@ -582,7 +592,7 @@
              */
             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
             public static final String SIM_FULL_ACTION =
-                "android.provider.Telephony.SIM_FULL";
+                    "android.provider.Telephony.SIM_FULL";
 
             /**
              * Broadcast Action: An incoming SMS has been rejected by the
@@ -1526,7 +1536,8 @@
              * which streams the captured image to the uri. Internally we write the media content
              * to this file. It's named '.temp.jpg' so Gallery won't pick it up.
              */
-            public static final String SCRAP_FILE_PATH = "/sdcard/mms/scrapSpace/.temp.jpg";
+            public static final String SCRAP_FILE_PATH =
+                Environment.getExternalStorageDirectory().getPath() + "/mms/scrapSpace/.temp.jpg";
         }
 
         public static final class Intents {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e1d3f13..35a582d 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -30,6 +30,8 @@
 
 import java.util.HashMap;
 import java.util.Set;
+import android.os.PowerManager;
+
 
 /**
  * TODO: Move this to
@@ -51,6 +53,9 @@
     private final BluetoothService mBluetoothService;
     private final BluetoothAdapter mAdapter;
     private final Context mContext;
+    // The WakeLock is used for bringing up the LCD during a pairing request
+    // from remote device when Android is in Suspend state.
+    private PowerManager.WakeLock mWakeLock;
 
     private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
     private static final int EVENT_RESTART_BLUETOOTH = 2;
@@ -121,6 +126,11 @@
         mContext = context;
         mPasskeyAgentRequestData = new HashMap();
         mAdapter = adapter;
+        //WakeLock instantiation in BluetoothEventLoop class
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
+                | PowerManager.ON_AFTER_RELEASE, TAG);
+        mWakeLock.setReferenceCounted(false);
         initializeNativeDataNative();
     }
 
@@ -458,37 +468,46 @@
             mHandler.sendMessageDelayed(message, 1500);
             return;
         }
-
+        // Acquire wakelock during PIN code request to bring up LCD display
+        mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                         BluetoothDevice.PAIRING_VARIANT_CONSENT);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        mWakeLock.release();
         return;
     }
 
     private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
-
+        // Acquire wakelock during PIN code request to bring up LCD display
+        mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                 BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        mWakeLock.release();
         return;
     }
 
     private void onRequestPasskey(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
-
+        // Acquire wakelock during PIN code request to bring up LCD display
+        mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                 BluetoothDevice.PAIRING_VARIANT_PASSKEY);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        mWakeLock.release();
         return;
     }
 
@@ -526,10 +545,14 @@
                 }
            }
         }
+        // Acquire wakelock during PIN code request to bring up LCD display
+        mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        mWakeLock.release();
         return;
     }
 
@@ -537,12 +560,16 @@
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
 
+        // Acquire wakelock during PIN code request to bring up LCD display
+        mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                         BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        //Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+        mWakeLock.release();
     }
 
     private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index dde0889..89b3cba 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -496,7 +496,7 @@
                 }
             }
         } else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
-            count = duration / DAY_IN_MILLIS;
+            count = getNumberOfDaysPassed(time, now);
             if (past) {
                 if (abbrevRelative) {
                     resId = com.android.internal.R.plurals.abbrev_num_days_ago;
@@ -521,6 +521,24 @@
     }
     
     /**
+     * Returns the number of days passed between two dates.
+     *
+     * @param date1 first date
+     * @param date2 second date
+     * @return number of days passed between to dates.
+     */
+    private synchronized static long getNumberOfDaysPassed(long date1, long date2) {
+        if (sThenTime == null) {
+            sThenTime = new Time();
+        }
+        sThenTime.set(date1);
+        int day1 = Time.getJulianDay(date1, sThenTime.gmtoff);
+        sThenTime.set(date2);
+        int day2 = Time.getJulianDay(date2, sThenTime.gmtoff);
+        return Math.abs(day2 - day1);
+    }
+
+    /**
      * Return string describing the elapsed time since startTime formatted like
      * "[relative time/date], [time]".
      * <p>
@@ -1550,40 +1568,45 @@
     public static CharSequence getRelativeTimeSpanString(Context c, long millis,
             boolean withPreposition) {
 
+        String result;
         long now = System.currentTimeMillis();
         long span = now - millis;
 
-        if (sNowTime == null) {
-            sNowTime = new Time();
-            sThenTime = new Time();
-        }
+        synchronized (DateUtils.class) {
+            if (sNowTime == null) {
+                sNowTime = new Time();
+            }
 
-        sNowTime.set(now);
-        sThenTime.set(millis);
+            if (sThenTime == null) {
+                sThenTime = new Time();
+            }
 
-        String result;
-        int prepositionId;
-        if (span < DAY_IN_MILLIS && sNowTime.weekDay == sThenTime.weekDay) {
-            // Same day
-            int flags = FORMAT_SHOW_TIME;
-            result = formatDateRange(c, millis, millis, flags);
-            prepositionId = R.string.preposition_for_time;
-        } else if (sNowTime.year != sThenTime.year) {
-            // Different years
-            int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
-            result = formatDateRange(c, millis, millis, flags);
+            sNowTime.set(now);
+            sThenTime.set(millis);
 
-            // This is a date (like "10/31/2008" so use the date preposition)
-            prepositionId = R.string.preposition_for_date;
-        } else {
-            // Default
-            int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
-            result = formatDateRange(c, millis, millis, flags);
-            prepositionId = R.string.preposition_for_date;
-        }
-        if (withPreposition) {
-            Resources res = c.getResources();
-            result = res.getString(prepositionId, result);
+            int prepositionId;
+            if (span < DAY_IN_MILLIS && sNowTime.weekDay == sThenTime.weekDay) {
+                // Same day
+                int flags = FORMAT_SHOW_TIME;
+                result = formatDateRange(c, millis, millis, flags);
+                prepositionId = R.string.preposition_for_time;
+            } else if (sNowTime.year != sThenTime.year) {
+                // Different years
+                int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
+                result = formatDateRange(c, millis, millis, flags);
+
+                // This is a date (like "10/31/2008" so use the date preposition)
+                prepositionId = R.string.preposition_for_date;
+            } else {
+                // Default
+                int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
+                result = formatDateRange(c, millis, millis, flags);
+                prepositionId = R.string.preposition_for_date;
+            }
+            if (withPreposition) {
+                Resources res = c.getResources();
+                result = res.getString(prepositionId, result);
+            }
         }
         return result;
     }
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 8eae111..c05a8fe 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -32,7 +32,7 @@
     private static final String Y_M_D_T_H_M_S_000 = "%Y-%m-%dT%H:%M:%S.000";
     private static final String Y_M_D_T_H_M_S_000_Z = "%Y-%m-%dT%H:%M:%S.000Z";
     private static final String Y_M_D = "%Y-%m-%d";
-    
+
     public static final String TIMEZONE_UTC = "UTC";
 
     /**
@@ -170,11 +170,11 @@
     public Time() {
         this(TimeZone.getDefault().getID());
     }
-    
+
     /**
      * A copy constructor.  Construct a Time object by copying the given
      * Time object.  No normalization occurs.
-     * 
+     *
      * @param other
      */
     public Time(Time other) {
@@ -185,17 +185,17 @@
      * Ensures the values in each field are in range. For example if the
      * current value of this calendar is March 32, normalize() will convert it
      * to April 1. It also fills in weekDay, yearDay, isDst and gmtoff.
-     * 
+     *
      * <p>
      * If "ignoreDst" is true, then this method sets the "isDst" field to -1
      * (the "unknown" value) before normalizing.  It then computes the
      * correct value for "isDst".
-     * 
+     *
      * <p>
      * See {@link #toMillis(boolean)} for more information about when to
      * use <tt>true</tt> or <tt>false</tt> for "ignoreDst".
-     * 
-     * @return the UTC milliseconds since the epoch 
+     *
+     * @return the UTC milliseconds since the epoch
      */
     native public long normalize(boolean ignoreDst);
 
@@ -379,13 +379,13 @@
      * Parses a date-time string in either the RFC 2445 format or an abbreviated
      * format that does not include the "time" field.  For example, all of the
      * following strings are valid:
-     * 
+     *
      * <ul>
      *   <li>"20081013T160000Z"</li>
      *   <li>"20081013T160000"</li>
      *   <li>"20081013"</li>
      * </ul>
-     * 
+     *
      * Returns whether or not the time is in UTC (ends with Z).  If the string
      * ends with "Z" then the timezone is set to UTC.  If the date-time string
      * included only a date and no time field, then the <code>allDay</code>
@@ -396,10 +396,10 @@
      * <code>yearDay</code>, and <code>gmtoff</code> are always set to zero,
      * and the field <code>isDst</code> is set to -1 (unknown).  To set those
      * fields, call {@link #normalize(boolean)} after parsing.
-     * 
+     *
      * To parse a date-time string and convert it to UTC milliseconds, do
      * something like this:
-     * 
+     *
      * <pre>
      *   Time time = new Time();
      *   String date = "20081013T160000Z";
@@ -428,25 +428,25 @@
      * Parse a time in RFC 3339 format.  This method also parses simple dates
      * (that is, strings that contain no time or time offset).  For example,
      * all of the following strings are valid:
-     * 
+     *
      * <ul>
      *   <li>"2008-10-13T16:00:00.000Z"</li>
      *   <li>"2008-10-13T16:00:00.000+07:00"</li>
      *   <li>"2008-10-13T16:00:00.000-07:00"</li>
      *   <li>"2008-10-13"</li>
      * </ul>
-     * 
+     *
      * <p>
      * If the string contains a time and time offset, then the time offset will
      * be used to convert the time value to UTC.
      * </p>
-     * 
+     *
      * <p>
      * If the given string contains just a date (with no time field), then
      * the {@link #allDay} field is set to true and the {@link #hour},
      * {@link #minute}, and  {@link #second} fields are set to zero.
      * </p>
-     * 
+     *
      * <p>
      * Returns true if the resulting time value is in UTC time.
      * </p>
@@ -462,7 +462,7 @@
          }
          return false;
      }
-     
+
      native private boolean nativeParse3339(String s);
 
     /**
@@ -484,13 +484,13 @@
      * <em>not</em> change any of the fields in this Time object.  If you want
      * to normalize the fields in this Time object and also get the milliseconds
      * then use {@link #normalize(boolean)}.
-     * 
+     *
      * <p>
      * If "ignoreDst" is false, then this method uses the current setting of the
      * "isDst" field and will adjust the returned time if the "isDst" field is
      * wrong for the given time.  See the sample code below for an example of
      * this.
-     * 
+     *
      * <p>
      * If "ignoreDst" is true, then this method ignores the current setting of
      * the "isDst" field in this Time object and will instead figure out the
@@ -499,27 +499,27 @@
      * correct value of the "isDst" field is when the time is inherently
      * ambiguous because it falls in the hour that is repeated when switching
      * from Daylight-Saving Time to Standard Time.
-     * 
+     *
      * <p>
      * Here is an example where <tt>toMillis(true)</tt> adjusts the time,
      * assuming that DST changes at 2am on Sunday, Nov 4, 2007.
-     * 
+     *
      * <pre>
      * Time time = new Time();
-     * time.set(2007, 10, 4);  // set the date to Nov 4, 2007, 12am
+     * time.set(4, 10, 2007);  // set the date to Nov 4, 2007, 12am
      * time.normalize();       // this sets isDst = 1
      * time.monthDay += 1;     // changes the date to Nov 5, 2007, 12am
      * millis = time.toMillis(false);   // millis is Nov 4, 2007, 11pm
      * millis = time.toMillis(true);    // millis is Nov 5, 2007, 12am
      * </pre>
-     * 
+     *
      * <p>
      * To avoid this problem, use <tt>toMillis(true)</tt>
      * after adding or subtracting days or explicitly setting the "monthDay"
      * field.  On the other hand, if you are adding
      * or subtracting hours or minutes, then you should use
      * <tt>toMillis(false)</tt>.
-     * 
+     *
      * <p>
      * You should also use <tt>toMillis(false)</tt> if you want
      * to read back the same milliseconds that you set with {@link #set(long)}
@@ -531,14 +531,14 @@
      * Sets the fields in this Time object given the UTC milliseconds.  After
      * this method returns, all the fields are normalized.
      * This also sets the "isDst" field to the correct value.
-     * 
+     *
      * @param millis the time in UTC milliseconds since the epoch.
      */
     native public void set(long millis);
 
     /**
      * Format according to RFC 2445 DATETIME type.
-     * 
+     *
      * <p>
      * The same as format("%Y%m%dT%H%M%S").
      */
@@ -584,7 +584,7 @@
      * Sets the date from the given fields.  Also sets allDay to true.
      * Sets weekDay, yearDay and gmtoff to 0, and isDst to -1.
      * Call {@link #normalize(boolean)} if you need those.
-     * 
+     *
      * @param monthDay the day of the month (in the range [1,31])
      * @param month the zero-based month number (in the range [0,11])
      * @param year the year
@@ -606,7 +606,7 @@
     /**
      * Returns true if the time represented by this Time object occurs before
      * the given time.
-     * 
+     *
      * @param that a given Time object to compare against
      * @return true if this time is less than the given time
      */
@@ -618,7 +618,7 @@
     /**
      * Returns true if the time represented by this Time object occurs after
      * the given time.
-     * 
+     *
      * @param that a given Time object to compare against
      * @return true if this time is greater than the given time
      */
@@ -632,12 +632,12 @@
      * closest Thursday yearDay.
      */
     private static final int[] sThursdayOffset = { -3, 3, 2, 1, 0, -1, -2 };
-        
+
     /**
      * Computes the week number according to ISO 8601.  The current Time
      * object must already be normalized because this method uses the
      * yearDay and weekDay fields.
-     * 
+     *
      * <p>
      * In IS0 8601, weeks start on Monday.
      * The first week of the year (week 1) is defined by ISO 8601 as the
@@ -645,12 +645,12 @@
      * Or equivalently, the week containing January 4.  Or equivalently,
      * the week with the year's first Thursday in it.
      * </p>
-     * 
+     *
      * <p>
      * The week number can be calculated by counting Thursdays.  Week N
      * contains the Nth Thursday of the year.
      * </p>
-     *   
+     *
      * @return the ISO week number.
      */
     public int getWeekNumber() {
@@ -661,7 +661,7 @@
         if (closestThursday >= 0 && closestThursday <= 364) {
             return closestThursday / 7 + 1;
         }
-        
+
         // The week crosses a year boundary.
         Time temp = new Time(this);
         temp.monthDay += sThursdayOffset[weekDay];
@@ -670,7 +670,7 @@
     }
 
     /**
-     * Return a string in the RFC 3339 format. 
+     * Return a string in the RFC 3339 format.
      * <p>
      * If allDay is true, expresses the time as Y-M-D</p>
      * <p>
@@ -691,13 +691,13 @@
             int offset = (int)Math.abs(gmtoff);
             int minutes = (offset % 3600) / 60;
             int hours = offset / 3600;
-            
+
             return String.format("%s%s%02d:%02d", base, sign, hours, minutes);
         }
     }
-    
+
     /**
-     * Returns true if the day of the given time is the epoch on the Julian Calendar 
+     * Returns true if the day of the given time is the epoch on the Julian Calendar
      * (January 1, 1970 on the Gregorian calendar).
      *
      * @param time the time to test
@@ -707,7 +707,7 @@
         long millis = time.toMillis(true);
         return getJulianDay(millis, 0) == EPOCH_JULIAN_DAY;
     }
-    
+
     /**
      * Computes the Julian day number, given the UTC milliseconds
      * and the offset (in seconds) from UTC.  The Julian day for a given
@@ -716,10 +716,10 @@
      * what timezone is being used.  The Julian day is useful for testing
      * if two events occur on the same day and for determining the relative
      * time of an event from the present ("yesterday", "3 days ago", etc.).
-     * 
+     *
      * <p>
      * Use {@link #toMillis(boolean)} to get the milliseconds.
-     * 
+     *
      * @param millis the time in UTC milliseconds
      * @param gmtoff the offset from UTC in seconds
      * @return the Julian day
@@ -729,7 +729,7 @@
         long julianDay = (millis + offsetMillis) / DateUtils.DAY_IN_MILLIS;
         return (int) julianDay + EPOCH_JULIAN_DAY;
     }
-    
+
     /**
      * <p>Sets the time from the given Julian day number, which must be based on
      * the same timezone that is set in this Time object.  The "gmtoff" field
@@ -738,7 +738,7 @@
      * After this method returns all the fields will be normalized and the time
      * will be set to 12am at the beginning of the given Julian day.
      * </p>
-     * 
+     *
      * <p>
      * The only exception to this is if 12am does not exist for that day because
      * of daylight saving time.  For example, Cairo, Eqypt moves time ahead one
@@ -746,7 +746,7 @@
      * also change daylight saving time at 12am.  In those cases, the time
      * will be set to 1am.
      * </p>
-     * 
+     *
      * @param julianDay the Julian day in the timezone for this Time object
      * @return the UTC milliseconds for the beginning of the Julian day
      */
@@ -756,13 +756,13 @@
         // the day.
         long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS;
         set(millis);
-        
+
         // Figure out how close we are to the requested Julian day.
         // We can't be off by more than a day.
         int approximateDay = getJulianDay(millis, gmtoff);
         int diff = julianDay - approximateDay;
         monthDay += diff;
-        
+
         // Set the time to 12am and re-normalize.
         hour = 0;
         minute = 0;
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index ca9ad53..c1ac180 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -369,10 +369,13 @@
             sMimeTypeMap.loadEntry("application/x-xfig", "fig");
             sMimeTypeMap.loadEntry("application/xhtml+xml", "xhtml");
             sMimeTypeMap.loadEntry("audio/3gpp", "3gpp");
+            sMimeTypeMap.loadEntry("audio/amr", "amr");
             sMimeTypeMap.loadEntry("audio/basic", "snd");
             sMimeTypeMap.loadEntry("audio/midi", "mid");
             sMimeTypeMap.loadEntry("audio/midi", "midi");
             sMimeTypeMap.loadEntry("audio/midi", "kar");
+            sMimeTypeMap.loadEntry("audio/midi", "xmf");
+            sMimeTypeMap.loadEntry("audio/mobile-xmf", "mxmf");
             sMimeTypeMap.loadEntry("audio/mpeg", "mpga");
             sMimeTypeMap.loadEntry("audio/mpeg", "mpega");
             sMimeTypeMap.loadEntry("audio/mpeg", "mp2");
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3e0187d..0d912de 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3850,6 +3850,16 @@
             }
         }
 
+        if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
+            pageUp(false);
+            return true;
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
+            pageDown(false);
+            return true;
+        }
+
         if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
             switchOutDrawHistory();
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 32e5504..03ada94 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Comparator;
 import java.util.Collections;
@@ -83,7 +84,7 @@
      */
     private boolean mNotifyOnChange = true;
 
-    private Context mContext;    
+    private Context mContext;
 
     private ArrayList<T> mOriginalValues;
     private ArrayFilter mFilter;
@@ -181,6 +182,44 @@
     }
 
     /**
+     * Adds the specified Collection at the end of the array.
+     *
+     * @param collection The Collection to add at the end of the array.
+     */
+    public void addAll(Collection<? extends T> collection) {
+        if (mOriginalValues != null) {
+            synchronized (mLock) {
+                mOriginalValues.addAll(collection);
+                if (mNotifyOnChange) notifyDataSetChanged();
+            }
+        } else {
+            mObjects.addAll(collection);
+            if (mNotifyOnChange) notifyDataSetChanged();
+        }
+    }
+
+    /**
+     * Adds the specified items at the end of the array.
+     *
+     * @param items The items to add at the end of the array.
+     */
+    public void addAll(T ... items) {
+        if (mOriginalValues != null) {
+            synchronized (mLock) {
+                for (T item : items) {
+                    mOriginalValues.add(item);
+                }
+                if (mNotifyOnChange) notifyDataSetChanged();
+            }
+        } else {
+            for (T item : items) {
+                mObjects.add(item);
+            }
+            if (mNotifyOnChange) notifyDataSetChanged();
+        }
+    }
+
+    /**
      * Inserts the specified object at the specified index in the array.
      *
      * @param object The object to insert into the array.
@@ -236,7 +275,7 @@
      */
     public void sort(Comparator<? super T> comparator) {
         Collections.sort(mObjects, comparator);
-        if (mNotifyOnChange) notifyDataSetChanged();        
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2f76bd0..d9d5259 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4548,6 +4548,9 @@
                     partialStartOffset = 0;
                     partialEndOffset = N;
                 } else {
+                    // Now use the delta to determine the actual amount of text
+                    // we need.
+                    partialEndOffset += delta;
                     // Adjust offsets to ensure we contain full spans.
                     if (content instanceof Spanned) {
                         Spanned spanned = (Spanned)content;
@@ -4563,10 +4566,8 @@
                         }
                     }
                     outText.partialStartOffset = partialStartOffset;
-                    outText.partialEndOffset = partialEndOffset;
-                    // Now use the delta to determine the actual amount of text
-                    // we need.
-                    partialEndOffset += delta;
+                    outText.partialEndOffset = partialEndOffset - delta;
+
                     if (partialStartOffset > N) {
                         partialStartOffset = N;
                     } else if (partialStartOffset < 0) {
@@ -4630,6 +4631,10 @@
                                     + ": " + ims.mTmpExtracted.text);
                             imm.updateExtractedText(this, req.token,
                                     mInputMethodState.mTmpExtracted);
+                            ims.mChangedStart = EXTRACT_UNKNOWN;
+                            ims.mChangedEnd = EXTRACT_UNKNOWN;
+                            ims.mChangedDelta = 0;
+                            ims.mContentChanged = false;
                             return true;
                         }
                     }
@@ -6217,8 +6222,8 @@
                 ims.mChangedStart = start;
                 ims.mChangedEnd = start+before;
             } else {
-                if (ims.mChangedStart > start) ims.mChangedStart = start;
-                if (ims.mChangedEnd < (start+before)) ims.mChangedEnd = start+before;
+                ims.mChangedStart = Math.min(ims.mChangedStart, start);
+                ims.mChangedEnd = Math.max(ims.mChangedEnd, start + before - ims.mChangedDelta);
             }
             ims.mChangedDelta += after-before;
         }
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 107b145..4a0617c 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -435,6 +435,7 @@
                 View titleTemplate = mWindow.findViewById(R.id.title_template);
                 titleTemplate.setVisibility(View.GONE);
                 mIconView.setVisibility(View.GONE);
+                topPanel.setVisibility(View.GONE);
                 hasTitle = false;
             }
         }
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index d1aff2a..e07c54f 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -134,7 +134,7 @@
     private static void beginShutdownSequence(Context context) {
         synchronized (sIsStartedGuard) {
             if (sIsStarted) {
-                Log.d(TAG, "Request to shutdown already running, returning.");
+                Log.d(TAG, "Shutdown sequence already running, returning.");
                 return;
             }
             sIsStarted = true;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f4447ab..0a1c8ff 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -917,7 +917,7 @@
     
     private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
         
-        byte[] buffer = new byte[4096];
+        byte[] buffer = new byte[8192];
         int len;
         
         try {
@@ -964,9 +964,11 @@
                 for (endIndex=startIndex; 
                         endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; 
                         endIndex++);
-                // Don't go over the end of the buffer
-                if (endIndex < len) {
-                    endIndex++; // endIndex is an exclusive upper bound.
+                endIndex++; // endIndex is an exclusive upper bound.
+                // Don't go over the end of the buffer, Process.parseProcLine might
+                // write to wlBuffer[endIndex]
+                if (endIndex >= (len - 1) ) {
+                    return m;
                 }
 
                 String[] nameStringArray = mProcWakelocksName;
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index 5f5c7a4..127fb23 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -85,7 +85,8 @@
             pending = true;
             snapshotWriter.execute(new Runnable() {
                 public void run() {
-                    String dir = "/sdcard/snapshots";
+                    String dir =
+                        Environment.getExternalStorageDirectory().getPath() + "/snapshots";
                     if (!dirMade) {
                         new File(dir).mkdirs();
                         if (new File(dir).isDirectory()) {
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
index 21f0c93..8edfe52 100644
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ b/core/java/com/google/android/mms/pdu/PduParser.java
@@ -163,6 +163,13 @@
                     // or "application/vnd.wap.multipart.related"
                     // or "application/vnd.wap.multipart.alternative"
                     return retrieveConf;
+                } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
+                    // "application/vnd.wap.multipart.alternative"
+                    // should take only the first part.
+                    PduPart firstPart = mBody.getPart(0);
+                    mBody.removeAll();
+                    mBody.addPart(0, firstPart);
+                    return retrieveConf;
                 }
                 return null;
             case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d565c68..800ed13 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -255,6 +255,21 @@
     <!-- Default LED off time for notification LED in milliseconds. -->
     <integer name="config_defaultNotificationLedOff">2000</integer>
 
+    <!-- Default value for led color when battery is low on charge -->
+    <integer name="config_notificationsBatteryLowARGB">0xFFFF0000</integer>
+
+    <!-- Default value for led color when battery is medium charged -->
+    <integer name="config_notificationsBatteryMediumARGB">0xFFFFFF00</integer>
+
+    <!-- Default value for led color when battery is fully charged -->
+    <integer name="config_notificationsBatteryFullARGB">0xFF00FF00</integer>
+
+    <!-- Default value for LED on time when the battery is low on charge in miliseconds -->
+    <integer name="config_notificationsBatteryLedOn">125</integer>
+
+    <!-- Default value for LED off time when the battery is low on charge in miliseconds -->
+    <integer name="config_notificationsBatteryLedOff">2875</integer>
+
     <!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
     <bool name="config_disableMenuKeyInLockScreen">false</bool>
 
diff --git a/core/tests/coretests/src/android/preference/ListPreferenceTest.java b/core/tests/coretests/src/android/preference/ListPreferenceTest.java
new file mode 100644
index 0000000..41f8e03
--- /dev/null
+++ b/core/tests/coretests/src/android/preference/ListPreferenceTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference;
+
+import android.preference.ListPreference;
+import android.test.AndroidTestCase;
+
+public class ListPreferenceTest extends AndroidTestCase {
+    public void testListPreferenceSummaryFromEntries() {
+        String[] entries = { "one", "two", "three" };
+        String[] entryValues = { "1" , "2", "3" };
+        ListPreference lp = new ListPreference(getContext());
+        lp.setEntries(entries);
+        lp.setEntryValues(entryValues);
+
+        lp.setValue(entryValues[1]);
+        assertTrue(lp.getSummary() == null);
+
+        lp.setSummary("%1$s");
+        assertEquals(entries[1], lp.getSummary());
+
+        lp.setValue(entryValues[2]);
+        assertEquals(entries[2], lp.getSummary());
+
+        lp.setSummary(null);
+        assertTrue(lp.getSummary() == null);
+
+        lp.setSummary("The color is %1$s");
+        assertEquals("The color is " + entries[2], lp.getSummary());
+    }
+}
diff --git a/core/tests/hosttests/Android.mk b/core/tests/hosttests/Android.mk
index 0001201..07d99cb 100644
--- a/core/tests/hosttests/Android.mk
+++ b/core/tests/hosttests/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_MODULE := FrameworkCoreHostTests
 
-LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib junit
+LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib-prebuilt junit
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
index 91cbe2f..b225c37 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
@@ -16,32 +16,32 @@
 
 package android.content.pm;
 
+import com.android.ddmlib.AdbCommandRejectedException;
 import com.android.ddmlib.AndroidDebugBridge;
 import com.android.ddmlib.IDevice;
 import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.InstallException;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.SyncService;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.TimeoutException;
 import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
 import com.android.ddmlib.testrunner.ITestRunListener;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.hosttest.DeviceTestCase;
-import com.android.hosttest.DeviceTestSuite;
 
 import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.lang.Runtime;
 import java.lang.Process;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import junit.framework.Assert;
-import com.android.hosttest.DeviceTestCase;
 
 /**
  * Set of tests that verify host side install cases
@@ -119,8 +119,14 @@
      * Helper method to run tests and return the listener that collected the results.
      * @param pkgName Android application package for tests
      * @return the {@link CollectingTestRunListener}
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    private CollectingTestRunListener doRunTests(String pkgName) throws IOException {
+    private CollectingTestRunListener doRunTests(String pkgName) throws IOException,
+    TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
                 pkgName, mDevice);
         CollectingTestRunListener listener = new CollectingTestRunListener();
@@ -133,8 +139,14 @@
      *
      * @param pkgName Android application package for tests
      * @return true if every test passed, false otherwise.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException {
+    public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         CollectingTestRunListener listener = doRunTests(pkgName);
         return listener.didAllTestsPass();
     }
@@ -142,22 +154,26 @@
     /**
      * Helper method to push a file to device
      * @param apkAppPrivatePath
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
      */
     public void pushFile(final String localFilePath, final String destFilePath)
-            throws IOException {
-        SyncResult result = mDevice.getSyncService().pushFile(
-                localFilePath, destFilePath, new NullSyncProgressMonitor());
-        assertEquals(SyncService.RESULT_OK, result.getCode());
+            throws IOException, SyncException, TimeoutException, AdbCommandRejectedException {
+        mDevice.getSyncService().pushFile(localFilePath,
+                destFilePath, new NullSyncProgressMonitor());
     }
 
     /**
      * Helper method to install a file
      * @param localFilePath the absolute file system path to file on local host to install
      * @param reinstall set to <code>true</code> if re-install of app should be performed
-     * @throws IOException
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed
      */
-    public void installFile(final String localFilePath, final boolean replace) throws IOException {
+    public void installFile(final String localFilePath, final boolean replace) throws IOException,
+            InstallException {
         String result = mDevice.installPackage(localFilePath, replace);
         assertEquals(null, result);
     }
@@ -167,10 +183,11 @@
      * @param localFilePath the absolute file system path to file on local host to install
      * @param reinstall set to <code>true</code> if re-install of app should be performed
      * @return the string output of the failed install attempt
-     * @throws IOException
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed
      */
     public String installFileFail(final String localFilePath, final boolean replace)
-            throws IOException {
+            throws IOException, InstallException {
         String result = mDevice.installPackage(localFilePath, replace);
         assertNotNull(result);
         return result;
@@ -180,10 +197,17 @@
      * Helper method to install a file to device as forward locked
      * @param localFilePath the absolute file system path to file on local host to install
      * @param reinstall set to <code>true</code> if re-install of app should be performed
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
     public String installFileForwardLocked(final String localFilePath, final boolean replace)
-            throws IOException {
+            throws IOException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException, InstallException {
         String remoteFilePath = mDevice.syncPackageToDevice(localFilePath);
         InstallReceiver receiver = new InstallReceiver();
         String cmd = String.format(replace ? "pm install -r -l \"%1$s\"" :
@@ -198,9 +222,14 @@
      *
      * @param destPath the absolute path of file on device to check
      * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean doesRemoteFileExist(String destPath) throws IOException {
+    public boolean doesRemoteFileExist(String destPath) throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         String lsGrep = executeShellCommand(String.format("ls %s", destPath));
         return !lsGrep.contains("No such file or directory");
     }
@@ -211,10 +240,15 @@
      * @param destPath the absolute path of the file
      * @return <code>true</code> if file exists containing given string,
      *         <code>false</code> otherwise.
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
     public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
-            throws IOException {
+            throws IOException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         String lsResult = executeShellCommand(String.format("ls %s", destPath));
         return lsResult.contains(searchString);
     }
@@ -224,9 +258,14 @@
      *
      * @param packageName the Android manifest package to check.
      * @return <code>true</code> if package exists, <code>false</code> otherwise
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean doesPackageExist(String packageName) throws IOException {
+    public boolean doesPackageExist(String packageName) throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         String pkgGrep = executeShellCommand(String.format("pm path %s", packageName));
         return pkgGrep.contains("package:");
     }
@@ -236,9 +275,14 @@
      *
      * @param packageName package name to check for
      * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean doesAppExistOnDevice(String packageName) throws IOException {
+    public boolean doesAppExistOnDevice(String packageName) throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
     }
 
@@ -247,9 +291,14 @@
      *
      * @param packageName package name to check for
      * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean doesAppExistOnSDCard(String packageName) throws IOException {
+    public boolean doesAppExistOnSDCard(String packageName) throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
     }
 
@@ -258,9 +307,14 @@
      *
      * @param packageName package name to check for
      * @return <code>true</code> if file exists, <code>false</code> otherwise.
-     * @throws IOException if adb shell command failed
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public boolean doesAppExistAsForwardLocked(String packageName) throws IOException {
+    public boolean doesAppExistAsForwardLocked(String packageName) throws IOException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         return doesRemoteFileExistContainingString(APP_PRIVATE_PATH, packageName);
     }
 
@@ -268,9 +322,14 @@
      * Waits for device's package manager to respond.
      *
      * @throws InterruptedException
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public void waitForPackageManager() throws InterruptedException, IOException {
+    public void waitForPackageManager() throws InterruptedException, IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "waiting for device");
         int currentWaitTime = 0;
         // poll the package manager until it returns something for android
@@ -336,9 +395,14 @@
      *
      * @param packageName The name of the package to wait to load
      * @throws InterruptedException
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public void waitForApp(String packageName) throws InterruptedException, IOException {
+    public void waitForApp(String packageName) throws InterruptedException, IOException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "waiting for app to launch");
         int currentWaitTime = 0;
         // poll the package manager until it returns something for the package we're looking for
@@ -355,9 +419,14 @@
     /**
      * Helper method which executes a adb shell command and returns output as a {@link String}
      * @return the output of the command
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public String executeShellCommand(String command) throws IOException {
+    public String executeShellCommand(String command) throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, String.format("adb shell %s", command));
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
         mDevice.executeShellCommand(command, receiver);
@@ -369,9 +438,14 @@
     /**
      * Helper method ensures we are in root mode on the host side. It returns only after
      * PackageManager is actually up and running.
-     * @throws IOException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public void runAdbRoot() throws IOException, InterruptedException {
+    public void runAdbRoot() throws IOException, InterruptedException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "adb root");
         Runtime runtime = Runtime.getRuntime();
         Process process = runtime.exec("adb root"); // adb should be in the path
@@ -389,10 +463,15 @@
     /**
      * Helper method which reboots the device and returns once the device is online again
      * and package manager is up and running (note this function is synchronous to callers).
-     * @throws IOException
      * @throws InterruptedException
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public void rebootDevice() throws IOException, InterruptedException {
+    public void rebootDevice() throws IOException, InterruptedException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         String command = "reboot"; // no need for -s since mDevice is already tied to a device
         Log.i(LOG_TAG, command);
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
@@ -468,7 +547,7 @@
             mAllTestsPassed = false;
         }
 
-        public void testRunEnded(long elapsedTime) {
+        public void testRunEnded(long elapsedTime, Map<String, String> resultBundle) {
             // ignore
         }
 
@@ -545,17 +624,23 @@
     /**
      * Helper method for installing an app to wherever is specified in its manifest, and
      * then verifying the app was installed onto SD Card.
+     * <p/>
+     * Assumes adb is running as root in device under test.
      *
      * @param the path of the apk to install
      * @param the name of the package
      * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
-     * <p/>
-     * Assumes adb is running as root in device under test.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void installAppAndVerifyExistsOnSDCard(String apkPath, String pkgName, boolean overwrite)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         // Start with a clean slate if we're not overwriting
         if (!overwrite) {
             // cleanup test app just in case it already exists
@@ -576,17 +661,23 @@
     /**
      * Helper method for installing an app to wherever is specified in its manifest, and
      * then verifying the app was installed onto device.
+     * <p/>
+     * Assumes adb is running as root in device under test.
      *
      * @param the path of the apk to install
      * @param the name of the package
      * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
-     * <p/>
-     * Assumes adb is running as root in device under test.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void installAppAndVerifyExistsOnDevice(String apkPath, String pkgName, boolean overwrite)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         // Start with a clean slate if we're not overwriting
         if (!overwrite) {
             // cleanup test app just in case it already exists
@@ -607,17 +698,24 @@
     /**
      * Helper method for installing an app as forward-locked, and
      * then verifying the app was installed in the proper forward-locked location.
+     * <p/>
+     * Assumes adb is running as root in device under test.
      *
      * @param the path of the apk to install
      * @param the name of the package
      * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
-     * <p/>
-     * Assumes adb is running as root in device under test.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
      */
     public void installFwdLockedAppAndVerifyExists(String apkPath,
-            String pkgName, boolean overwrite) throws IOException, InterruptedException {
+            String pkgName, boolean overwrite) throws IOException, InterruptedException,
+            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         // Start with a clean slate if we're not overwriting
         if (!overwrite) {
             // cleanup test app just in case it already exists
@@ -638,14 +736,21 @@
 
     /**
      * Helper method for uninstalling an app.
-     *
-     * @param pkgName package name to uninstall
-     * @throws IOException if adb shell command failed
-     * @throws InterruptedException if the thread was interrupted
      * <p/>
      * Assumes adb is running as root in device under test.
+     *
+     * @param pkgName package name to uninstall
+     * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the uninstall failed.
      */
-    public void uninstallApp(String pkgName) throws IOException, InterruptedException {
+    public void uninstallApp(String pkgName) throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         mDevice.uninstallPackage(pkgName);
         // make sure its not installed anymore
         assertFalse(doesPackageExist(pkgName));
@@ -655,12 +760,18 @@
      * Helper method for clearing any installed non-system apps.
      * Useful ensuring no non-system apps are installed, and for cleaning up stale files that
      * may be lingering on the system for whatever reason.
-     *
-     * @throws IOException if adb shell command failed
      * <p/>
      * Assumes adb is running as root in device under test.
+     *
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the uninstall failed.
      */
-    public void wipeNonSystemApps() throws IOException {
+    public void wipeNonSystemApps() throws IOException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException, InstallException {
       String allInstalledPackages = executeShellCommand("pm list packages -f");
       BufferedReader outputReader = new BufferedReader(new StringReader(allInstalledPackages));
 
@@ -685,8 +796,14 @@
      *
      * <p/>
      * Assumes adb is running as root in device under test.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException {
+    public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         String command = "pm setInstallLocation %d";
         int locValue = 0;
         switch (pref) {
@@ -708,8 +825,14 @@
      *
      * <p/>
      * Assumes adb is running as root in device under test.
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
      */
-    public InstallLocPreference getDevicePreferredInstallLocation() throws IOException {
+    public InstallLocPreference getDevicePreferredInstallLocation() throws IOException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         String result = executeShellCommand("pm getInstallLocation");
         if (result.indexOf('0') != -1) {
             return InstallLocPreference.AUTO;
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
index 1b797d5..22a2be6 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
@@ -16,13 +16,12 @@
 
 package android.content.pm;
 
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.InstallException;
 import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.TimeoutException;
 import com.android.hosttest.DeviceTestCase;
 import com.android.hosttest.DeviceTestSuite;
 
@@ -156,10 +155,18 @@
      * the app, and otherwise cause the system to blow up.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
-    public void testPushAppPrivate() throws IOException, InterruptedException {
+    public void testPushAppPrivate() throws IOException, InterruptedException, InstallException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+            SyncException {
         Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
         final String apkAppPrivatePath =  appPrivatePath + SIMPLE_APK;
 
@@ -187,12 +194,18 @@
      * @param apkName the file name of the test app apk
      * @param pkgName the package name of the test app apk
      * @param expectedLocation the file name of the test app apk
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     private void doStandardInstall(String apkName, String pkgName,
             PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
 
         if (expectedLocation == PackageManagerHostTestUtils.InstallLocation.DEVICE) {
             mPMHostUtils.installAppAndVerifyExistsOnDevice(
@@ -211,12 +224,18 @@
      * Assumes adb is running as root in device under test.
      * @param preference the device's preferred location of where to install apps
      * @param expectedLocation the expected location of where the apk was installed
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
             PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException, InstallException {
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
                 PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -239,10 +258,16 @@
      * will install the app to the device when device's preference is auto.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppAutoLocPrefIsAuto() throws IOException, InterruptedException {
+    public void testInstallAppAutoLocPrefIsAuto() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=auto, prefer=auto gets installed on device");
         installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -253,10 +278,17 @@
      * will install the app to the device when device's preference is internal.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppAutoLocPrefIsInternal() throws IOException, InterruptedException {
+    public void testInstallAppAutoLocPrefIsInternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=auto, prefer=internal gets installed on device");
         installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -267,10 +299,17 @@
      * will install the app to the SD card when device's preference is external.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppAutoLocPrefIsExternal() throws IOException, InterruptedException {
+    public void testInstallAppAutoLocPrefIsExternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=auto, prefer=external gets installed on device");
         installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -283,12 +322,18 @@
      * Assumes adb is running as root in device under test.
      * @param preference the device's preferred location of where to install apps
      * @param expectedLocation the expected location of where the apk was installed
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the (un)install failed.
      */
     public void installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
             PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException, InstallException {
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
             PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -311,10 +356,17 @@
      * will install the app to the device when device's preference is auto.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppInternalLocPrefIsAuto() throws IOException, InterruptedException {
+    public void testInstallAppInternalLocPrefIsAuto() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=internal, prefer=auto gets installed on device");
         installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -325,10 +377,17 @@
      * will install the app to the device when device's preference is internal.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppInternalLocPrefIsInternal() throws IOException, InterruptedException {
+    public void testInstallAppInternalLocPrefIsInternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=internal, prefer=internal is installed on device");
         installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -339,10 +398,17 @@
      * will install the app to the device when device's preference is external.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppInternalLocPrefIsExternal() throws IOException, InterruptedException {
+    public void testInstallAppInternalLocPrefIsExternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=internal, prefer=external is installed on device");
         installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -355,12 +421,18 @@
      * Assumes adb is running as root in device under test.
      * @param preference the device's preferred location of where to install apps
      * @param expectedLocation the expected location of where the apk was installed
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
             PackageManagerHostTestUtils.InstallLocation expectedLocation)
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException, InstallException {
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
             PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -384,10 +456,17 @@
      * will install the app to the device when device's preference is auto.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppExternalLocPrefIsAuto() throws IOException, InterruptedException {
+    public void testInstallAppExternalLocPrefIsAuto() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=external, pref=auto gets installed on SD Card");
         installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
                 PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -398,10 +477,17 @@
      * will install the app to the device when device's preference is internal.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppExternalLocPrefIsInternal() throws IOException, InterruptedException {
+    public void testInstallAppExternalLocPrefIsInternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=external, pref=internal gets installed on SD Card");
         installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -412,10 +498,17 @@
      * will install the app to the device when device's preference is external.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppExternalLocPrefIsExternal() throws IOException, InterruptedException {
+    public void testInstallAppExternalLocPrefIsExternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installLocation=external, pref=external gets installed on SD Card");
         installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
                 PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -427,10 +520,17 @@
      * system decide.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppNoLocPrefIsAuto() throws IOException, InterruptedException {
+    public void testInstallAppNoLocPrefIsAuto() throws IOException, InterruptedException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+            InstallException {
         Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -456,10 +556,17 @@
      * external.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppNoLocPrefIsExternal() throws IOException, InterruptedException {
+    public void testInstallAppNoLocPrefIsExternal() throws IOException, InterruptedException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+            InstallException {
         Log.i(LOG_TAG, "Test an app with no installLocation gets installed on SD card");
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -485,10 +592,17 @@
      * internal.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallAppNoLocPrefIsInternal() throws IOException, InterruptedException {
+    public void testInstallAppNoLocPrefIsInternal() throws IOException, InterruptedException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+            InstallException {
         Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
 
         PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -513,10 +627,18 @@
      * forward-locked will get installed to the correct location.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallFwdLockedAppInternal() throws IOException, InterruptedException {
+    public void testInstallFwdLockedAppInternal() throws IOException, InterruptedException,
+            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
 
         try {
@@ -534,10 +656,18 @@
      * forward-locked will get installed to the correct location.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallFwdLockedAppExternal() throws IOException, InterruptedException {
+    public void testInstallFwdLockedAppExternal() throws IOException, InterruptedException,
+            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
 
         try {
@@ -555,10 +685,18 @@
      * forward-locked will get installed to the correct location.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallFwdLockedAppAuto() throws IOException, InterruptedException {
+    public void testInstallFwdLockedAppAuto() throws IOException, InterruptedException,
+            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test an app with installLoc set to Auto gets installed to app-private");
 
         try {
@@ -576,10 +714,18 @@
      * forward-locked installed will get installed to the correct location.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
-    public void testInstallFwdLockedAppNone() throws IOException, InterruptedException {
+    public void testInstallFwdLockedAppNone() throws IOException, InterruptedException,
+            InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test an app with no installLoc set gets installed to app-private");
 
         try {
@@ -597,14 +743,21 @@
      * uninstall it, and reinstall it onto the SD card.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     // TODO: This currently relies on the app's manifest to switch from device to
     // SD card install locations. We might want to make Device's installPackage()
     // accept a installLocation flag so we can install a package to the
     // destination of our choosing.
-    public void testReinstallInternalToExternal() throws IOException, InterruptedException {
+    public void testReinstallInternalToExternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
 
         try {
@@ -625,14 +778,21 @@
      * uninstall it, and reinstall it onto the device.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     // TODO: This currently relies on the app's manifest to switch from device to
     // SD card install locations. We might want to make Device's installPackage()
     // accept a installLocation flag so we can install a package to the
     // destination of our choosing.
-    public void testReinstallExternalToInternal() throws IOException, InterruptedException {
+    public void testReinstallExternalToInternal() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
 
         try {
@@ -655,10 +815,16 @@
      * the update onto the SD card as well when location is set to external for both versions
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testUpdateBothExternal() throws IOException, InterruptedException {
+    public void testUpdateBothExternal() throws IOException, InterruptedException, InstallException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
 
         try {
@@ -681,10 +847,16 @@
      * updated apps' manifest file.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testUpdateToSDCard() throws IOException, InterruptedException {
+    public void testUpdateToSDCard() throws IOException, InterruptedException, InstallException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
 
         try {
@@ -706,10 +878,17 @@
      * the update onto the device if the manifest has changed to installLocation=internalOnly
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
-    public void testUpdateSDCardToDevice() throws IOException, InterruptedException {
+    public void testUpdateSDCardToDevice() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
 
         try {
@@ -731,11 +910,18 @@
      * the update onto the device's forward-locked location
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndUpdateExternalLocForwardLockedApp()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, SyncException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating a forward-locked app marked preferExternal");
 
         try {
@@ -757,11 +943,18 @@
      * the update onto the device's forward-locked location
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndUpdateNoLocForwardLockedApp()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, SyncException,
+            TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating a forward-locked app with no installLocation pref set");
 
         try {
@@ -783,11 +976,18 @@
      * and then launched without crashing.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws SyncException if the sync failed for another reason.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchAllPermsAppOnSD()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with all perms set, installed on SD card");
 
         try {
@@ -808,11 +1008,17 @@
      * run without permissions errors.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchFLPermsAppOnSD()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
 
         try {
@@ -833,11 +1039,17 @@
      * run without permissions errors.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchBTPermsAppOnSD()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with bluetooth perms set, installed on SD card");
 
         try {
@@ -858,11 +1070,17 @@
      * SecurityException when launched if its other shared apps are not installed.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchSharedPermsAppOnSD_NoPerms()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
 
         try {
@@ -888,11 +1106,17 @@
      * shared apps are installed.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchSharedPermsAppOnSD_GrantedPerms()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
 
         try {
@@ -921,11 +1145,17 @@
      * run without permissions errors even after a reboot
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchFLPermsAppOnSD_Reboot()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
 
         try {
@@ -951,11 +1181,17 @@
      * shared apps are installed, even after a reboot.
      * <p/>
      * Assumes adb is running as root in device under test.
-     * @throws IOException if adb shell command failed
      * @throws InterruptedException if the thread was interrupted
+     * @throws TimeoutException in case of a timeout on the connection.
+     * @throws AdbCommandRejectedException if adb rejects the command
+     * @throws ShellCommandUnresponsiveException if the device did not output anything for
+     * a period longer than the max time to output.
+     * @throws IOException if connection to device was lost.
+     * @throws InstallException if the install failed.
      */
     public void testInstallAndLaunchSharedPermsAppOnSD_Reboot()
-            throws IOException, InterruptedException {
+            throws IOException, InterruptedException, InstallException, TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test launching an app on SD, with no explicit perms set after reboot");
 
         try {
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
index 715c55b..a2a5dd3 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
@@ -16,8 +16,11 @@
 
 package android.content.pm;
 
-import com.android.ddmlib.IDevice;
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.InstallException;
 import com.android.ddmlib.Log;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
 import com.android.hosttest.DeviceTestCase;
 import com.android.hosttest.DeviceTestSuite;
 
@@ -138,7 +141,9 @@
      * <p/>
      * Assumes adb is running as root in device under test.
      */
-    public void testUpdateAppManyTimesOnSD() throws IOException, InterruptedException {
+    public void testUpdateAppManyTimesOnSD() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating an app on SD numerous times");
 
         // cleanup test app just in case it already exists
@@ -173,7 +178,9 @@
      * <p/>
      * Assumes adb is running as root in device under test.
      */
-    public void testUninstallReinstallAppOnSDManyTimes() throws IOException, InterruptedException {
+    public void testUninstallReinstallAppOnSDManyTimes() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
 
         // cleanup test app just in case it was already exists
@@ -207,7 +214,9 @@
      * <p/>
      * Assumes adb is running as root in device under test.
      */
-    public void testInstallManyLargeAppsOnSD() throws IOException, InterruptedException {
+    public void testInstallManyLargeAppsOnSD() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installing 20 large apps onto the sd card");
 
         try {
@@ -251,7 +260,9 @@
      * <p/>
      * Assumes adb is running as root in device under test.
      */
-    public void testInstallManyAppsOnSD() throws IOException, InterruptedException {
+    public void testInstallManyAppsOnSD() throws IOException, InterruptedException,
+            InstallException, TimeoutException, AdbCommandRejectedException,
+            ShellCommandUnresponsiveException {
         Log.i(LOG_TAG, "Test installing 500 small apps onto SD");
 
         try {
diff --git a/docs/html/community/index.jd b/docs/html/community/index.jd
index 3e69de4..23203c1 100644
--- a/docs/html/community/index.jd
+++ b/docs/html/community/index.jd
@@ -4,10 +4,10 @@
 
 	<div id="mainBodyFluid">
 <h1>Community</h1>
-<p>Welcome to the Android developers community! We're glad you're here and invite you to participate in these discussions. Before posting, please read the <a href="http://source.android.com/discuss/android-discussion-groups-charter">Groups Charter</a> that covers the community guidelines.</p>
+<p>Welcome to the Android developers community! We're glad you're here and invite you to participate in these discussions. Before posting, please read the <a href="http://source.android.com/community/groups-charter.html">Groups Charter</a> that covers the community guidelines.</p>
 
 <p class="note"><strong>Note:</strong> If you are seeking discussion about Android source code (not application development),
-then please refer to the <a href="http://source.android.com/discuss">Open Source Project Mailing lists</a>.</p>
+then please refer to the <a href="http://source.android.com/community">Open Source Project Mailing lists</a>.</p>
 
 <p style="margin-bottom:.5em"><strong>Contents</strong></p>
 <ol class="toc">
@@ -31,7 +31,7 @@
 As you write your post, please do the following:
 <ol>
 <li><b>Read
-the <a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">mailing list charter</a></b> that covers the community guidelines. 
+the <a href="http://source.android.com/community/groups-charter.html">mailing list charter</a></b> that covers the community guidelines. 
 </li>
 <li><b>Select the most appropriate mailing list for your question</b>. There are several different lists for 
 developers, described below.</li>
diff --git a/docs/html/guide/topics/resources/animation-resource.jd b/docs/html/guide/topics/resources/animation-resource.jd
index e0ce051..972dd72 100644
--- a/docs/html/guide/topics/resources/animation-resource.jd
+++ b/docs/html/guide/topics/resources/animation-resource.jd
@@ -65,10 +65,10 @@
         android:pivotX="<em>float</em>"
         android:pivotY="<em>float</em>" /&gt;
     &lt;<a href="#translate-element">translate</a>
-        android:fromX="<em>float</em>"
-        android:toX="<em>float</em>"
-        android:fromY="<em>float</em>"
-        android:toY="<em>float</em>" /&gt;
+        android:fromXDelta="<em>float</em>"
+        android:toXDelta="<em>float</em>"
+        android:fromYDelta="<em>float</em>"
+        android:toYDelta="<em>float</em>" /&gt;
     &lt;<a href="#rotate-element">rotate</a>
         android:fromDegrees="<em>float</em>"
         android:toDegrees="<em>float</em>"
@@ -212,10 +212,10 @@
     android:shareInterpolator="false">
     &lt;scale
         android:interpolator="@android:anim/accelerate_decelerate_interpolator"
-        android:fromXScale="1.0" 
-        android:toXScale="1.4" 
-        android:fromYScale="1.0" 
-        android:toYScale="0.6" 
+        android:fromXScale="1.0"
+        android:toXScale="1.4"
+        android:fromYScale="1.0"
+        android:toYScale="0.6"
         android:pivotX="50%"
         android:pivotY="50%"
         android:fillAfter="false"
@@ -224,18 +224,18 @@
         android:interpolator="@android:anim/accelerate_interpolator"
         android:startOffset="700">
         &lt;scale
-            android:fromXScale="1.4" 
+            android:fromXScale="1.4"
             android:toXScale="0.0"
             android:fromYScale="0.6"
-            android:toYScale="0.0" 
-            android:pivotX="50%" 
-            android:pivotY="50%" 
+            android:toYScale="0.0"
+            android:pivotX="50%"
+            android:pivotY="50%"
             android:duration="400" />
         &lt;rotate
-            android:fromDegrees="0" 
+            android:fromDegrees="0"
             android:toDegrees="-45"
-            android:toYScale="0.0" 
-            android:pivotX="50%" 
+            android:toYScale="0.0"
+            android:pivotX="50%"
             android:pivotY="50%"
             android:duration="400" />
     &lt;/set>
diff --git a/docs/html/intl/ja/community/index.jd b/docs/html/intl/ja/community/index.jd
index 659aee7..490b23f 100644
--- a/docs/html/intl/ja/community/index.jd
+++ b/docs/html/intl/ja/community/index.jd
@@ -4,9 +4,9 @@
 
 	<div id="mainBodyFluid">
 			<h1>コミュニティ</h1>
-			<p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/discuss/android-discussion-groups-charter">グループの趣意</a>をお読みください。</p>
+			<p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/community/groups-charter.html">グループの趣意</a>をお読みください。</p>
 
-<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/discuss">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
+<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/community">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
 
 <p style="margin-bottom:.5em"><strong>目次</strong></p>
 <ol class="toc">
@@ -28,7 +28,7 @@
 
 <p>質問への答えが見つからない場合、コミュニティで質問することをおすすめします。投稿する際は、次の手順に従ってください。
 <ol>
-<li>コミュニティ ガイドラインが記載されている<b><a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">Android メーリングリストの趣意</a></b>をお読みください。 
+<li>コミュニティ ガイドラインが記載されている<b><a href="http://source.android.com/community/groups-charter.html">Android メーリングリストの趣意</a></b>をお読みください。 
 </li>
 <li><b>質問に最適なメーリング リストを選択してください</b>。後述するように、デベロッパー向けのメーリング リストは何種類かに分かれています。</li>
 <li>
diff --git a/docs/html/intl/ja/resources/community-groups.jd b/docs/html/intl/ja/resources/community-groups.jd
index c99b1f8..ecedde1 100644
--- a/docs/html/intl/ja/resources/community-groups.jd
+++ b/docs/html/intl/ja/resources/community-groups.jd
@@ -4,9 +4,9 @@
 
 	<div id="mainBodyFluid">
 			<h1>コミュニティ</h1>
-			<p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/discuss/android-discussion-groups-charter">グループの趣意</a>をお読みください。</p>
+			<p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/community/groups-charter.html">グループの趣意</a>をお読みください。</p>
 
-<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/discuss">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
+<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/community">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
 
 <p style="margin-bottom:.5em"><strong>目次</strong></p>
 <ol class="toc">
@@ -28,7 +28,7 @@
 
 <p>質問への答えが見つからない場合、コミュニティで質問することをおすすめします。投稿する際は、次の手順に従ってください。
 <ol>
-<li>コミュニティ ガイドラインが記載されている<b><a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">Android メーリングリストの趣意</a></b>をお読みください。 
+<li>コミュニティ ガイドラインが記載されている<b><a href="http://source.android.com/community/groups-charter.html">Android メーリングリストの趣意</a></b>をお読みください。 
 </li>
 <li><b>質問に最適なメーリング リストを選択してください</b>。後述するように、デベロッパー向けのメーリング リストは何種類かに分かれています。</li>
 <li>
diff --git a/docs/html/resources/articles/painless-threading.jd b/docs/html/resources/articles/painless-threading.jd
index 921f4df..17cec35 100644
--- a/docs/html/resources/articles/painless-threading.jd
+++ b/docs/html/resources/articles/painless-threading.jd
@@ -108,7 +108,7 @@
   new DownloadImageTask().execute("http://example.com/image.png");
 }
 
-private class DownloadImageTask extends AsyncTask&lt;string, void,="" bitmap=""&gt; {
+private class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
      protected Bitmap doInBackground(String... urls) {
          return loadImageFromNetwork(urls[0]);
      }
diff --git a/docs/html/resources/community-groups.jd b/docs/html/resources/community-groups.jd
index 651edbc..599c4ae 100644
--- a/docs/html/resources/community-groups.jd
+++ b/docs/html/resources/community-groups.jd
@@ -22,7 +22,7 @@
 
 <p>Welcome to the Android developers community! We're glad you're here and invite you to participate in discussions with other Android application developers on topics that interest you.</p>
 
-<p>The lists on this page are primarily for discussion about Android application development. If you are seeking discussion about Android source code (not application development), then please refer to the <a href="http://source.android.com/discuss">Open Source Project Mailing lists</a>.</p>
+<p>The lists on this page are primarily for discussion about Android application development. If you are seeking discussion about Android source code (not application development), then please refer to the <a href="http://source.android.com/community">Open Source Project Mailing lists</a>.</p>
 
 <h2 id="StackOverflow">Stack Overflow</h2>
 
@@ -56,7 +56,7 @@
 As you write your post, please do the following:
 <ol>
 <li><strong>Read
-the <a href="http://source.android.com/discuss/android-discussion-groups-charter">mailing list charter</a></strong> that covers the community guidelines.
+the <a href="http://source.android.com/community/groups-charter.html">mailing list charter</a></strong> that covers the community guidelines.
 </li>
 <li><strong>Select the most appropriate mailing list for your question</strong>. There are several different lists for
 developers, described below.</li>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 345f810..76cde73 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1221,7 +1221,7 @@
             checkRange(texs.length, texOffset, vertexCount);
         }
         if (colors != null) {
-            checkRange(colors.length, colorOffset, vertexCount);
+            checkRange(colors.length, colorOffset, vertexCount / 2);
         }
         if (indices != null) {
             checkRange(indices.length, indexOffset, indexCount);
diff --git a/libs/rs/rsNoise.cpp b/libs/rs/rsNoise.cpp
index 764dc1a..4b67586 100644
--- a/libs/rs/rsNoise.cpp
+++ b/libs/rs/rsNoise.cpp
@@ -253,4 +253,4 @@
 }
 
 }
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 013f8fc..3333268 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1215,8 +1215,12 @@
             prescan(path);
 
             File file = new File(path);
+
+            // lastModified is in milliseconds on Files.
+            long lastModifiedSeconds = file.lastModified() / 1000;
+
             // always scan the file, so we can return the content://media Uri for existing files
-            return mClient.doScanFile(path, mimeType, file.lastModified(), file.length(), true);
+            return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
             return null;
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 6f581d3..c5112a5 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -81,13 +81,13 @@
 }
 
 static bool fileMatchesExtension(const char* path, const char* extensions) {
-    char* extension = strrchr(path, '.');
+    const char* extension = strrchr(path, '.');
     if (!extension) return false;
     ++extension;    // skip the dot
     if (extension[0] == 0) return false;
 
     while (extensions[0]) {
-        char* comma = strchr(extensions, ',');
+        const char* comma = strchr(extensions, ',');
         size_t length = (comma ? comma - extensions : strlen(extensions));
         if (length == strlen(extension) && strncasecmp(extension, extensions, length) == 0) return true;
         extensions += length;
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 9e25681..53cc398 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -485,13 +485,13 @@
     copybit_device_t* const copybit = blitengine;
     if (copybit)  {
         copybit_image_t simg;
-        simg.w = src->width;
+        simg.w = src->stride;
         simg.h = src->height;
         simg.format = src->format;
         simg.handle = const_cast<native_handle_t*>(src->handle);
 
         copybit_image_t dimg;
-        dimg.w = dst->width;
+        dimg.w = dst->stride;
         dimg.h = dst->height;
         dimg.format = dst->format;
         dimg.handle = const_cast<native_handle_t*>(dst->handle);
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
index f031c79..ef66841 100644
--- a/opengl/tests/gl_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -181,4 +181,3 @@
 {
     background = 1.0f - background;
 }
-
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 4d35bec..2e33cf1 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -77,9 +77,12 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.text.Collator;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
 
 /**
  * This class provides a system service that manages input methods.
@@ -463,6 +466,9 @@
         screenOnOffFilt.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         mContext.registerReceiver(new ScreenOnOffReceiver(), screenOnOffFilt);
 
+        mStatusBar = statusBar;
+        statusBar.setIconVisibility("ime", false);
+
         buildInputMethodListLocked(mMethodList, mMethodMap);
 
         final String enabledStr = Settings.Secure.getString(
@@ -504,9 +510,6 @@
             }
         }
 
-        mStatusBar = statusBar;
-        statusBar.setIconVisibility("ime", false);
-
         mSettingsObserver = new SettingsObserver(mHandler);
         updateFromSettingsLocked();
     }
@@ -1506,21 +1509,22 @@
             hideInputMethodMenuLocked();
 
             int N = immis.size();
-    
-            mItems = new CharSequence[N];
-            mIms = new InputMethodInfo[N];
-    
-            int j = 0;
+
+            final Map<CharSequence, InputMethodInfo> imMap =
+                new TreeMap<CharSequence, InputMethodInfo>(Collator.getInstance());
+
             for (int i = 0; i < N; ++i) {
                 InputMethodInfo property = immis.get(i);
                 if (property == null) {
                     continue;
                 }
-                mItems[j] = property.loadLabel(pm);
-                mIms[j] = property;
-                j++;
+                imMap.put(property.loadLabel(pm), property);
             }
-    
+
+            N = imMap.size();
+            mItems = imMap.keySet().toArray(new CharSequence[N]);
+            mIms = imMap.values().toArray(new InputMethodInfo[N]);
+
             int checkedItem = 0;
             for (int i = 0; i < N; ++i) {
                 if (mIms[i].getId().equals(lastInputMethodId)) {
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 344bfc1..fded623 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1079,7 +1079,7 @@
 
     private void setUmsEnabling(boolean enable) {
         synchronized (mListeners) {
-            mUmsEnabling = true;
+            mUmsEnabling = enable;
         }
     }
 
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 63325dd..ed8b90b 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -129,11 +129,11 @@
     private boolean mBatteryFull;
     private NotificationRecord mLedNotification;
 
-    private static final int BATTERY_LOW_ARGB = 0xFFFF0000; // Charging Low - red solid on
-    private static final int BATTERY_MEDIUM_ARGB = 0xFFFFFF00;    // Charging - orange solid on
-    private static final int BATTERY_FULL_ARGB = 0xFF00FF00; // Charging Full - green solid on
-    private static final int BATTERY_BLINK_ON = 125;
-    private static final int BATTERY_BLINK_OFF = 2875;
+    private static int mBatteryLowARGB;
+    private static int mBatteryMediumARGB;
+    private static int mBatteryFullARGB;
+    private static int mBatteryLedOn;
+    private static int mBatteryLedOff;
 
     private static String idDebugString(Context baseContext, String packageName, int id) {
         Context c = null;
@@ -448,6 +448,17 @@
         mDefaultNotificationLedOff = resources.getInteger(
                 com.android.internal.R.integer.config_defaultNotificationLedOff);
 
+        mBatteryLowARGB = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationsBatteryLowARGB);
+        mBatteryMediumARGB = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationsBatteryMediumARGB);
+        mBatteryFullARGB = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationsBatteryFullARGB);
+        mBatteryLedOn = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationsBatteryLedOn);
+        mBatteryLedOff = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationsBatteryLedOff);
+
         // Don't start allowing notifications until the setup wizard has run once.
         // After that, including subsequent boots, init with notifications turned on.
         // This works on the first boot because the setup wizard will toggle this
@@ -1066,17 +1077,17 @@
         // Battery low always shows, other states only show if charging.
         if (mBatteryLow) {
             if (mBatteryCharging) {
-                mBatteryLight.setColor(BATTERY_LOW_ARGB);
+                mBatteryLight.setColor(mBatteryLowARGB);
             } else {
                 // Flash when battery is low and not charging
-                mBatteryLight.setFlashing(BATTERY_LOW_ARGB, LightsService.LIGHT_FLASH_TIMED,
-                        BATTERY_BLINK_ON, BATTERY_BLINK_OFF);
+                mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED,
+                        mBatteryLedOn, mBatteryLedOff);
             }
         } else if (mBatteryCharging) {
             if (mBatteryFull) {
-                mBatteryLight.setColor(BATTERY_FULL_ARGB);
+                mBatteryLight.setColor(mBatteryFullARGB);
             } else {
-                mBatteryLight.setColor(BATTERY_MEDIUM_ARGB);
+                mBatteryLight.setColor(mBatteryMediumARGB);
             }
         } else {
             mBatteryLight.turnOff();
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index a02c4e7..4fa89d9 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -687,7 +687,7 @@
                         break;
                     }
                 }
-                return new String(mBuffer, 0, 0, i);
+                return new String(mBuffer, 0, i);
             }
         } catch (java.io.FileNotFoundException e) {
         } catch (java.io.IOException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b37cd89..21df14a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -55,6 +55,7 @@
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IIntentReceiver;
@@ -1083,7 +1084,7 @@
                 d.setCancelable(false);
                 d.setTitle("System UIDs Inconsistent");
                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
-                d.setButton("I'm Feeling Lucky",
+                d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
                 mUidAlert = d;
                 d.show();
@@ -3569,10 +3570,12 @@
                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
                 if (pkgs != null) {
                     for (String pkg : pkgs) {
-                        if (forceStopPackageLocked(pkg, -1, false, false, false)) {
-                            setResultCode(Activity.RESULT_OK);
-                            return;
-                        }
+                        synchronized (ActivityManagerService.this) {
+                          if (forceStopPackageLocked(pkg, -1, false, false, false)) {
+                              setResultCode(Activity.RESULT_OK);
+                              return;
+                          }
+                       }
                     }
                 }
             }
@@ -6130,7 +6133,28 @@
                 sr.crashCount++;
             }
         }
-        
+
+        // If the crashing process is what we consider to be the "home process" and it has been
+        // replaced by a third-party app, clear the package preferred activities from packages
+        // with a home activity running in the process to prevent a repeatedly crashing app
+        // from blocking the user to manually clear the list.
+        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
+                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+            Iterator it = mHomeProcess.activities.iterator();
+            while (it.hasNext()) {
+                ActivityRecord r = (ActivityRecord)it.next();
+                if (r.isHomeActivity) {
+                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
+                    try {
+                        ActivityThread.getPackageManager()
+                                .clearPackagePreferredActivities(r.packageName);
+                    } catch (RemoteException c) {
+                        // pm is in same process, this will never happen.
+                    }
+                }
+            }
+        }
+
         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
         return true;
     }
diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
index 8e9818d..9fb48b3 100644
--- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
+++ b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Handler;
 import android.os.Message;
 
@@ -49,7 +50,7 @@
         text.append(" is waiting for the debugger to attach.");
 
         setMessage(text.toString());
-        setButton("Force Close", mHandler.obtainMessage(1, app));
+        setButton(DialogInterface.BUTTON_POSITIVE, "Force Close", mHandler.obtainMessage(1, app));
         setTitle("Waiting For Debugger");
         getWindow().setTitle("Waiting For Debugger: " + app.info.processName);
     }
diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/java/com/android/server/am/FactoryErrorDialog.java
index 2e25474..b19bb5ca 100644
--- a/services/java/com/android/server/am/FactoryErrorDialog.java
+++ b/services/java/com/android/server/am/FactoryErrorDialog.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Handler;
 import android.os.Message;
 
@@ -26,7 +27,8 @@
         setCancelable(false);
         setTitle(context.getText(com.android.internal.R.string.factorytest_failed));
         setMessage(msg);
-        setButton(context.getText(com.android.internal.R.string.factorytest_reboot),
+        setButton(DialogInterface.BUTTON_POSITIVE,
+                context.getText(com.android.internal.R.string.factorytest_reboot),
                 mHandler.obtainMessage(0));
         getWindow().setTitle("Factory Error");
     }
diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
index 0240748..fdf9abc 100644
--- a/services/surfaceflinger/LayerBuffer.cpp
+++ b/services/surfaceflinger/LayerBuffer.cpp
@@ -495,7 +495,7 @@
     const ISurface::BufferHeap& buffers(mBufferHeap);
     uint32_t w = mLayer.mTransformedBounds.width();
     uint32_t h = mLayer.mTransformedBounds.height();
-    if (buffers.w * h != buffers.h * w) {
+    if (mLayer.getOrientation() & (Transform::ROT_90 | Transform::ROT_270)) {
         int t = w; w = h; h = t;
     }
 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f5c6909..7829006 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -55,6 +55,12 @@
     public static final char WILD = 'N';
 
     /*
+     * Calling Line Identification Restriction (CLIR)
+     */
+    private static final String CLIR_ON = "*31#+";
+    private static final String CLIR_OFF = "#31#+";
+
+    /*
      * TOA = TON + NPI
      * See TS 24.008 section 10.5.4.7 for details.
      * These are the only really useful TOA values
@@ -179,8 +185,6 @@
      *  Please note that the GSM wild character is allowed in the result.
      *  This must be resolved before dialing.
      *
-     *  Allows + only in the first  position in the result string.
-     *
      *  Returns null if phoneNumber == null
      */
     public static String
@@ -203,6 +207,11 @@
             }
         }
 
+        int pos = addPlusChar(phoneNumber);
+        if (pos >= 0 && ret.length() > pos) {
+            ret.insert(pos, '+');
+        }
+
         return ret.toString();
     }
 
@@ -304,6 +313,28 @@
         }
     }
 
+    /** GSM codes
+     *  Finds if a GSM code includes the international prefix (+).
+     *
+     * @param number the number to dial.
+     *
+     * @return the position where the + char will be inserted, -1 if the GSM code was not found.
+     */
+    private static int
+    addPlusChar(String number) {
+        int pos = -1;
+
+        if (number.startsWith(CLIR_OFF)) {
+            pos = CLIR_OFF.length() - 1;
+        }
+
+        if (number.startsWith(CLIR_ON)) {
+            pos = CLIR_ON.length() - 1;
+        }
+
+        return pos;
+    }
+
     /**
      * Extracts the post-dial sequence of DTMF control digits, pauses, and
      * waits. Strips separators. This string may be empty, but will not be null
@@ -1119,7 +1150,7 @@
                 && text.charAt(2) == '1') {
                 formatType = FORMAT_JAPAN;
             } else {
-                return;
+                formatType = FORMAT_UNKNOWN;
             }
         }
 
@@ -1130,6 +1161,9 @@
             case FORMAT_JAPAN:
                 formatJapaneseNumber(text);
                 return;
+            case FORMAT_UNKNOWN:
+                removeDashes(text);
+                return;
         }
     }
 
@@ -1165,14 +1199,7 @@
         CharSequence saved = text.subSequence(0, length);
 
         // Strip the dashes first, as we're going to add them back
-        int p = 0;
-        while (p < text.length()) {
-            if (text.charAt(p) == '-') {
-                text.delete(p, p + 1);
-            } else {
-                p++;
-            }
-        }
+        removeDashes(text);
         length = text.length();
 
         // When scanning the number we record where dashes need to be added,
@@ -1276,6 +1303,22 @@
         JapanesePhoneNumberFormatter.format(text);
     }
 
+    /**
+     * Removes all dashes from the number.
+     *
+     * @param text the number to clear from dashes
+     */
+    private static void removeDashes(Editable text) {
+        int p = 0;
+        while (p < text.length()) {
+            if (text.charAt(p) == '-') {
+                text.delete(p, p + 1);
+           } else {
+                p++;
+           }
+        }
+    }
+
     // Three and four digit phone numbers for either special services,
     // or 3-6 digit addresses from the network (eg carrier-originated SMS messages) should
     // not match.
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
index c8c0658..a175d49 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
@@ -186,7 +186,12 @@
         }
 
         ArrayList<AdnRecord>  oldAdnList;
-        oldAdnList = getRecordsIfLoaded(efid);
+
+        if (efid == EF_PBR) {
+            oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
+        } else {
+            oldAdnList = getRecordsIfLoaded(efid);
+        }
 
         if (oldAdnList == null) {
             sendErrorResponse(response, "Adn list not exist for EF:" + efid);
@@ -208,6 +213,17 @@
             return;
         }
 
+        if (efid == EF_PBR) {
+            AdnRecord foundAdn = oldAdnList.get(index-1);
+            efid = foundAdn.efid;
+            extensionEF = foundAdn.extRecord;
+            index = foundAdn.recordNumber;
+
+            newAdn.efid = efid;
+            newAdn.extRecord = extensionEF;
+            newAdn.recordNumber = index;
+        }
+
         Message pendingResponse = userWriteResponse.get(efid);
 
         if (pendingResponse != null) {
@@ -331,6 +347,7 @@
 
                 if (ar.exception == null) {
                     adnLikeFiles.get(efid).set(index - 1, adn);
+                    mUsimPhoneBookManager.invalidateCache();
                 }
 
                 Message response = userWriteResponse.get(efid);
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index b962375..815fbfb 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -73,10 +73,10 @@
     protected Registrant mSmsOnSimRegistrant;
     protected Registrant mSmsStatusRegistrant;
     protected Registrant mSsnRegistrant;
-    protected Registrant mStkSessionEndRegistrant;
-    protected Registrant mStkProCmdRegistrant;
-    protected Registrant mStkEventRegistrant;
-    protected Registrant mStkCallSetUpRegistrant;
+    protected Registrant mCatSessionEndRegistrant;
+    protected Registrant mCatProCmdRegistrant;
+    protected Registrant mCatEventRegistrant;
+    protected Registrant mCatCallSetUpRegistrant;
     protected Registrant mIccSmsFullRegistrant;
     protected Registrant mEmergencyCallbackModeRegistrant;
     protected Registrant mIccRefreshRegistrant;
@@ -395,36 +395,36 @@
         mSsnRegistrant.clear();
     }
 
-    public void setOnStkSessionEnd(Handler h, int what, Object obj) {
-        mStkSessionEndRegistrant = new Registrant (h, what, obj);
+    public void setOnCatSessionEnd(Handler h, int what, Object obj) {
+        mCatSessionEndRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnStkSessionEnd(Handler h) {
-        mStkSessionEndRegistrant.clear();
+    public void unSetOnCatSessionEnd(Handler h) {
+        mCatSessionEndRegistrant.clear();
     }
 
-    public void setOnStkProactiveCmd(Handler h, int what, Object obj) {
-        mStkProCmdRegistrant = new Registrant (h, what, obj);
+    public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
+        mCatProCmdRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnStkProactiveCmd(Handler h) {
-        mStkProCmdRegistrant.clear();
+    public void unSetOnCatProactiveCmd(Handler h) {
+        mCatProCmdRegistrant.clear();
     }
 
-    public void setOnStkEvent(Handler h, int what, Object obj) {
-        mStkEventRegistrant = new Registrant (h, what, obj);
+    public void setOnCatEvent(Handler h, int what, Object obj) {
+        mCatEventRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnStkEvent(Handler h) {
-        mStkEventRegistrant.clear();
+    public void unSetOnCatEvent(Handler h) {
+        mCatEventRegistrant.clear();
     }
 
-    public void setOnStkCallSetUp(Handler h, int what, Object obj) {
-        mStkCallSetUpRegistrant = new Registrant (h, what, obj);
+    public void setOnCatCallSetUp(Handler h, int what, Object obj) {
+        mCatCallSetUpRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnStkCallSetUp(Handler h) {
-        mStkCallSetUpRegistrant.clear();
+    public void unSetOnCatCallSetUp(Handler h) {
+        mCatCallSetUpRegistrant.clear();
     }
 
     public void setOnIccSmsFull(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 8e03c5a..5de0426 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -374,48 +374,48 @@
     void unSetOnSuppServiceNotification(Handler h);
 
     /**
-     * Sets the handler for Session End Notifications for STK.
+     * Sets the handler for Session End Notifications for CAT.
      * Unlike the register* methods, there's only one notification handler
      *
      * @param h Handler for notification message.
      * @param what User-defined message code.
      * @param obj User object.
      */
-    void setOnStkSessionEnd(Handler h, int what, Object obj);
-    void unSetOnStkSessionEnd(Handler h);
+    void setOnCatSessionEnd(Handler h, int what, Object obj);
+    void unSetOnCatSessionEnd(Handler h);
 
     /**
-     * Sets the handler for Proactive Commands for STK.
+     * Sets the handler for Proactive Commands for CAT.
      * Unlike the register* methods, there's only one notification handler
      *
      * @param h Handler for notification message.
      * @param what User-defined message code.
      * @param obj User object.
      */
-    void setOnStkProactiveCmd(Handler h, int what, Object obj);
-    void unSetOnStkProactiveCmd(Handler h);
+    void setOnCatProactiveCmd(Handler h, int what, Object obj);
+    void unSetOnCatProactiveCmd(Handler h);
 
     /**
-     * Sets the handler for Event Notifications for STK.
+     * Sets the handler for Event Notifications for CAT.
      * Unlike the register* methods, there's only one notification handler
      *
      * @param h Handler for notification message.
      * @param what User-defined message code.
      * @param obj User object.
      */
-    void setOnStkEvent(Handler h, int what, Object obj);
-    void unSetOnStkEvent(Handler h);
+    void setOnCatEvent(Handler h, int what, Object obj);
+    void unSetOnCatEvent(Handler h);
 
     /**
-     * Sets the handler for Call Set Up Notifications for STK.
+     * Sets the handler for Call Set Up Notifications for CAT.
      * Unlike the register* methods, there's only one notification handler
      *
      * @param h Handler for notification message.
      * @param what User-defined message code.
      * @param obj User object.
      */
-    void setOnStkCallSetUp(Handler h, int what, Object obj);
-    void unSetOnStkCallSetUp(Handler h);
+    void setOnCatCallSetUp(Handler h, int what, Object obj);
+    void unSetOnCatCallSetUp(Handler h);
 
     /**
      * Enables/disbables supplementary service related notifications from
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index d3a34ec..90f9e8c 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -672,12 +672,11 @@
      * @return true if a ICC card is present
      */
     public boolean hasIccCard() {
-        boolean isIccPresent;
-        if (mPhone.getPhoneName().equals("GSM")) {
-            return mIccCardStatus.getCardState().isCardPresent();
-        } else {
-            // TODO: Make work with a CDMA device with a RUIM card.
+        if (mIccCardStatus == null) {
             return false;
+        } else {
+            // Returns ICC card status for both GSM and CDMA mode
+            return mIccCardStatus.getCardState().isCardPresent();
         }
     }
 
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 9f8e57f..2f22d74 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -62,8 +62,8 @@
                             logd("GET_RECORD_SIZE Size " + recordSize[0] +
                                     " total " + recordSize[1] +
                                     " #record " + recordSize[2]);
-                            mLock.notifyAll();
                         }
+                        mLock.notifyAll();
                     }
                     break;
                 case EVENT_UPDATE_DONE:
@@ -144,6 +144,9 @@
         if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
                 " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
                 " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
+
+        efid = updateEfForIccType(efid);
+
         synchronized(mLock) {
             checkThread();
             success = false;
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index 71936f1..957eddd 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -51,6 +51,8 @@
             ret.append((char)('0' + v));
 
             v = (data[i] >> 4) & 0xf;
+            // Some PLMNs have 'f' as high nibble, ignore it
+            if (v == 0xf) continue;
             if (v > 9)  break;
             ret.append((char)('0' + v));
         }
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 3d410fd..569ac5c 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2339,7 +2339,7 @@
             case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
             case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:  ret =  responseVoid(p); break;
             case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:  ret =  responseCdmaSms(p); break;
-            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseString(p); break;
+            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseRaw(p); break;
             case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:  ret =  responseVoid(p); break;
             case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
             case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
@@ -2481,8 +2481,8 @@
             case RIL_UNSOL_STK_SESSION_END:
                 if (RILJ_LOGD) unsljLog(response);
 
-                if (mStkSessionEndRegistrant != null) {
-                    mStkSessionEndRegistrant.notifyRegistrant(
+                if (mCatSessionEndRegistrant != null) {
+                    mCatSessionEndRegistrant.notifyRegistrant(
                                         new AsyncResult (null, ret, null));
                 }
                 break;
@@ -2490,8 +2490,8 @@
             case RIL_UNSOL_STK_PROACTIVE_COMMAND:
                 if (RILJ_LOGD) unsljLogRet(response, ret);
 
-                if (mStkProCmdRegistrant != null) {
-                    mStkProCmdRegistrant.notifyRegistrant(
+                if (mCatProCmdRegistrant != null) {
+                    mCatProCmdRegistrant.notifyRegistrant(
                                         new AsyncResult (null, ret, null));
                 }
                 break;
@@ -2499,8 +2499,8 @@
             case RIL_UNSOL_STK_EVENT_NOTIFY:
                 if (RILJ_LOGD) unsljLogRet(response, ret);
 
-                if (mStkEventRegistrant != null) {
-                    mStkEventRegistrant.notifyRegistrant(
+                if (mCatEventRegistrant != null) {
+                    mCatEventRegistrant.notifyRegistrant(
                                         new AsyncResult (null, ret, null));
                 }
                 break;
@@ -2508,8 +2508,8 @@
             case RIL_UNSOL_STK_CALL_SETUP:
                 if (RILJ_LOGD) unsljLogRet(response, ret);
 
-                if (mStkCallSetUpRegistrant != null) {
-                    mStkCallSetUpRegistrant.notifyRegistrant(
+                if (mCatCallSetUpRegistrant != null) {
+                    mCatCallSetUpRegistrant.notifyRegistrant(
                                         new AsyncResult (null, ret, null));
                 }
                 break;
@@ -3406,6 +3406,8 @@
         RILRequest rr = RILRequest.obtain(
                 RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
 
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
         send(rr);
     }
 
@@ -3419,6 +3421,9 @@
         rr.mp.writeInt(1);
         rr.mp.writeInt(ttyMode);
 
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                + " : " + ttyMode);
+
         send(rr);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index a636a4b..2f5d3ec 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -24,7 +24,6 @@
 import android.util.Config;
 import android.util.Log;
 
-
 /**
  * WAP push handler class.
  *
@@ -59,7 +58,7 @@
      */
     public int dispatchWapPdu(byte[] pdu) {
 
-        if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
+        if (Config.DEBUG) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
 
         int index = 0;
         int transactionId = pdu[index++] & 0xFF;
@@ -68,7 +67,7 @@
 
         if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
                 (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
-            if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
+            if (Config.DEBUG) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
             return Intents.RESULT_SMS_HANDLED;
         }
 
@@ -81,7 +80,7 @@
          * So it will be encoded in no more than 5 octets.
          */
         if (pduDecoder.decodeUintvarInteger(index) == false) {
-            if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error.");
+            if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Length error.");
             return Intents.RESULT_SMS_GENERIC_ERROR;
         }
         headerLength = (int)pduDecoder.getValue32();
@@ -102,136 +101,44 @@
          * Length = Uintvar-integer
          */
         if (pduDecoder.decodeContentType(index) == false) {
-            if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
+            if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
             return Intents.RESULT_SMS_GENERIC_ERROR;
         }
-        int binaryContentType;
+
         String mimeType = pduDecoder.getValueString();
-        if (mimeType == null) {
-            binaryContentType = (int)pduDecoder.getValue32();
-            // TODO we should have more generic way to map binaryContentType code to mimeType.
-            switch (binaryContentType) {
-                case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_MMS:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS;
-                    break;
-                case WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF:
-                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF;
-                    break;
-                default:
-                    if (Config.LOGD) {
-                        Log.w(LOG_TAG,
-                                "Received PDU. Unsupported Content-Type = " + binaryContentType);
-                    }
-                return Intents.RESULT_SMS_HANDLED;
-            }
-        } else {
-            if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
-            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF)) {
-                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF;
-            } else {
-                if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
-                return Intents.RESULT_SMS_HANDLED;
-            }
-        }
+
         index += pduDecoder.getDecodedDataLength();
 
-        boolean dispatchedByApplication = false;
-        switch (binaryContentType) {
-            case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
-                dispatchWapPdu_PushCO(pdu, transactionId, pduType, headerStartIndex, headerLength);
-                dispatchedByApplication = true;
-                break;
-            case WspTypeDecoder.CONTENT_TYPE_B_MMS:
-                dispatchWapPdu_MMS(pdu, transactionId, pduType, headerStartIndex, headerLength);
-                dispatchedByApplication = true;
-                break;
-            default:
-                break;
-        }
-        if (dispatchedByApplication == false) {
-            dispatchWapPdu_default(pdu, transactionId, pduType, mimeType,
-                                   headerStartIndex, headerLength);
-        }
-        return Activity.RESULT_OK;
-    }
-
-    private void dispatchWapPdu_default(byte[] pdu, int transactionId, int pduType,
-                                        String mimeType, int headerStartIndex, int headerLength) {
         byte[] header = new byte[headerLength];
         System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-        int dataIndex = headerStartIndex + headerLength;
-        byte[] data;
 
-        data = new byte[pdu.length - dataIndex];
-        System.arraycopy(pdu, dataIndex, data, 0, data.length);
+        byte[] intentData;
+        String permission;
+
+        if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+            intentData = pdu;
+        } else {
+            int dataIndex = headerStartIndex + headerLength;
+            intentData = new byte[pdu.length - dataIndex];
+            System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
+        }
+
+        if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
+            permission = "android.permission.RECEIVE_MMS";
+        } else {
+            permission = "android.permission.RECEIVE_WAP_PUSH";
+        }
 
         Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
         intent.setType(mimeType);
         intent.putExtra("transactionId", transactionId);
         intent.putExtra("pduType", pduType);
         intent.putExtra("header", header);
-        intent.putExtra("data", data);
+        intent.putExtra("data", intentData);
+        intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
 
-        mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
+        mSmsDispatcher.dispatch(intent, permission);
+
+        return Activity.RESULT_OK;
     }
-
-    private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType,
-                                       int headerStartIndex, int headerLength) {
-        byte[] header = new byte[headerLength];
-        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-
-        Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
-        intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO);
-        intent.putExtra("transactionId", transactionId);
-        intent.putExtra("pduType", pduType);
-        intent.putExtra("header", header);
-        intent.putExtra("data", pdu);
-
-        mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
-    }
-
-    private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType,
-                                    int headerStartIndex, int headerLength) {
-        byte[] header = new byte[headerLength];
-        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-        int dataIndex = headerStartIndex + headerLength;
-        byte[] data = new byte[pdu.length - dataIndex];
-        System.arraycopy(pdu, dataIndex, data, 0, data.length);
-
-        Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
-        intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS);
-        intent.putExtra("transactionId", transactionId);
-        intent.putExtra("pduType", pduType);
-        intent.putExtra("header", header);
-        intent.putExtra("data", data);
-
-        mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
-    }
-}
-
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 336bc82..6bf6b13 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -16,11 +16,12 @@
 
 package com.android.internal.telephony;
 
+import java.util.HashMap;
 
 /**
- *  Implement the WSP data type decoder.
+ * Implement the WSP data type decoder.
  *
- *  @hide
+ * @hide
  */
 public class WspTypeDecoder {
 
@@ -30,35 +31,176 @@
     public static final int PDU_TYPE_PUSH = 0x06;
     public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
 
-    // TODO we should have mapping between those binary code and mime type string.
-    //  see http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
+    private final static HashMap<Integer, String> WELL_KNOWN_MIME_TYPES =
+            new HashMap<Integer, String>();
 
-    public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a;
-    public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b;
-    public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e;
-    public static final int CONTENT_TYPE_B_PUSH_SL = 0x30;
-    public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
-    public static final int CONTENT_TYPE_B_MMS = 0x3e;
-    public static final int CONTENT_TYPE_B_VND_DOCOMO_PF = 0x0310;
+    private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
+            new HashMap<Integer, String>();
 
-    public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
-            "application/vnd.oma.drm.rights+xml";
-    public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML =
-            "application/vnd.oma.drm.rights+wbxml";
-    public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic";
-    public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc";
-    public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
-    public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
-    public static final String CONTENT_MIME_TYPE_B_VND_DOCOMO_PF = "application/vnd.docomo.pf";
+    private static final int Q_VALUE = 0x00;
 
-    public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
+    static {
+        WELL_KNOWN_MIME_TYPES.put(0x00, "*/*");
+        WELL_KNOWN_MIME_TYPES.put(0x01, "text/*");
+        WELL_KNOWN_MIME_TYPES.put(0x02, "text/html");
+        WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain");
+        WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml");
+        WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml");
+        WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar");
+        WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard");
+        WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
+        WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
+        WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
+        WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*");
+        WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed");
+        WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data");
+        WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes");
+        WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative");
+        WELL_KNOWN_MIME_TYPES.put(0x10, "application/*");
+        WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm");
+        WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
+        WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc");
+        WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
+        WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
+        WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
+        WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
+        WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
+        WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
+        WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
+        WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
+        WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*");
+        WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif");
+        WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg");
+        WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff");
+        WELL_KNOWN_MIME_TYPES.put(0x20, "image/png");
+        WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
+        WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
+        WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
+        WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
+        WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
+        WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
+        WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml");
+        WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml");
+        WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
+        WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
+        WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
+        WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
+        WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
+        WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
+        WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
+        WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co");
+        WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
+        WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
+        WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
+        WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
+        WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime");
+        WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
+        WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
+        WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
+        WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css");
+        WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
+        WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
+        WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
+        WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
+        WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
+        WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
+        WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
+        WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*");
+        WELL_KNOWN_MIME_TYPES.put(0x50, "video/*");
+        WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey");
+        WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
+        WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
 
+        WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
+        WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
+        WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
+        WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng");
+        WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar");
+        WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
+        WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
+        WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
+        WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
+        WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
+        WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
+        WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
+        WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
+        WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
+        WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
+        WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
+        WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
+        WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
+
+        WELL_KNOWN_PARAMETERS.put(0x00, "Q");
+        WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
+        WELL_KNOWN_PARAMETERS.put(0x02, "Level");
+        WELL_KNOWN_PARAMETERS.put(0x03, "Type");
+        WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
+        WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
+        WELL_KNOWN_PARAMETERS.put(0x09, "Type");
+        WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
+        WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
+        WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
+        WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
+        WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
+        WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
+        WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
+        WELL_KNOWN_PARAMETERS.put(0x16, "Size");
+        WELL_KNOWN_PARAMETERS.put(0x17, "Name");
+        WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
+        WELL_KNOWN_PARAMETERS.put(0x19, "Start");
+        WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
+        WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
+        WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
+        WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
+    }
+
+    public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
+    public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
 
     byte[] wspData;
     int    dataLength;
     long   unsigned32bit;
     String stringValue;
 
+    HashMap<String, String> contentParameters;
+
     public WspTypeDecoder(byte[] pdu) {
         wspData = pdu;
     }
@@ -69,17 +211,17 @@
      * @param startIndex The starting position of the "Text-string" in this pdu
      *
      * @return false when error(not a Text-string) occur
-     *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         return value can be retrieved by getValueString() method length of data in pdu can be
+     *         retrieved by getDecodedDataLength() method
      */
     public boolean decodeTextString(int startIndex) {
         int index = startIndex;
         while (wspData[index] != 0) {
             index++;
         }
-        dataLength  = index - startIndex + 1;
+        dataLength = index - startIndex + 1;
         if (wspData[startIndex] == 127) {
-            stringValue = new String(wspData, startIndex+1, dataLength - 2);
+            stringValue = new String(wspData, startIndex + 1, dataLength - 2);
         } else {
             stringValue = new String(wspData, startIndex, dataLength - 1);
         }
@@ -87,13 +229,33 @@
     }
 
     /**
+     * Decode the "Token-text" type for WSP pdu
+     *
+     * @param startIndex The starting position of the "Token-text" in this pdu
+     *
+     * @return always true
+     *         return value can be retrieved by getValueString() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
+     */
+    public boolean decodeTokenText(int startIndex) {
+        int index = startIndex;
+        while (wspData[index] != 0) {
+            index++;
+        }
+        dataLength = index - startIndex + 1;
+        stringValue = new String(wspData, startIndex, dataLength - 1);
+
+        return true;
+    }
+
+    /**
      * Decode the "Short-integer" type for WSP pdu
      *
      * @param startIndex The starting position of the "Short-integer" in this pdu
      *
      * @return false when error(not a Short-integer) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeShortInteger(int startIndex) {
         if ((wspData[startIndex] & 0x80) == 0) {
@@ -111,7 +273,7 @@
      *
      * @return false when error(not a Long-integer) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeLongInteger(int startIndex) {
         int lengthMultiOctet = wspData[startIndex] & 0xff;
@@ -120,10 +282,10 @@
             return false;
         }
         unsigned32bit = 0;
-        for (int i=1; i<=lengthMultiOctet; i++) {
-            unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff);
+        for (int i = 1; i <= lengthMultiOctet; i++) {
+            unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff);
         }
-        dataLength = 1+lengthMultiOctet;
+        dataLength = 1 + lengthMultiOctet;
         return true;
     }
 
@@ -134,7 +296,7 @@
      *
      * @return false when error(not a Integer-Value) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeIntegerValue(int startIndex) {
         if (decodeShortInteger(startIndex) == true) {
@@ -150,10 +312,10 @@
      *
      * @return false when error(not a Uintvar-integer) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeUintvarInteger(int startIndex) {
-        int  index = startIndex;
+        int index = startIndex;
 
         unsigned32bit = 0;
         while ((wspData[index] & 0x80) != 0) {
@@ -175,7 +337,7 @@
      *
      * @return false when error(not a Value-length) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeValueLength(int startIndex) {
         if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
@@ -185,22 +347,22 @@
             unsigned32bit = wspData[startIndex];
             dataLength = 1;
         } else {
-            decodeUintvarInteger(startIndex+1);
-            dataLength ++;
+            decodeUintvarInteger(startIndex + 1);
+            dataLength++;
         }
         return true;
     }
 
     /**
-    * Decode the "Extension-media" type for WSP PDU.
-    *
-    * @param startIndex The starting position of the "Extension-media" in this PDU.
-    *
-    * @return false on error, such as if there is no Extension-media at startIndex.
-    * Side-effects: updates stringValue (available with getValueString()), which will be
-    * null on error. The length of the data in the PDU is available with getValue32(), 0
-    * on error.
-    */
+     * Decode the "Extension-media" type for WSP PDU.
+     *
+     * @param startIndex The starting position of the "Extension-media" in this PDU.
+     *
+     * @return false on error, such as if there is no Extension-media at startIndex.
+     *         Side-effects: updates stringValue (available with
+     *         getValueString()), which will be null on error. The length of the
+     *         data in the PDU is available with getValue32(), 0 on error.
+     */
     public boolean decodeExtensionMedia(int startIndex) {
         int index = startIndex;
         dataLength = 0;
@@ -212,7 +374,7 @@
             index++;
         }
 
-        dataLength  = index - startIndex + 1;
+        dataLength = index - startIndex + 1;
         stringValue = new String(wspData, startIndex, dataLength - 1);
 
         return rtrn;
@@ -225,7 +387,7 @@
      *
      * @return false when error(not a Constrained-encoding) occur
      *         return value can be retrieved first by getValueString() and second by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeConstrainedEncoding(int startIndex) {
         if (decodeShortInteger(startIndex) == true) {
@@ -240,31 +402,162 @@
      *
      * @param startIndex The starting position of the "Content-type" in this pdu
      *
-     * @return false when error(not a Content-type) occur
-     *         return value can be retrieved first by getValueString() and second by getValue32()
-     *         method length of data in pdu can be retrieved by getValue32() method
+     * @return false when error(not a Content-type) occurs
+     *         If a content type exists in the headers (either as inline string, or as well-known
+     *         value), getValueString() will return it. If a 'well known value' is encountered that
+     *         cannot be mapped to a string mime type, getValueString() will return null, and
+     *         getValue32() will return the unknown content type value.
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
+     *         Any content type parameters will be accessible via getContentParameters()
      */
     public boolean decodeContentType(int startIndex) {
         int mediaPrefixLength;
-        long mediaFieldLength;
+        contentParameters = new HashMap<String, String>();
 
-        if (decodeValueLength(startIndex) == false) {
-            return decodeConstrainedEncoding(startIndex);
-        }
-        mediaPrefixLength = getDecodedDataLength();
-        mediaFieldLength = getValue32();
-        if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
-            dataLength += mediaPrefixLength;
-            stringValue = null;
-            return true;
-        }
-        if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
-            dataLength += mediaPrefixLength;
-            return true;
+        try {
+            if (decodeValueLength(startIndex) == false) {
+                boolean found = decodeConstrainedEncoding(startIndex);
+                if (found) {
+                    expandWellKnownMimeType();
+                }
+                return found;
+            }
+            int headersLength = (int) unsigned32bit;
+            mediaPrefixLength = getDecodedDataLength();
+            if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
+                dataLength += mediaPrefixLength;
+                int readLength = dataLength;
+                stringValue = null;
+                expandWellKnownMimeType();
+                long wellKnownValue = unsigned32bit;
+                String mimeType = stringValue;
+                if (readContentParameters(startIndex + dataLength,
+                        (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+                    dataLength += readLength;
+                    unsigned32bit = wellKnownValue;
+                    stringValue = mimeType;
+                    return true;
+                }
+                return false;
+            }
+            if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
+                dataLength += mediaPrefixLength;
+                int readLength = dataLength;
+                expandWellKnownMimeType();
+                long wellKnownValue = unsigned32bit;
+                String mimeType = stringValue;
+                if (readContentParameters(startIndex + dataLength,
+                        (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+                    dataLength += readLength;
+                    unsigned32bit = wellKnownValue;
+                    stringValue = mimeType;
+                    return true;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            //something doesn't add up
+            return false;
         }
         return false;
     }
 
+    private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) {
+
+        int totalRead = 0;
+
+        if (leftToRead > 0) {
+            byte nextByte = wspData[startIndex];
+            String value = null;
+            String param = null;
+            if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped
+                decodeTokenText(startIndex);
+                param = stringValue;
+                totalRead += dataLength;
+            } else { // typed
+                if (decodeIntegerValue(startIndex)) {
+                    totalRead += dataLength;
+                    int wellKnownParameterValue = (int) unsigned32bit;
+                    param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue);
+                    if (param == null) {
+                        param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue);
+                    }
+                    // special case for the "Q" parameter, value is a uintvar
+                    if (wellKnownParameterValue == Q_VALUE) {
+                        if (decodeUintvarInteger(startIndex + totalRead)) {
+                            totalRead += dataLength;
+                            value = String.valueOf(unsigned32bit);
+                            contentParameters.put(param, value);
+                            return readContentParameters(startIndex + totalRead, leftToRead
+                                                            - totalRead, accumulator + totalRead);
+                        } else {
+                            return false;
+                        }
+                    }
+                } else {
+                    return false;
+                }
+            }
+
+            if (decodeNoValue(startIndex + totalRead)) {
+                totalRead += dataLength;
+                value = null;
+            } else if (decodeIntegerValue(startIndex + totalRead)) {
+                totalRead += dataLength;
+                int intValue = (int) unsigned32bit;
+                if (intValue == 0) {
+                    value = "";
+                } else {
+                    value = String.valueOf(intValue);
+                }
+            } else {
+                decodeTokenText(startIndex + totalRead);
+                totalRead += dataLength;
+                value = stringValue;
+                if (value.startsWith("\"")) {
+                    // quoted string, so remove the quote
+                    value = value.substring(1);
+                }
+            }
+            contentParameters.put(param, value);
+            return readContentParameters(startIndex + totalRead, leftToRead - totalRead,
+                                            accumulator + totalRead);
+
+        } else {
+            dataLength = accumulator;
+            return true;
+        }
+    }
+
+    /**
+     * Check if the next byte is No-Value
+     *
+     * @param startIndex The starting position of the "Content length" in this pdu
+     *
+     * @return true if and only if the next byte is 0x00
+     */
+    private boolean decodeNoValue(int startIndex) {
+        if (wspData[startIndex] == 0) {
+            dataLength = 1;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Populate stringValue with the mime type corresponding to the value in unsigned32bit
+     *
+     * Sets unsigned32bit to -1 if stringValue is already populated
+     */
+    private void expandWellKnownMimeType() {
+        if (stringValue == null) {
+            int binaryContentType = (int) unsigned32bit;
+            stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType);
+        } else {
+            unsigned32bit = -1;
+        }
+    }
+
     /**
      * Decode the "Content length" type for WSP pdu
      *
@@ -272,7 +565,7 @@
      *
      * @return false when error(not a Content length) occur
      *         return value can be retrieved by getValue32() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeContentLength(int startIndex) {
         return decodeIntegerValue(startIndex);
@@ -285,7 +578,7 @@
      *
      * @return false when error(not a Content location) occur
      *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeContentLocation(int startIndex) {
         return decodeTextString(startIndex);
@@ -298,7 +591,8 @@
      *
      * @return false when error(not a X-Wap-Application-Id) occur
      *         return value can be retrieved first by getValueString() and second by getValue32()
-     *         method length of data in pdu can be retrieved by getValue32() method
+     *         method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeXWapApplicationId(int startIndex) {
         if (decodeIntegerValue(startIndex) == true) {
@@ -315,7 +609,7 @@
      *
      * @return false when error(not a X-Wap-Content-URI) occur
      *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeXWapContentURI(int startIndex) {
         return decodeTextString(startIndex);
@@ -328,7 +622,7 @@
      *
      * @return false when error(not a X-Wap-Initiator-URI) occur
      *         return value can be retrieved by getValueString() method
-     *         length of data in pdu can be retrieved by getValue32() method
+     *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
     public boolean decodeXWapInitiatorURI(int startIndex) {
         return decodeTextString(startIndex);
@@ -354,4 +648,18 @@
     public String getValueString() {
         return stringValue;
     }
+
+    /**
+     * Any parameters encountered as part of a decodeContentType() invocation.
+     *
+     * @return a map of content parameters keyed by their names, or null if
+     *         decodeContentType() has not been called If any unassigned
+     *         well-known parameters are encountered, the key of the map will be
+     *         'unassigned/0x...', where '...' is the hex value of the
+     *         unassigned parameter.  If a parameter has No-Value the value will be null.
+     *
+     */
+    public HashMap<String, String> getContentParameters() {
+        return contentParameters;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
similarity index 86%
rename from telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
rename to telephony/java/com/android/internal/telephony/cat/AppInterface.java
index 58f1f97..2eb6ccb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
@@ -14,29 +14,29 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 /**
- * Interface for communication between STK App and STK Telephony
+ * Interface for communication between STK App and CAT Telephony
  *
  * {@hide}
  */
 public interface AppInterface {
 
     /*
-     * Intent's actions which are broadcasted by the Telephony once a new STK
+     * Intent's actions which are broadcasted by the Telephony once a new CAT
      * proactive command, session end arrive.
      */
-    public static final String STK_CMD_ACTION =
+    public static final String CAT_CMD_ACTION =
                                     "android.intent.action.stk.command";
-    public static final String STK_SESSION_END_ACTION =
+    public static final String CAT_SESSION_END_ACTION =
                                     "android.intent.action.stk.session_end";
 
     /*
      * Callback function from app to telephony to pass a result code and user's
-     * input back to the SIM.
+     * input back to the ICC.
      */
-    void onCmdResponse(StkResponseMessage resMsg);
+    void onCmdResponse(CatResponseMessage resMsg);
 
     /*
      * Enumeration for representing "Type of Command" of proactive commands.
@@ -58,7 +58,8 @@
         SET_UP_EVENT_LIST(0x05),
         SET_UP_IDLE_MODE_TEXT(0x28),
         SET_UP_MENU(0x25),
-        SET_UP_CALL(0x10);
+        SET_UP_CALL(0x10),
+        PROVIDE_LOCAL_INFORMATION(0x26);
 
         private int mValue;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
rename to telephony/java/com/android/internal/telephony/cat/BerTlv.java
index 19d3279..774bfa3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import java.util.List;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
similarity index 89%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
rename to telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 5425a43..5155bb2 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 
 /**
- * Class used to pass STK messages from telephony to application. Application
+ * Class used to pass CAT messages from telephony to application. Application
  * should call getXXX() to get commands's specific values.
  *
  */
-public class StkCmdMessage implements Parcelable {
+public class CatCmdMessage implements Parcelable {
     // members
     CommandDetails mCmdDet;
     private TextMessage mTextMsg;
@@ -50,7 +50,7 @@
         public TextMessage callMsg;
     }
 
-    StkCmdMessage(CommandParams cmdParams) {
+    CatCmdMessage(CommandParams cmdParams) {
         mCmdDet = cmdParams.cmdDet;
         switch(getCmdType()) {
         case SET_UP_MENU:
@@ -88,7 +88,7 @@
         }
     }
 
-    public StkCmdMessage(Parcel in) {
+    public CatCmdMessage(Parcel in) {
         mCmdDet = in.readParcelable(null);
         mTextMsg = in.readParcelable(null);
         mMenu = in.readParcelable(null);
@@ -130,13 +130,13 @@
         }
     }
 
-    public static final Parcelable.Creator<StkCmdMessage> CREATOR = new Parcelable.Creator<StkCmdMessage>() {
-        public StkCmdMessage createFromParcel(Parcel in) {
-            return new StkCmdMessage(in);
+    public static final Parcelable.Creator<CatCmdMessage> CREATOR = new Parcelable.Creator<CatCmdMessage>() {
+        public CatCmdMessage createFromParcel(Parcel in) {
+            return new CatCmdMessage(in);
         }
 
-        public StkCmdMessage[] newArray(int size) {
-            return new StkCmdMessage[size];
+        public CatCmdMessage[] newArray(int size) {
+            return new CatCmdMessage[size];
         }
     };
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java
similarity index 80%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkException.java
rename to telephony/java/com/android/internal/telephony/cat/CatException.java
index 86de366..1bf1369 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatException.java
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.util.AndroidException;
 
 
 /**
- * Base class for all the exceptions in STK service.
+ * Base class for all the exceptions in CAT service.
  *
  * {@hide}
  */
-class StkException extends AndroidException {
-    public StkException() {
+class CatException extends AndroidException {
+    public CatException() {
         super();
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java
similarity index 84%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
rename to telephony/java/com/android/internal/telephony/cat/CatLog.java
index bd6bc8f..e19ff43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatLog.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.util.Log;
 
-public abstract class StkLog {
+public abstract class CatLog {
     static final boolean DEBUG = true;
 
     public static void d(Object caller, String msg) {
@@ -27,7 +27,7 @@
         }
 
         String className = caller.getClass().getName();
-        Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": "
+        Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
                 + msg);
     }
 
@@ -36,6 +36,6 @@
             return;
         }
 
-        Log.d("STK", caller + ": " + msg);
+        Log.d("CAT", caller + ": " + msg);
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
similarity index 91%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java
rename to telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
index 04a52e6..cfcac36 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
-public class StkResponseMessage {
+public class CatResponseMessage {
         CommandDetails cmdDet = null;
         ResultCode resCode  = ResultCode.OK;
         int usersMenuSelection = 0;
@@ -24,7 +24,7 @@
         boolean usersYesNoSelection = false;
         boolean usersConfirm = false;
 
-        public StkResponseMessage(StkCmdMessage cmdMsg) {
+        public CatResponseMessage(CatCmdMessage cmdMsg) {
             this.cmdDet = cmdMsg.mCmdDet;
         }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
similarity index 68%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
rename to telephony/java/com/android/internal/telephony/cat/CatService.java
index 29ed95c..1e23e34 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.content.Context;
 import android.content.Intent;
@@ -22,12 +22,13 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
+import android.os.SystemProperties;
 
 import com.android.internal.telephony.IccUtils;
 import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.gsm.SimCard;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccRecords;
 
 import android.util.Config;
 
@@ -111,17 +112,17 @@
  *
  * {@hide}
  */
-public class StkService extends Handler implements AppInterface {
+public class CatService extends Handler implements AppInterface {
 
     // Class members
-    private static SIMRecords mSimRecords;
+    private static IccRecords mIccRecords;
 
     // Service members.
-    private static StkService sInstance;
+    private static CatService sInstance;
     private CommandsInterface mCmdIf;
     private Context mContext;
-    private StkCmdMessage mCurrntCmd = null;
-    private StkCmdMessage mMenuCmd = null;
+    private CatCmdMessage mCurrntCmd = null;
+    private CatCmdMessage mMenuCmd = null;
 
     private RilMessageDecoder mMsgDecoder = null;
 
@@ -136,7 +137,7 @@
     static final int MSG_ID_RIL_MSG_DECODED          = 10;
 
     // Events to signal SIM presence or absent in the device.
-    private static final int MSG_ID_SIM_LOADED       = 20;
+    private static final int MSG_ID_ICC_RECORDS_LOADED       = 20;
 
     private static final int DEV_ID_KEYPAD      = 0x01;
     private static final int DEV_ID_DISPLAY     = 0x02;
@@ -146,10 +147,10 @@
     private static final int DEV_ID_NETWORK     = 0x83;
 
     /* Intentionally private for singleton */
-    private StkService(CommandsInterface ci, SIMRecords sr, Context context,
-            SIMFileHandler fh, SimCard sc) {
-        if (ci == null || sr == null || context == null || fh == null
-                || sc == null) {
+    private CatService(CommandsInterface ci, IccRecords ir, Context context,
+            IccFileHandler fh, IccCard ic) {
+        if (ci == null || ir == null || context == null || fh == null
+                || ic == null) {
             throw new NullPointerException(
                     "Service: Input parameters must not be null");
         }
@@ -160,33 +161,33 @@
         mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
 
         // Register ril events handling.
-        mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null);
-        mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
-        mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null);
-        mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null);
+        mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
+        mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
+        mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
+        mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
         //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
 
-        mSimRecords = sr;
+        mIccRecords = ir;
 
         // Register for SIM ready event.
-        mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null);
+        mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
 
         mCmdIf.reportStkServiceIsRunning(null);
-        StkLog.d(this, "StkService: is running");
+        CatLog.d(this, "Is running");
     }
 
     public void dispose() {
-        mSimRecords.unregisterForRecordsLoaded(this);
-        mCmdIf.unSetOnStkSessionEnd(this);
-        mCmdIf.unSetOnStkProactiveCmd(this);
-        mCmdIf.unSetOnStkEvent(this);
-        mCmdIf.unSetOnStkCallSetUp(this);
+        mIccRecords.unregisterForRecordsLoaded(this);
+        mCmdIf.unSetOnCatSessionEnd(this);
+        mCmdIf.unSetOnCatProactiveCmd(this);
+        mCmdIf.unSetOnCatEvent(this);
+        mCmdIf.unSetOnCatCallSetUp(this);
 
         this.removeCallbacksAndMessages(null);
     }
 
     protected void finalize() {
-        StkLog.d(this, "Service finalized");
+        CatLog.d(this, "Service finalized");
     }
 
     private void handleRilMsg(RilMessage rilMsg) {
@@ -241,55 +242,53 @@
      *
      */
     private void handleProactiveCommand(CommandParams cmdParams) {
-        StkLog.d(this, cmdParams.getCommandType().name());
+        CatLog.d(this, cmdParams.getCommandType().name());
 
-        StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams);
+        CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
         switch (cmdParams.getCommandType()) {
-        case SET_UP_MENU:
-            if (removeMenu(cmdMsg.getMenu())) {
-                mMenuCmd = null;
-            } else {
-                mMenuCmd = cmdMsg;
-            }
-            sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0,
-                    null);
-            break;
-        case DISPLAY_TEXT:
-            // when application is not required to respond, send an immediate
-            // response.
-            if (!cmdMsg.geTextMessage().responseNeeded) {
-                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
-                        0, null);
-            }
-            break;
-        case REFRESH:
-            // ME side only handles refresh commands which meant to remove IDLE
-            // MODE TEXT.
-            cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT
-                    .value();
-            break;
-        case SET_UP_IDLE_MODE_TEXT:
-            sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
-                    0, null);
-            break;
-        case LAUNCH_BROWSER:
-        case SELECT_ITEM:
-        case GET_INPUT:
-        case GET_INKEY:
-        case SEND_DTMF:
-        case SEND_SMS:
-        case SEND_SS:
-        case SEND_USSD:
-        case PLAY_TONE:
-        case SET_UP_CALL:
-            // nothing to do on telephony!
-            break;
-        default:
-            StkLog.d(this, "Unsupported command");
-            return;
+            case SET_UP_MENU:
+                if (removeMenu(cmdMsg.getMenu())) {
+                    mMenuCmd = null;
+                } else {
+                    mMenuCmd = cmdMsg;
+                }
+                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+                break;
+            case DISPLAY_TEXT:
+                // when application is not required to respond, send an immediate response.
+                if (!cmdMsg.geTextMessage().responseNeeded) {
+                    sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+                }
+                break;
+            case REFRESH:
+                // ME side only handles refresh commands which meant to remove IDLE
+                // MODE TEXT.
+                cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
+                break;
+            case SET_UP_IDLE_MODE_TEXT:
+                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+                break;
+            case PROVIDE_LOCAL_INFORMATION:
+                sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+                return;
+            case LAUNCH_BROWSER:
+            case SELECT_ITEM:
+            case GET_INPUT:
+            case GET_INKEY:
+            case SEND_DTMF:
+            case SEND_SMS:
+            case SEND_SS:
+            case SEND_USSD:
+            case PLAY_TONE:
+            case SET_UP_CALL:
+                // nothing to do on telephony!
+                break;
+            default:
+                CatLog.d(this, "Unsupported command");
+                return;
         }
         mCurrntCmd = cmdMsg;
-        Intent intent = new Intent(AppInterface.STK_CMD_ACTION);
+        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
         intent.putExtra("STK CMD", cmdMsg);
         mContext.sendBroadcast(intent);
     }
@@ -299,10 +298,10 @@
      *
      */
     private void handleSessionEnd() {
-        StkLog.d(this, "SESSION END");
+        CatLog.d(this, "SESSION END");
 
         mCurrntCmd = mMenuCmd;
-        Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION);
+        Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
         mContext.sendBroadcast(intent);
     }
 
@@ -315,6 +314,11 @@
         }
         ByteArrayOutputStream buf = new ByteArrayOutputStream();
 
+        Input cmdInput = null;
+        if (mCurrntCmd != null) {
+            cmdInput = mCurrntCmd.geInput();
+        }
+
         // command details
         int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
         if (cmdDet.compRequired) {
@@ -327,7 +331,13 @@
         buf.write(cmdDet.commandQualifier);
 
         // device identities
-        tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
+        // According to TS102.223/TS31.111 section 6.8 Structure of
+        // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
+        // the ME should set the CR(comprehension required) flag to
+        // comprehension not required.(CR=0)"
+        // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
+        // the CR flag is not set.
+        tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
         buf.write(tag);
         buf.write(0x02); // length
         buf.write(DEV_ID_TERMINAL); // source device id
@@ -348,17 +358,65 @@
         // Fill optional data for each corresponding command
         if (resp != null) {
             resp.format(buf);
+        } else {
+            encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
         }
 
         byte[] rawData = buf.toByteArray();
         String hexString = IccUtils.bytesToHexString(rawData);
         if (Config.LOGD) {
-            StkLog.d(this, "TERMINAL RESPONSE: " + hexString);
+            CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
         }
 
         mCmdIf.sendTerminalResponse(hexString, null);
     }
 
+    private void encodeOptionalTags(CommandDetails cmdDet,
+            ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
+        switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
+            case GET_INKEY:
+                // ETSI TS 102 384,27.22.4.2.8.4.2.
+                // If it is a response for GET_INKEY command and the response timeout
+                // occured, then add DURATION TLV for variable timeout case.
+                if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
+                    (cmdInput != null) && (cmdInput.duration != null)) {
+                    getInKeyResponse(buf, cmdInput);
+                }
+                break;
+            case PROVIDE_LOCAL_INFORMATION:
+                if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
+                    (resultCode.value() == ResultCode.OK.value())) {
+                    getPliResponse(buf);
+                }
+                break;
+            default:
+                CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
+                break;
+        }
+    }
+
+    private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
+        int tag = ComprehensionTlvTag.DURATION.value();
+
+        buf.write(tag);
+        buf.write(0x02); // length
+        buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
+        buf.write(cmdInput.duration.timeInterval); // Time Duration
+    }
+
+    private void getPliResponse(ByteArrayOutputStream buf) {
+
+        // Locale Language Setting
+        String lang = SystemProperties.get("persist.sys.language");
+
+        if (lang != null) {
+            // tag
+            int tag = ComprehensionTlvTag.LANGUAGE.value();
+            buf.write(tag);
+            ResponseData.writeLength(buf, lang.length());
+            buf.write(lang.getBytes(), 0, lang.length());
+        }
+    }
 
     private void sendMenuSelection(int menuId, boolean helpRequired) {
 
@@ -446,35 +504,35 @@
     }
 
     /**
-     * Used for instantiating/updating the Service from the GsmPhone constructor.
+     * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor.
      *
      * @param ci CommandsInterface object
-     * @param sr SIMRecords object
+     * @param ir IccRecords object
      * @param context phone app context
-     * @param fh SIM file handler
-     * @param sc GSM SIM card
+     * @param fh Icc file handler
+     * @param ic Icc card
      * @return The only Service object in the system
      */
-    public static StkService getInstance(CommandsInterface ci, SIMRecords sr,
-            Context context, SIMFileHandler fh, SimCard sc) {
+    public static CatService getInstance(CommandsInterface ci, IccRecords ir,
+            Context context, IccFileHandler fh, IccCard ic) {
         if (sInstance == null) {
-            if (ci == null || sr == null || context == null || fh == null
-                    || sc == null) {
+            if (ci == null || ir == null || context == null || fh == null
+                    || ic == null) {
                 return null;
             }
-            HandlerThread thread = new HandlerThread("Stk Telephony service");
+            HandlerThread thread = new HandlerThread("Cat Telephony service");
             thread.start();
-            sInstance = new StkService(ci, sr, context, fh, sc);
-            StkLog.d(sInstance, "NEW sInstance");
-        } else if ((sr != null) && (mSimRecords != sr)) {
-            StkLog.d(sInstance, "Reinitialize the Service with SIMRecords");
-            mSimRecords = sr;
+            sInstance = new CatService(ci, ir, context, fh, ic);
+            CatLog.d(sInstance, "NEW sInstance");
+        } else if ((ir != null) && (mIccRecords != ir)) {
+            CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
+            mIccRecords = ir;
 
             // re-Register for SIM ready event.
-            mSimRecords.registerForRecordsLoaded(sInstance, MSG_ID_SIM_LOADED, null);
-            StkLog.d(sInstance, "sr changed reinitialize and return current sInstance");
+            mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
+            CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
         } else {
-            StkLog.d(sInstance, "Return current sInstance");
+            CatLog.d(sInstance, "Return current sInstance");
         }
         return sInstance;
     }
@@ -496,7 +554,7 @@
         case MSG_ID_PROACTIVE_COMMAND:
         case MSG_ID_EVENT_NOTIFY:
         case MSG_ID_REFRESH:
-            StkLog.d(this, "ril message arrived");
+            CatLog.d(this, "ril message arrived");
             String data = null;
             if (msg.obj != null) {
                 AsyncResult ar = (AsyncResult) msg.obj;
@@ -513,20 +571,20 @@
         case MSG_ID_CALL_SETUP:
             mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
             break;
-        case MSG_ID_SIM_LOADED:
+        case MSG_ID_ICC_RECORDS_LOADED:
             break;
         case MSG_ID_RIL_MSG_DECODED:
             handleRilMsg((RilMessage) msg.obj);
             break;
         case MSG_ID_RESPONSE:
-            handleCmdResponse((StkResponseMessage) msg.obj);
+            handleCmdResponse((CatResponseMessage) msg.obj);
             break;
         default:
-            throw new AssertionError("Unrecognized STK command: " + msg.what);
+            throw new AssertionError("Unrecognized CAT command: " + msg.what);
         }
     }
 
-    public synchronized void onCmdResponse(StkResponseMessage resMsg) {
+    public synchronized void onCmdResponse(CatResponseMessage resMsg) {
         if (resMsg == null) {
             return;
         }
@@ -535,7 +593,7 @@
         msg.sendToTarget();
     }
 
-    private boolean validateResponse(StkResponseMessage resMsg) {
+    private boolean validateResponse(CatResponseMessage resMsg) {
         if (mCurrntCmd != null) {
             return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet));
         }
@@ -548,13 +606,13 @@
                 return true;
             }
         } catch (NullPointerException e) {
-            StkLog.d(this, "Unable to get Menu's items size");
+            CatLog.d(this, "Unable to get Menu's items size");
             return true;
         }
         return false;
     }
 
-    private void handleCmdResponse(StkResponseMessage resMsg) {
+    private void handleCmdResponse(CatResponseMessage resMsg) {
         // Make sure the response details match the last valid command. An invalid
         // response is a one that doesn't have a corresponding proactive command
         // and sending it can "confuse" the baseband/ril.
@@ -563,7 +621,7 @@
         // by the framework inside the history stack. That activity will be
         // available for relaunch using the latest application dialog
         // (long press on the home button). Relaunching that activity can send
-        // the same command's result again to the StkService and can cause it to
+        // the same command's result again to the CatService and can cause it to
         // get out of sync with the SIM.
         if (!validateResponse(resMsg)) {
             return;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
rename to telephony/java/com/android/internal/telephony/cat/CommandDetails.java
index e81ff98..e3f0798 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.os.Parcel;
 import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
rename to telephony/java/com/android/internal/telephony/cat/CommandParams.java
index 3da652f..22a5c8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
similarity index 92%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
rename to telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index ce4c459..12204a0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Message;
 
 import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
 
 import java.util.Iterator;
 import java.util.List;
@@ -52,8 +52,11 @@
     static final int REFRESH_NAA_INIT                       = 0x03;
     static final int REFRESH_UICC_RESET                     = 0x04;
 
+    // Command Qualifier values for PLI command
+    static final int LANGUAGE_SETTING                       = 0x04;
+
     static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
-            SIMFileHandler fh) {
+            IccFileHandler fh) {
         if (sInstance != null) {
             return sInstance;
         }
@@ -63,7 +66,7 @@
         return null;
     }
 
-    private CommandParamsFactory(RilMessageDecoder caller, SIMFileHandler fh) {
+    private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) {
         mCaller = caller;
         mIconLoader = IconLoader.getInstance(this, fh);
     }
@@ -79,7 +82,7 @@
                 try {
                     cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet);
                 } catch (ResultException e) {
-                    StkLog.d(this, "Failed to procees command details");
+                    CatLog.d(this, "Failed to procees command details");
                 }
             }
         }
@@ -112,7 +115,10 @@
         AppInterface.CommandType cmdType = AppInterface.CommandType
                 .fromInt(cmdDet.typeOfCommand);
         if (cmdType == null) {
-            sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+            // This PROACTIVE COMMAND is presently not handled. Hence set
+            // result code as BEYOND_TERMINAL_CAPABILITY in TR.
+            mCmdParams = new CommandParams(cmdDet);
+            sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
             return;
         }
 
@@ -155,10 +161,13 @@
              case PLAY_TONE:
                 cmdPending = processPlayTone(cmdDet, ctlvs);
                 break;
+             case PROVIDE_LOCAL_INFORMATION:
+                cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
+                break;
             default:
                 // unsupported proactive commands
                 mCmdParams = new CommandParams(cmdDet);
-                sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+                sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
                 return;
             }
         } catch (ResultException e) {
@@ -259,7 +268,7 @@
             List<ComprehensionTlv> ctlvs)
             throws ResultException {
 
-        StkLog.d(this, "process DisplayText");
+        CatLog.d(this, "process DisplayText");
 
         TextMessage textMsg = new TextMessage();
         IconId iconId = null;
@@ -319,7 +328,7 @@
     private boolean processSetUpIdleModeText(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process SetUpIdleModeText");
+        CatLog.d(this, "process SetUpIdleModeText");
 
         TextMessage textMsg = new TextMessage();
         IconId iconId = null;
@@ -362,7 +371,7 @@
     private boolean processGetInkey(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process GetInkey");
+        CatLog.d(this, "process GetInkey");
 
         Input input = new Input();
         IconId iconId = null;
@@ -380,6 +389,12 @@
             iconId = ValueParser.retrieveIconId(ctlv);
         }
 
+        // parse duration
+        ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
+        if (ctlv != null) {
+            input.duration = ValueParser.retrieveDuration(ctlv);
+        }
+
         input.minLen = 1;
         input.maxLen = 1;
 
@@ -412,7 +427,7 @@
     private boolean processGetInput(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process GetInput");
+        CatLog.d(this, "process GetInput");
 
         Input input = new Input();
         IconId iconId = null;
@@ -476,7 +491,7 @@
     private boolean processRefresh(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) {
 
-        StkLog.d(this, "process Refresh");
+        CatLog.d(this, "process Refresh");
 
         // REFRESH proactive command is rerouted by the baseband and handled by
         // the telephony layer. IDLE TEXT should be removed for a REFRESH command
@@ -505,7 +520,7 @@
     private boolean processSelectItem(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process SelectItem");
+        CatLog.d(this, "process SelectItem");
 
         Menu menu = new Menu();
         IconId titleIconId = null;
@@ -534,7 +549,7 @@
 
         ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs);
         if (ctlv != null) {
-            // STK items are listed 1...n while list start at 0, need to
+            // CAT items are listed 1...n while list start at 0, need to
             // subtract one.
             menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1;
         }
@@ -602,7 +617,7 @@
     private boolean processEventNotify(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process EventNotify");
+        CatLog.d(this, "process EventNotify");
 
         TextMessage textMsg = new TextMessage();
         IconId iconId = null;
@@ -645,7 +660,7 @@
     private boolean processSetUpEventList(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) {
 
-        StkLog.d(this, "process SetUpEventList");
+        CatLog.d(this, "process SetUpEventList");
         //
         // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST,
         // ctlvs);
@@ -670,10 +685,10 @@
      *         asynchronous processing is required.
      * @throws ResultException
      */
-     private boolean processLaunchBrowser(CommandDetails cmdDet,
+    private boolean processLaunchBrowser(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process LaunchBrowser");
+        CatLog.d(this, "process LaunchBrowser");
 
         TextMessage confirmMsg = new TextMessage();
         IconId iconId = null;
@@ -744,10 +759,10 @@
      *         asynchronous processing is required.t
      * @throws ResultException
      */
-     private boolean processPlayTone(CommandDetails cmdDet,
+    private boolean processPlayTone(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
 
-        StkLog.d(this, "process PlayTone");
+        CatLog.d(this, "process PlayTone");
 
         Tone tone = null;
         TextMessage textMsg = new TextMessage();
@@ -810,9 +825,9 @@
      * @return true if the command is processing is pending and additional
      *         asynchronous processing is required.
      */
-     private boolean processSetupCall(CommandDetails cmdDet,
+    private boolean processSetupCall(CommandDetails cmdDet,
             List<ComprehensionTlv> ctlvs) throws ResultException {
-        StkLog.d(this, "process SetupCall");
+        CatLog.d(this, "process SetupCall");
 
         Iterator<ComprehensionTlv> iter = ctlvs.iterator();
         ComprehensionTlv ctlv = null;
@@ -863,4 +878,20 @@
         }
         return false;
     }
+
+    private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
+            throws ResultException {
+        CatLog.d(this, "process ProvideLocalInfo");
+        switch (cmdDet.commandQualifier) {
+            case LANGUAGE_SETTING:
+                CatLog.d(this, "PLI [LANGUAGE_SETTING]");
+                mCmdParams = new CommandParams(cmdDet);
+                break;
+            default:
+                CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
+                mCmdParams = new CommandParams(cmdDet);
+                throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
rename to telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index ffde6a3..99f662d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java
similarity index 94%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Duration.java
rename to telephony/java/com/android/internal/telephony/cat/Duration.java
index 9d8cc97..e8cd404 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java
+++ b/telephony/java/com/android/internal/telephony/cat/Duration.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 
 
 /**
- * Class for representing "Duration" object for STK.
+ * Class for representing "Duration" object for CAT.
  *
  * {@hide}
  */
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java
rename to telephony/java/com/android/internal/telephony/cat/FontSize.java
index bd4f49f..02c7ea0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java
+++ b/telephony/java/com/android/internal/telephony/cat/FontSize.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
rename to telephony/java/com/android/internal/telephony/cat/IconLoader.java
index fc02d2a..2fa1811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
+++ b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
 
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -40,7 +40,7 @@
     private ImageDescriptor mId = null;
     private Bitmap mCurrentIcon = null;
     private int mRecordNumber;
-    private SIMFileHandler mSimFH = null;
+    private IccFileHandler mSimFH = null;
     private Message mEndMsg = null;
     private byte[] mIconData = null;
     // multi icons state members
@@ -68,19 +68,19 @@
     private static final int CLUT_ENTRY_SIZE = 3;
 
 
-    private IconLoader(Looper looper , SIMFileHandler fh) {
+    private IconLoader(Looper looper , IccFileHandler fh) {
         super(looper);
         mSimFH = fh;
 
         mIconsCache = new HashMap<Integer, Bitmap>(50);
     }
 
-    static IconLoader getInstance(Handler caller, SIMFileHandler fh) {
+    static IconLoader getInstance(Handler caller, IccFileHandler fh) {
         if (sLoader != null) {
             return sLoader;
         }
         if (fh != null) {
-            HandlerThread thread = new HandlerThread("Stk Icon Loader");
+            HandlerThread thread = new HandlerThread("Cat Icon Loader");
             thread.start();
             return new IconLoader(thread.getLooper(), fh);
         }
@@ -163,7 +163,7 @@
                 break;
             }
         } catch (Exception e) {
-            StkLog.d(this, "Icon load failed");
+            CatLog.d(this, "Icon load failed");
             // post null icon back to the caller.
             postIcon();
         }
@@ -254,7 +254,7 @@
         }
 
         if (pixelIndex != numOfPixels) {
-            StkLog.d("IconLoader", "parseToBnW; size error");
+            CatLog.d("IconLoader", "parseToBnW; size error");
         }
         return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
rename to telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
index 880b9e5..711d977 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
+++ b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 /**
  * {@hide}
@@ -69,7 +69,7 @@
 
             d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff));
         } catch (IndexOutOfBoundsException e) {
-            StkLog.d("ImageDescripter", "parse; failed parsing image descriptor");
+            CatLog.d("ImageDescripter", "parse; failed parsing image descriptor");
             d = null;
         }
         return d;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java
similarity index 91%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Input.java
rename to telephony/java/com/android/internal/telephony/cat/Input.java
index 19f724b..13a5ad4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
+++ b/telephony/java/com/android/internal/telephony/cat/Input.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 /**
- * Container class for STK GET INPUT, GET IN KEY commands parameters.
+ * Container class for CAT GET INPUT, GET IN KEY commands parameters.
  *
  */
 public class Input implements Parcelable {
@@ -36,6 +36,7 @@
     public boolean echo;
     public boolean yesNo;
     public boolean helpAvailable;
+    public Duration duration;
 
     Input() {
         text = "";
@@ -49,6 +50,7 @@
         echo = false;
         yesNo = false;
         helpAvailable = false;
+        duration = null;
     }
 
     private Input(Parcel in) {
@@ -63,6 +65,7 @@
         echo = in.readInt() == 1 ? true : false;
         yesNo = in.readInt() == 1 ? true : false;
         helpAvailable = in.readInt() == 1 ? true : false;
+        duration = in.readParcelable(null);
     }
 
     public int describeContents() {
@@ -81,6 +84,7 @@
         dest.writeInt(echo ? 1 : 0);
         dest.writeInt(yesNo ? 1 : 0);
         dest.writeInt(helpAvailable ? 1 : 0);
+        dest.writeParcelable(duration, 0);
     }
 
     public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Item.java
rename to telephony/java/com/android/internal/telephony/cat/Item.java
index b2f338c..d4702bb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java
+++ b/telephony/java/com/android/internal/telephony/cat/Item.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java
rename to telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
index 302273c..af043d1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java
+++ b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
rename to telephony/java/com/android/internal/telephony/cat/Menu.java
index 331f69d..7bbae01 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
+++ b/telephony/java/com/android/internal/telephony/cat/Menu.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 import android.os.Parcel;
@@ -24,7 +24,7 @@
 import java.util.List;
 
 /**
- * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
+ * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters.
  *
  */
 public class Menu implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
similarity index 94%
rename from telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java
rename to telephony/java/com/android/internal/telephony/cat/PresentationType.java
index 71bdcdc..7c8cd8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java
+++ b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
similarity index 90%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
rename to telephony/java/com/android/internal/telephony/cat/ResponseData.java
index afd1bba..677d66b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
@@ -14,7 +14,7 @@
  * the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import com.android.internal.telephony.EncodeException;
 import com.android.internal.telephony.GsmAlphabet;
@@ -28,6 +28,16 @@
      * the ByteArrayOutputStream object.
      */
     public abstract void format(ByteArrayOutputStream buf);
+
+    public static void writeLength(ByteArrayOutputStream buf, int length) {
+        // As per ETSI 102.220 Sec7.1.2, if the total length is greater
+        // than 0x7F, it should be coded in two bytes and the first byte
+        // should be 0x81.
+        if (length > 0x7F) {
+            buf.write(0x81);
+        }
+        buf.write(length);
+    }
 }
 
 class SelectItemResponseData extends ResponseData {
@@ -120,7 +130,7 @@
         }
 
         // length - one more for data coding scheme.
-        buf.write(data.length + 1);
+        writeLength(buf, data.length + 1);
 
         // data coding scheme
         if (mIsUcs2) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java
rename to telephony/java/com/android/internal/telephony/cat/ResultCode.java
index b96a524..8544175 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java
rename to telephony/java/com/android/internal/telephony/cat/ResultException.java
index 2eb16c9..1c2cb63 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
@@ -22,7 +22,7 @@
  *
  * {@hide}
  */
-public class ResultException extends StkException {
+public class ResultException extends CatException {
     private ResultCode mResult;
     private int mAdditionalInfo;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
similarity index 87%
rename from telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java
rename to telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
index a82177c..a197c9a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java
+++ b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
 import com.android.internal.telephony.IccUtils;
 
 import android.os.Handler;
@@ -26,7 +26,7 @@
 
 /**
  * Class used for queuing raw ril messages, decoding them into CommanParams
- * objects and sending the result back to the STK Service.
+ * objects and sending the result back to the CAT Service.
  */
 class RilMessageDecoder extends HierarchicalStateMachine {
 
@@ -51,7 +51,7 @@
      * @param fh
      * @return RilMesssageDecoder
      */
-    public static synchronized RilMessageDecoder getInstance(Handler caller, SIMFileHandler fh) {
+    public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
         if (sInstance == null) {
             sInstance = new RilMessageDecoder(caller, fh);
             sInstance.start();
@@ -85,12 +85,12 @@
     }
 
     private void sendCmdForExecution(RilMessage rilMsg) {
-        Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED,
+        Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
                 new RilMessage(rilMsg));
         msg.sendToTarget();
     }
 
-    private RilMessageDecoder(Handler caller, SIMFileHandler fh) {
+    private RilMessageDecoder(Handler caller, IccFileHandler fh) {
         super("RilMessageDecoder");
 
         addState(mStateStart);
@@ -108,7 +108,7 @@
                     transitionTo(mStateCmdParamsReady);
                 }
             } else {
-                StkLog.d(this, "StateStart unexpected expecting START=" +
+                CatLog.d(this, "StateStart unexpected expecting START=" +
                          CMD_START + " got " + msg.what);
             }
             return true;
@@ -123,7 +123,7 @@
                 sendCmdForExecution(mCurrentRilMessage);
                 transitionTo(mStateStart);
             } else {
-                StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
+                CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
                          + CMD_PARAMS_READY + " got " + msg.what);
                 deferMessage(msg);
             }
@@ -136,21 +136,21 @@
 
         mCurrentRilMessage = rilMsg;
         switch(rilMsg.mId) {
-        case StkService.MSG_ID_SESSION_END:
-        case StkService.MSG_ID_CALL_SETUP:
+        case CatService.MSG_ID_SESSION_END:
+        case CatService.MSG_ID_CALL_SETUP:
             mCurrentRilMessage.mResCode = ResultCode.OK;
             sendCmdForExecution(mCurrentRilMessage);
             decodingStarted = false;
             break;
-        case StkService.MSG_ID_PROACTIVE_COMMAND:
-        case StkService.MSG_ID_EVENT_NOTIFY:
-        case StkService.MSG_ID_REFRESH:
+        case CatService.MSG_ID_PROACTIVE_COMMAND:
+        case CatService.MSG_ID_EVENT_NOTIFY:
+        case CatService.MSG_ID_REFRESH:
             byte[] rawData = null;
             try {
                 rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
             } catch (Exception e) {
                 // zombie messages are dropped
-                StkLog.d(this, "decodeMessageParams dropping zombie messages");
+                CatLog.d(this, "decodeMessageParams dropping zombie messages");
                 decodingStarted = false;
                 break;
             }
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java
rename to telephony/java/com/android/internal/telephony/cat/TextAlignment.java
index c5dd50e..7fb58a5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java
rename to telephony/java/com/android/internal/telephony/cat/TextAttribute.java
index ace4300..0dea640 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java
rename to telephony/java/com/android/internal/telephony/cat/TextColor.java
index 126fc62..6447e74 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextColor.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 
 /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java
rename to telephony/java/com/android/internal/telephony/cat/TextMessage.java
index 3b6a09a..5ffd076 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.graphics.Bitmap;
 import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Tone.java
rename to telephony/java/com/android/internal/telephony/cat/Tone.java
index b64e777d..27b4489 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java
+++ b/telephony/java/com/android/internal/telephony/cat/Tone.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.os.Parcel;
 import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
rename to telephony/java/com/android/internal/telephony/cat/ToneSettings.java
index 90cc6c1..6375afb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
+++ b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import android.os.Parcel;
 import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
rename to telephony/java/com/android/internal/telephony/cat/ValueParser.java
index 09a860e..34e4811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
+++ b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
@@ -14,11 +14,11 @@
  * the License.
  */
 
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
 
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.gsm.stk.Duration.TimeUnit;
+import com.android.internal.telephony.cat.Duration.TimeUnit;
 
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
@@ -182,7 +182,7 @@
      */
     static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv)
             throws ResultException {
-        StkLog.d("ValueParser", "retrieveItemsIconId:");
+        CatLog.d("ValueParser", "retrieveItemsIconId:");
         ItemsIconId id = new ItemsIconId();
 
         byte[] rawValue = ctlv.getRawValue();
diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html
new file mode 100644
index 0000000..5b6bfc6
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cat/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+Provides classes for ICC Toolkit Service (CAT).
+</BODY>
+</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index c21b6d9..6ab89cd 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -42,6 +42,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.telephony.cat.CatService;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandException;
@@ -109,7 +110,7 @@
     PhoneSubInfo mSubInfo;
     EriManager mEriManager;
     WakeLock mWakeLock;
-
+    CatService mCcatService;
 
     // mNvLoadedRegistrants are informed after the EVENT_NV_READY
     private RegistrantList mNvLoadedRegistrants = new RegistrantList();
@@ -161,6 +162,8 @@
         mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this);
         mSubInfo = new PhoneSubInfo(this);
         mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
+        mCcatService = CatService.getInstance(mCM, mRuimRecords, mContext,
+                mIccFileHandler, mRuimCard);
 
         mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
         mRuimRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
@@ -236,6 +239,7 @@
             mRuimSmsInterfaceManager.dispose();
             mSubInfo.dispose();
             mEriManager.dispose();
+            mCcatService.dispose();
         }
     }
 
@@ -251,6 +255,7 @@
             this.mCT = null;
             this.mSST = null;
             this.mEriManager = null;
+            this.mCcatService = null;
     }
 
     protected void finalize() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index c7b1e5c..69a7a57 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -49,6 +49,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
 
+import com.android.internal.telephony.cat.CatService;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallStateException;
@@ -68,7 +69,6 @@
 import com.android.internal.telephony.PhoneSubInfo;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.stk.StkService;
 import com.android.internal.telephony.test.SimulatedRadioControl;
 import com.android.internal.telephony.IccVmNotSupportedException;
 
@@ -102,7 +102,7 @@
     GsmSMSDispatcher mSMS;
     SIMRecords mSIMRecords;
     SimCard mSimCard;
-    StkService mStkService;
+    CatService mStkService;
     ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
     SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
     SimSmsInterfaceManager mSimSmsIntManager;
@@ -154,7 +154,7 @@
             mSimSmsIntManager = new SimSmsInterfaceManager(this);
             mSubInfo = new PhoneSubInfo(this);
         }
-        mStkService = StkService.getInstance(mCM, mSIMRecords, mContext,
+        mStkService = CatService.getInstance(mCM, mSIMRecords, mContext,
                 (SIMFileHandler)mIccFileHandler, mSimCard);
 
         mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
@@ -972,7 +972,9 @@
     }
 
     public void getCallWaiting(Message onComplete) {
-        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
+        //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
+        //class parameter in call waiting interrogation  to network
+        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
     }
 
     public void setCallWaiting(boolean enable, Message onComplete) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index aa16fa3..fe7a5cb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -44,6 +44,13 @@
 
     //***** Constants
 
+    // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
+    static final int MAX_LENGTH_SHORT_CODE = 2;
+
+    // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
+    // (known as #-String)
+    static final char END_OF_USSD_COMMAND = '#';
+
     // From TS 22.030 6.5.2
     static final String ACTION_ACTIVATE = "*";
     static final String ACTION_DEACTIVATE = "#";
@@ -446,22 +453,69 @@
     }
 
     /**
-     * Helper function for newFromDialString.  Returns true if dialString appears to be a short code
-     * AND conditions are correct for it to be treated as such.
+     * Helper function for newFromDialString. Returns true if dialString appears
+     * to be a short code AND conditions are correct for it to be treated as
+     * such.
      */
     static private boolean isShortCode(String dialString, GSMPhone phone) {
         // Refer to TS 22.030 Figure 3.5.3.2:
-        // A 1 or 2 digit "short code" is treated as USSD if it is entered while on a call or
-        // does not satisfy the condition (exactly 2 digits && starts with '1').
-        return ((dialString != null && dialString.length() <= 2)
-                && !PhoneNumberUtils.isEmergencyNumber(dialString)
-                && (phone.isInCall()
-                    || !((dialString.length() == 2 && dialString.charAt(0) == '1')
-                         /* While contrary to TS 22.030, there is strong precedence
-                          * for treating "0" and "00" as call setup strings.
-                          */
-                         || dialString.equals("0")
-                         || dialString.equals("00"))));
+        if (dialString == null) {
+            return false;
+        }
+
+        // Illegal dial string characters will give a ZERO length.
+        // At this point we do not want to crash as any application with
+        // call privileges may send a non dial string.
+        // It return false as when the dialString is equal to NULL.
+        if (dialString.length() == 0) {
+            return false;
+        }
+
+        if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+            return false;
+        } else {
+            return isShortCodeUSSD(dialString, phone);
+        }
+    }
+
+    /**
+     * Helper function for isShortCode. Returns true if dialString appears to be
+     * a short code and it is a USSD structure
+     *
+     * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
+     * digit "short code" is treated as USSD if it is entered while on a call or
+     * does not satisfy the condition (exactly 2 digits && starts with '1'), there
+     * are however exceptions to this rule (see below)
+     *
+     * Exception (1) to Call initiation is: If the user of the device is already in a call
+     * and enters a Short String without any #-key at the end and the length of the Short String is
+     * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
+     *
+     * The phone shall initiate a USSD/SS commands.
+     *
+     * Exception (2) to Call initiation is: If the user of the device enters one
+     * Digit followed by the #-key. This rule defines this String as the
+     * #-String which is a USSD/SS command.
+     *
+     * The phone shall initiate a USSD/SS command.
+     */
+    static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
+        if (dialString != null) {
+            if (phone.isInCall()) {
+                // The maximum length of a Short Code (aka Short String) is 2
+                if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+                    return true;
+                }
+            }
+
+            // The maximum length of a Short Code (aka Short String) is 2
+            if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+                if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index d711a80..30f38bd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -93,6 +93,7 @@
     static final int SPN_RULE_SHOW_PLMN = 0x02;
 
     // From TS 51.011 EF[SPDI] section
+    static final int TAG_SPDI = 0xA3;
     static final int TAG_SPDI_PLMN_LIST = 0x80;
 
     // Full Name IEI from TS 24.008
@@ -559,6 +560,13 @@
                 break;
             case EVENT_GET_CPHS_MAILBOX_DONE:
             case EVENT_GET_MBDN_DONE:
+                //Resetting the voice mail number and voice mail tag to null
+                //as these should be updated from the data read from EF_MBDN.
+                //If they are not reset, incase of invalid data/exception these
+                //variables are retaining their previous values and are
+                //causing invalid voice mailbox info display to user.
+                voiceMailNum = null;
+                voiceMailTag = null;
                 isRecordLoadResponse = true;
 
                 ar = (AsyncResult)msg.obj;
@@ -1426,8 +1434,12 @@
 
         byte[] plmnEntries = null;
 
-        // There should only be one TAG_SPDI_PLMN_LIST
         for ( ; tlv.isValidObject() ; tlv.nextObject()) {
+            // Skip SPDI tag, if existant
+            if (tlv.getTag() == TAG_SPDI) {
+              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
+            }
+            // There should only be one TAG_SPDI_PLMN_LIST
             if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
                 plmnEntries = tlv.getData();
                 break;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 50dd402..9a3c476 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -930,6 +930,8 @@
         // TP-Message-Type-Indicator
         // 9.2.3
         case 0:
+        case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
+                //This should be processed in the same way as MTI == 0 (Deliver)
             parseSmsDeliver(p, firstByte);
             break;
         case 2:
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
old mode 100644
new mode 100755
index 41e527c..b642541
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -53,6 +53,7 @@
     private ArrayList<byte[]> mIapFileRecord;
     private ArrayList<byte[]> mEmailFileRecord;
     private Map<Integer, ArrayList<String>> mEmailsForAdnRec;
+    private boolean mRefreshCache = false;
 
     private static final int EVENT_PBR_LOAD_DONE = 1;
     private static final int EVENT_USIM_ADN_LOAD_DONE = 2;
@@ -91,11 +92,19 @@
         mEmailFileRecord = null;
         mPbrFile = null;
         mIsPbrPresent = true;
+        mRefreshCache = false;
     }
 
     public ArrayList<AdnRecord> loadEfFilesFromUsim() {
         synchronized (mLock) {
-            if (!mPhoneBookRecords.isEmpty()) return mPhoneBookRecords;
+            if (!mPhoneBookRecords.isEmpty()) {
+                if (mRefreshCache) {
+                    mRefreshCache = false;
+                    refreshCache();
+                }
+                return mPhoneBookRecords;
+            }
+
             if (!mIsPbrPresent) return null;
 
             // Check if the PBR file is present in the cache, if not read it
@@ -116,6 +125,20 @@
         return mPhoneBookRecords;
     }
 
+    private void refreshCache() {
+        if (mPbrFile == null) return;
+        mPhoneBookRecords.clear();
+
+        int numRecs = mPbrFile.mFileIds.size();
+        for (int i = 0; i < numRecs; i++) {
+            readAdnFileAndWait(i);
+        }
+    }
+
+    public void invalidateCache() {
+        mRefreshCache = true;
+    }
+
     private void readPbrFileAndWait() {
         mPhone.getIccFileHandler().loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE));
         try {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/package.html b/telephony/java/com/android/internal/telephony/gsm/stk/package.html
deleted file mode 100644
index c285b57..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/stk/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides classes for SIM Toolkit Service.
-</BODY>
-</HTML>
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
new file mode 100644
index 0000000..d31b294
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
@@ -0,0 +1,853 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import com.android.internal.telephony.WspTypeDecoder;
+import com.android.internal.util.HexDump;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class Wap230WspContentTypeTest extends TestCase {
+
+    public static final Map<Integer, String> WELL_KNOWN_SHORT_MIME_TYPES
+            = new HashMap<Integer, String>();
+    public static final Map<Integer, String> WELL_KNOWN_LONG_MIME_TYPES
+            = new HashMap<Integer, String>();
+    public static final Map<Integer, String> WELL_KNOWN_PARAMETERS
+            = new HashMap<Integer, String>();
+
+    static {
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x00, "*/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x01, "text/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x02, "text/html");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x03, "text/plain");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x04, "text/x-hdml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x05, "text/x-ttml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x06, "text/x-vCalendar");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x07, "text/x-vCard");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0B, "multipart/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0C, "multipart/mixed");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0D, "multipart/form-data");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0E, "multipart/byterantes");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x0F, "multipart/alternative");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x10, "application/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x11, "application/java-vm");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x13, "application/x-hdmlc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1C, "image/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1D, "image/gif");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1E, "image/jpeg");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x1F, "image/tiff");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x20, "image/png");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x27, "application/xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x28, "text/xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x31, "text/vnd.wap.co");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x37, "application/pkcs7-mime");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3B, "application/xhtml+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3C, "application/wml+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3D, "text/css");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x4F, "audio/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x50, "video/*");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x52, "application/mikey");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
+        WELL_KNOWN_SHORT_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
+
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x020C, "image/x-up-wpng");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0305, "text/calendar");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
+        WELL_KNOWN_LONG_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
+
+        WELL_KNOWN_PARAMETERS.put(0x00, "Q");
+        WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
+        WELL_KNOWN_PARAMETERS.put(0x02, "Level");
+        WELL_KNOWN_PARAMETERS.put(0x03, "Type");
+        WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
+        WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
+        WELL_KNOWN_PARAMETERS.put(0x09, "Type");
+        WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
+        WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
+        WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
+        WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
+        WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
+        WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
+        WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
+        WELL_KNOWN_PARAMETERS.put(0x16, "Size");
+        WELL_KNOWN_PARAMETERS.put(0x17, "Name");
+        WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
+        WELL_KNOWN_PARAMETERS.put(0x19, "Start");
+        WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
+        WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
+        WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
+        WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
+
+    }
+
+    final int WSP_DEFINED_SHORT_MIME_TYPE_COUNT = 85;
+    final int WSP_DEFINED_LONG_MIME_TYPE_COUNT = 85;
+
+    private static final byte WSP_STRING_TERMINATOR = 0x00;
+    private static final byte WSP_SHORT_INTEGER_MASK = (byte) 0x80;
+    private static final byte WSP_LENGTH_QUOTE = 0x1F;
+    private static final byte WSP_QUOTE = 0x22;
+
+    private static final short LONG_MIME_TYPE_OMA_DIRECTORY_XML = 0x0314;
+    private static final short LONG_MIME_TYPE_UNASSIGNED = 0x052C;
+
+    private static final byte SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE = 0x3F;
+    private static final byte SHORT_MIME_TYPE_UNASSIGNED = 0x60;
+
+    private static final String STRING_MIME_TYPE_ROLLOVER_CERTIFICATE
+            = "application/vnd.wap.rollover-certificate";
+
+    private static final byte TYPED_PARAM_Q = 0x00;
+    private static final byte TYPED_PARAM_DOMAIN = 0x1C;
+    private static final byte PARAM_UNASSIGNED = 0x42;
+    private static final byte PARAM_NO_VALUE = 0x00;
+    private static final byte TYPED_PARAM_SEC = 0x11;
+    private static final byte TYPED_PARAM_MAC = 0x12;
+
+    public void testHasExpectedNumberOfShortMimeTypes() {
+        assertEquals(WSP_DEFINED_SHORT_MIME_TYPE_COUNT, WELL_KNOWN_SHORT_MIME_TYPES.size());
+    }
+
+    public void testHasExpectedNumberOfLongMimeTypes() {
+        assertEquals(WSP_DEFINED_LONG_MIME_TYPE_COUNT, WELL_KNOWN_LONG_MIME_TYPES.size());
+    }
+
+    public void testWellKnownShortIntegerMimeTypeValues() {
+
+        for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
+            WspTypeDecoder unit = new WspTypeDecoder(
+                    HexDump.toByteArray((byte) (value | WSP_SHORT_INTEGER_MASK)));
+            assertTrue(unit.decodeContentType(0));
+            String mimeType = unit.getValueString();
+            int wellKnownValue = (int) unit.getValue32();
+            assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
+            assertEquals(value, wellKnownValue);
+            assertEquals(1, unit.getDecodedDataLength());
+        }
+    }
+
+    public void testWellKnownLongIntegerMimeTypeValues() {
+        byte headerLength = 3;
+        byte typeLength = 2;
+        for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
+            byte[] data = new byte[10];
+            data[0] = headerLength;
+            data[1] = typeLength;
+            data[2] = (byte) (value >> 8);
+            data[3] = (byte) (value & 0xFF);
+            WspTypeDecoder unit = new WspTypeDecoder(data);
+            assertTrue(unit.decodeContentType(0));
+            String mimeType = unit.getValueString();
+            int wellKnownValue = (int) unit.getValue32();
+            assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
+            assertEquals(value, wellKnownValue);
+            assertEquals(4, unit.getDecodedDataLength());
+        }
+    }
+
+    public void testDecodeReturnsFalse_WhenOnlyAZeroBytePresent() {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x00);
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertFalse(unit.decodeContentType(0));
+    }
+
+    public void testConstrainedMediaExtensionMedia() throws Exception {
+
+        String testType = "application/wibble";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(testType.getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+        String mimeType = unit.getValueString();
+        assertEquals(testType, mimeType);
+        assertEquals(-1, unit.getValue32());
+        assertEquals(19, unit.getDecodedDataLength());
+    }
+
+    public void testGeneralFormShortLengthExtensionMedia() throws Exception {
+
+        String testType = "12345678901234567890123456789";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(testType.length() + 1);
+        out.write(testType.getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+        assertEquals(testType, mimeType);
+        assertEquals(-1, unit.getValue32());
+        assertEquals(31, unit.getDecodedDataLength());
+    }
+
+    public void testGeneralFormShortLengthWellKnownShortInteger()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x01);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(2, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormShortLengthWellKnownShortIntegerWithUnknownValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x01);
+        out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+        assertNull(mimeType);
+        assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
+        assertEquals(2, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormShortLengthWellKnownLongInteger()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(0x03); // header length
+        out.write(0x02); // type length (2 octets)
+        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
+        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals("application/oma-directory+xml", mimeType);
+        assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
+        assertEquals(4, unit.getDecodedDataLength());
+    }
+
+    public void testGeneralFormShortLengthWellKnownLongIntegerWithUnknownValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(0x03); // Value-length, short-length
+        out.write(0x02); // long-integer length (2 octets)
+        out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
+        out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertNull(mimeType);
+        assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
+        assertEquals(4, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormLengthQuoteWellKnownShortInteger()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(0x01); // Length as UINTVAR
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(3, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormLengthQuoteWellKnownShortIntegerWithUnknownValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(0x01); // Length as UINTVAR
+        out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+        assertNull(mimeType);
+        assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
+        assertEquals(3, unit.getDecodedDataLength());
+    }
+
+    public void testGeneralFormLengthQuoteWellKnownLongInteger()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(0x03); // Length as UINTVAR
+        out.write(0x02); // long-integer length (2 octets)
+        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
+        out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals("application/oma-directory+xml", mimeType);
+        assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
+        assertEquals(5, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormLengthQuoteWellKnownLongIntegerWithUnknownValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(0x03); // Length as UINTVAR
+        out.write(0x02); // long-integer length (2 octets)
+        out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
+        out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertNull(mimeType);
+        assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
+        assertEquals(5, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormLengthQuoteExtensionMedia() throws Exception {
+
+        String testType = "application/wibble";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(testType.length() + 1); // Length as UINTVAR
+
+        out.write(testType.getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(testType, mimeType);
+        assertEquals(-1, unit.getValue32());
+        assertEquals(21, unit.getDecodedDataLength());
+
+    }
+
+    public void testGeneralFormLengthQuoteExtensionMediaWithNiceLongMimeType() throws Exception {
+
+        String testType =
+                "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
+                +"01234567890123456789012345678901234567890123456789012345678901234567890123456789";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        out.write(WSP_LENGTH_QUOTE);
+        out.write(0x81); // Length as UINTVAR (161 decimal, 0xA1), 2 bytes
+        out.write(0x21);
+
+        out.write(testType.getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(testType, mimeType);
+        assertEquals(-1, unit.getValue32());
+        assertEquals(164, unit.getDecodedDataLength());
+
+    }
+
+    public void testConstrainedMediaExtensionMediaWithSpace() throws Exception {
+
+        String testType = " application/wibble";
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(testType.getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(testType, mimeType);
+        assertEquals(-1, unit.getValue32());
+        assertEquals(20, unit.getDecodedDataLength());
+
+    }
+
+    public void testTypedParamWellKnownShortIntegerNoValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x03); // Value-length, short-length
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+        out.write(PARAM_NO_VALUE);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+        assertEquals(4, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals(null, params.get("Domain"));
+
+    }
+
+    public void testTypedParamWellKnownShortIntegerTokenText() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x14); // Value-length, short-length
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+        assertEquals(out.toByteArray().length, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("wdstechnology.com", params.get("Domain"));
+
+    }
+
+    public void testTypedParamWellKnownLongIntegerTokenText() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x15);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(0x01);
+        out.write(TYPED_PARAM_DOMAIN);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+        assertEquals(22, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("wdstechnology.com", params.get("Domain"));
+
+    }
+
+    public void testTypedParamWellKnownShortIntegerQuotedText() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x15);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+        out.write(WSP_QUOTE);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(0x3F, unit.getValue32());
+        assertEquals(22, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("wdstechnology.com", params.get("Domain"));
+
+    }
+
+    public void testTypedParamWellKnownShortIntegerCompactIntegerValue()  {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x3);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
+        out.write(0x01 | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(0x3F, unit.getValue32());
+        assertEquals(4, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("1", params.get("SEC"));
+
+    }
+
+    public void testTypedParamWellKnownShortIntegerMultipleParameters() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x0B);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
+        out.write(0x01 | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_MAC | WSP_SHORT_INTEGER_MASK);
+        out.write(WSP_QUOTE);
+        out.write("imapc".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(12, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("1", params.get("SEC"));
+        assertEquals("imapc", params.get("MAC"));
+    }
+
+    public void testUntypedParamIntegerValueShortInteger() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x0A);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR); // EOS
+        out.write(0x45 | WSP_SHORT_INTEGER_MASK);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(11, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("69", params.get("MYPARAM"));
+    }
+
+    public void testUntypedParamIntegerValueLongInteger() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x0C);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+        out.write(0x02); // Short Length
+        out.write(0x42); // Long Integer byte 1
+        out.write(0x69); // Long Integer byte 2
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(0x3F, unit.getValue32());
+        assertEquals(13, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("17001", params.get("MYPARAM"));
+    }
+
+    public void testUntypedParamTextNoValue() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x0A);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+        out.write(PARAM_NO_VALUE);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(11, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals(null, params.get("MYPARAM"));
+
+    }
+
+    public void testUntypedParamTextTokenText() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x11);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+        out.write("myvalue".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(18, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("myvalue", params.get("MYPARAM"));
+    }
+
+    public void testUntypedParamTextQuotedString() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x11);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+        out.write(WSP_QUOTE);
+        out.write("myvalue".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+        assertEquals(19, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("myvalue", params.get("MYPARAM"));
+
+    }
+
+    public void testDecodesReturnsFalse_ForParamWithMissingValue() throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x09);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write("MYPARAM".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertFalse(unit.decodeContentType(0));
+    }
+
+    public void testTypedParamTextQValue()  {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x04);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(TYPED_PARAM_Q);
+        out.write(0x83); // Q value byte 1
+        out.write(0x31); // Q value byte 2
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(0x3F, unit.getValue32());
+        assertEquals(5, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("433", params.get("Q"));
+
+    }
+
+    public void testTypedParamUnassignedWellKnownShortIntegerTokenText() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x14);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(PARAM_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+        assertEquals(21, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
+
+    }
+
+    public void testTypedParamUnassignedWellKnownLongIntegerTokenText() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x15);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(0x01); // Short-length of well-known parameter token
+        out.write(PARAM_UNASSIGNED);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+        out.write(WSP_STRING_TERMINATOR);
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertTrue(unit.decodeContentType(0));
+
+        String mimeType = unit.getValueString();
+
+        assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+        assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+        assertEquals(22, unit.getDecodedDataLength());
+
+        Map<String, String> params = unit.getContentParameters();
+        assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
+    }
+
+    public void testDecodesReturnsFalse_WhenParamValueNotTerminated() throws Exception {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(0x15);
+        out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+        out.write(0x01);
+        out.write(PARAM_UNASSIGNED);
+        out.write("wdstechnology.com".getBytes("US-ASCII"));
+
+        WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+        assertFalse(unit.decodeContentType(0));
+    }
+}
\ No newline at end of file
diff --git a/tests/CoreTests/android/AndroidManifest.xml b/tests/CoreTests/android/AndroidManifest.xml
index f02673c..8331f0c 100644
--- a/tests/CoreTests/android/AndroidManifest.xml
+++ b/tests/CoreTests/android/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
     <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
     <!-- location test permissions -->
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
diff --git a/tests/CoreTests/android/core/HttpHeaderTest.java b/tests/CoreTests/android/core/HttpHeaderTest.java
new file mode 100644
index 0000000..a5d48578
--- /dev/null
+++ b/tests/CoreTests/android/core/HttpHeaderTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.core;
+
+import android.test.AndroidTestCase;
+import org.apache.http.util.CharArrayBuffer;
+
+import android.net.http.Headers;
+
+public class HttpHeaderTest extends AndroidTestCase {
+
+    static final String LAST_MODIFIED = "Last-Modified: Fri, 18 Jun 2010 09:56:47 GMT";
+    static final String CACHE_CONTROL_MAX_AGE = "Cache-Control:max-age=15";
+    static final String CACHE_CONTROL_PRIVATE = "Cache-Control: private";
+
+    /**
+     * Tests that cache control header supports multiple instances of the header,
+     * according to HTTP specification.
+     *
+     * The HTTP specification states the following about the fields:
+     * Multiple message-header fields with the same field-name MAY be present
+     * in a message if and only if the entire field-value for that header field
+     * is defined as a comma-separated list [i.e., #(values)]. It MUST be
+     * possible to combine the multiple header fields into one "field-name:
+     * field-value" pair, without changing the semantics of the message, by
+     * appending each subsequent field-value to the first, each separated by a
+     * comma. The order in which header fields with the same field-name are
+     * received is therefore significant to the interpretation of the combined
+     * field value, and thus a proxy MUST NOT change the order of these field
+     * values when a message is forwarded.
+     */
+    public void testCacheControl() throws Exception {
+        Headers h = new Headers();
+        CharArrayBuffer buffer = new CharArrayBuffer(64);
+
+        buffer.append(CACHE_CONTROL_MAX_AGE);
+        h.parseHeader(buffer);
+
+        buffer.clear();
+        buffer.append(LAST_MODIFIED);
+        h.parseHeader(buffer);
+        assertEquals("max-age=15", h.getCacheControl());
+
+        buffer.clear();
+        buffer.append(CACHE_CONTROL_PRIVATE);
+        h.parseHeader(buffer);
+        assertEquals("max-age=15,private", h.getCacheControl());
+    }
+}
diff --git a/tests/CoreTests/android/core/ProxyTest.java b/tests/CoreTests/android/core/ProxyTest.java
new file mode 100644
index 0000000..12acfe8
--- /dev/null
+++ b/tests/CoreTests/android/core/ProxyTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.core;
+
+import org.apache.http.HttpHost;
+
+import android.content.Context;
+import android.net.Proxy;
+import android.test.AndroidTestCase;
+
+/**
+ * Proxy tests
+ */
+public class ProxyTest extends AndroidTestCase {
+    private Context mContext;
+    private HttpHost mHttpHost;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getContext();
+        mHttpHost = null;
+        String proxyHost = Proxy.getHost(mContext);
+        int proxyPort = Proxy.getPort(mContext);
+        if (proxyHost != null) {
+            mHttpHost = new HttpHost(proxyHost, proxyPort, "http");
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Bad url parameter should not cause any exception.
+     */
+    public void testProxyGetPreferredHttpHost_UrlBad() throws Exception {
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, null));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, ""));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:\\"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad://#"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "://#"));
+    }
+
+    /**
+     * Proxy (if available) should be returned when url parameter is not localhost.
+     */
+    public void testProxyGetPreferredHttpHost_UrlNotlLocalhost() throws Exception {
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://192.168.0.1/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "file:///foo/bar"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com/"));
+        assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "javascript:alert(1)"));
+    }
+
+    /**
+     * No proxy should be returned when url parameter is localhost.
+     */
+    public void testProxyGetPreferredHttpHost_UrlLocalhost() throws Exception {
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/hej.html"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/hej.html"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:80/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:8080/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://127.0.0.1/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://localhost/"));
+        assertNull(Proxy.getPreferredHttpHost(mContext, "https://localhost/"));
+    }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
index e741177..73d7363 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
@@ -31,6 +31,7 @@
 import android.widget.ListView;
 import android.widget.SimpleAdapter;
 import android.os.Bundle;
+import android.os.Environment;
 
 
 public abstract class FileList extends ListActivity
@@ -179,10 +180,9 @@
         getListView().setSelection(mFocusIndex);
     }
 
-    protected void setupPath()
-    {
-    	mPath = "/sdcard/android/layout_tests";
-    	mBaseLength = mPath.length();
+    protected void setupPath() {
+        mPath = Environment.getExternalStorageDirectory() + "/android/layout_tests";
+        mBaseLength = mPath.length();
     }
 
     protected String mPath;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
index 322b0d2..6cfce41 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
@@ -18,6 +18,7 @@
 
 import com.android.dumprendertree.forwarder.ForwardService;
 
+import android.os.Environment;
 import android.util.Log;
 
 import java.io.BufferedOutputStream;
@@ -32,11 +33,17 @@
 public class FsUtils {
 
     private static final String LOGTAG = "FsUtils";
-    static final String HTTP_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/";
-    static final String HTTPS_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/ssl/";
-    static final String HTTP_LOCAL_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/local/";
-    static final String HTTP_MEDIA_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/media/";
-    static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
+    static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
+    static final String HTTP_TESTS_PREFIX =
+        EXTERNAL_DIR + "/android/layout_tests/http/tests/";
+    static final String HTTPS_TESTS_PREFIX =
+        EXTERNAL_DIR + "/android/layout_tests/http/tests/ssl/";
+    static final String HTTP_LOCAL_TESTS_PREFIX =
+        EXTERNAL_DIR + "/android/layout_tests/http/tests/local/";
+    static final String HTTP_MEDIA_TESTS_PREFIX =
+        EXTERNAL_DIR + "/android/layout_tests/http/tests/media/";
+    static final String HTTP_WML_TESTS_PREFIX =
+        EXTERNAL_DIR + "/android/layout_tests/http/tests/wml/";
 
     private FsUtils() {
         //no creation of instances
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 042158a..9ccf549 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -18,12 +18,12 @@
 
 import com.android.dumprendertree.TestShellActivity.DumpDataType;
 import com.android.dumprendertree.forwarder.AdbUtils;
-import com.android.dumprendertree.forwarder.ForwardServer;
 import com.android.dumprendertree.forwarder.ForwardService;
 
 import android.app.Instrumentation;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Environment;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
@@ -92,10 +92,11 @@
 
     public MyTestRecorder(boolean resume) {
         try {
-            File resultsPassedFile = new File("/sdcard/layout_tests_passed.txt");
-            File resultsFailedFile = new File("/sdcard/layout_tests_failed.txt");
-            File resultsIgnoreResultFile = new File("/sdcard/layout_tests_ignored.txt");
-            File noExpectedResultFile = new File("/sdcard/layout_tests_nontext.txt");
+            File externalDir = Environment.getExternalStorageDirectory();
+            File resultsPassedFile = new File(externalDir, "layout_tests_passed.txt");
+            File resultsFailedFile = new File(externalDir, "layout_tests_failed.txt");
+            File resultsIgnoreResultFile = new File(externalDir, "layout_tests_ignored.txt");
+            File noExpectedResultFile = new File(externalDir, "layout_tests_nontext.txt");
 
             mBufferedOutputPassedStream =
                 new BufferedOutputStream(new FileOutputStream(resultsPassedFile, resume));
@@ -128,11 +129,12 @@
     private static final String LOGTAG = "LayoutTests";
     static final int DEFAULT_TIMEOUT_IN_MILLIS = 5000;
 
-    static final String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/";
-    static final String LAYOUT_TESTS_RESULT_DIR = "/sdcard/android/layout_tests_results/";
-    static final String ANDROID_EXPECTED_RESULT_DIR = "/sdcard/android/expected_results/";
-    static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/android/layout_tests_list.txt";
-    static final String TEST_STATUS_FILE = "/sdcard/android/running_test.txt";
+    static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
+    static final String LAYOUT_TESTS_ROOT = EXTERNAL_DIR + "/android/layout_tests/";
+    static final String LAYOUT_TESTS_RESULT_DIR = EXTERNAL_DIR + "/android/layout_tests_results/";
+    static final String ANDROID_EXPECTED_RESULT_DIR = EXTERNAL_DIR + "/android/expected_results/";
+    static final String LAYOUT_TESTS_LIST_FILE = EXTERNAL_DIR + "/android/layout_tests_list.txt";
+    static final String TEST_STATUS_FILE = EXTERNAL_DIR + "/android/running_test.txt";
     static final String LAYOUT_TESTS_RESULTS_REFERENCE_FILES[] = {
           "results/layout_tests_passed.txt",
           "results/layout_tests_failed.txt",
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index 2ef342f..9352f39 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Debug;
+import android.os.Environment;
 import android.os.Process;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
@@ -35,7 +36,8 @@
 public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
 
     private final static String LOGTAG = "LoadTest";
-    private final static String LOAD_TEST_RESULT = "/sdcard/load_test_result.txt";
+    private final static String LOAD_TEST_RESULT =
+        Environment.getExternalStorageDirectory() + "/load_test_result.txt";
     private boolean mFinished;
     static final String LOAD_TEST_RUNNER_FILES[] = {
         "run_page_cycler.py"
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
index 82671eb..9c4b57256 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
@@ -18,6 +18,7 @@
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Environment;
 import android.util.Log;
 
 import java.io.BufferedOutputStream;
@@ -28,7 +29,8 @@
 
     private static final int MENU_START = 0x01;
     private static String LOGTAG = "MenuActivity";
-    static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/android/layout_tests_list.txt";
+    static final String LAYOUT_TESTS_LIST_FILE =
+        Environment.getExternalStorageDirectory() + "/android/layout_tests_list.txt";
 
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index 9bc0962..d146fc7 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.content.Intent;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
 import android.test.ActivityInstrumentationTestCase2;
@@ -37,10 +38,16 @@
 
     private static final String LOGTAG = "ReliabilityTest";
     private static final String PKG_NAME = "com.android.dumprendertree";
-    private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
-    private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
-    private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
-    private static final String TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt";
+    private static final String EXTERNAL_DIR =
+        Environment.getExternalStorageDirectory().toString();
+    private static final String TEST_LIST_FILE = EXTERNAL_DIR +
+        "/android/reliability_tests_list.txt";
+    private static final String TEST_STATUS_FILE = EXTERNAL_DIR +
+        "/android/reliability_running_test.txt";
+    private static final String TEST_TIMEOUT_FILE = EXTERNAL_DIR +
+        "/android/reliability_timeout_test.txt";
+    private static final String TEST_LOAD_TIME_FILE = EXTERNAL_DIR +
+        "/android/reliability_load_time.txt";
     private static final String TEST_DONE = "#DONE";
     static final String RELIABILITY_TEST_RUNNER_FILES[] = {
         "run_reliability_tests.py"
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 81d5b08..7475719 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -30,6 +30,7 @@
 import android.graphics.Bitmap.Config;
 import android.net.http.SslError;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
@@ -862,7 +863,8 @@
     static final String SAVE_IMAGE = "SaveImage";
 
     static final int DRAW_RUNS = 5;
-    static final String DRAW_TIME_LOG = "/sdcard/android/page_draw_time.txt";
+    static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
+        "/android/page_draw_time.txt";
 
     private boolean mGeolocationPermissionSet;
     private boolean mGeolocationPermission;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
index 8b7de6e..25dd04fd 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
@@ -21,6 +21,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 
+import android.os.Environment;
 import android.util.Log;
 
 public class ForwardService {
@@ -33,7 +34,8 @@
 
     private static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
 
-    private static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
+    private static final String FORWARD_HOST_CONF =
+        Environment.getExternalStorageDirectory() + "/drt_forward_host.txt";
 
     private ForwardService() {
         int addr = getForwardHostAddr();
diff --git a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
index 98d0a50..4cfdf6c 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
@@ -28,6 +28,7 @@
 import android.database.Cursor;
 import android.location.LocationManager;
 import android.os.Bundle;
+import android.os.Environment;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -210,12 +211,11 @@
     }
 
     private String getUniqueFileName(String ext) {
-        File dir = new File("/sdcard/locationtracker");
+        File dir = new File(Environment.getExternalStorageDirectory() + "/locationtracker");
         if (!dir.exists()) {
             dir.mkdir();
         }
-        return "/sdcard/locationtracker/tracking-" +
-            DateUtils.getCurrentTimestamp() + "." + ext;
+        return dir + "/tracking-" + DateUtils.getCurrentTimestamp() + "." + ext;
     }
 
     private void launchSettings() {
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 21f3be4..37976ee 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -16,24 +16,19 @@
 
 package com.android.statusbartest;
 
-import android.app.ListActivity;
 import android.app.PendingIntent;
-import android.widget.ArrayAdapter;
-import android.view.View;
-import android.widget.ListView;
 import android.content.Context;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.os.Environment;
 import android.os.Vibrator;
-import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.widget.RemoteViews;
-import android.widget.TextView;
 import android.os.PowerManager;
 
 public class NotificationTestList extends TestActivity
@@ -70,7 +65,8 @@
                 pm.goToSleep(SystemClock.uptimeMillis());
 
                 Notification n = new Notification();
-                n.sound = Uri.parse("file:///sdcard/virtual-void.mp3");
+                n.sound = Uri.parse("file://" + Environment.getExternalStorageDirectory() +
+                        "/virtual-void.mp3");
                 Log.d(TAG, "n.sound=" + n.sound);
 
                 mNM.notify(1, n);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 22dbda3..59f2312 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -321,6 +321,7 @@
     private static String LS = System.getProperty("line.separator");
 
     private static String[] sDnsPropNames;
+    private Runnable mReleaseWakeLockCallback;
 
     /**
      * A structure for supplying information about a supplicant state
@@ -1430,7 +1431,7 @@
         int netId = -1;
         String[] lines = reply.split("\n");
         for (String line : lines) {
-            String[] prop = line.split(" *= *");
+            String[] prop = line.split(" *= *", 2);
             if (prop.length < 2)
                 continue;
             String name = prop[0];
@@ -2415,11 +2416,11 @@
                         setBluetoothCoexistenceMode(
                                 WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
                     }
-
+                    
                     powerMode = getPowerMode();
                     if (powerMode < 0) {
-                        // Handle the case where supplicant driver does not support
-                        // getPowerModeCommand.
+                      // Handle the case where supplicant driver does not support
+                      // getPowerModeCommand.
                         powerMode = DRIVER_POWER_MODE_AUTO;
                     }
                     if (powerMode != DRIVER_POWER_MODE_ACTIVE) {