diff --git a/Android.mk b/Android.mk
index 110117b..632dd09 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,8 +23,6 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v13
-
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-java-files-under, WallpaperPicker/src) \
     $(call all-renderscript-files-under, src) \
diff --git a/WallpaperPicker/AndroidManifest.xml b/WallpaperPicker/AndroidManifest.xml
index 5b6a007..cb1457b 100644
--- a/WallpaperPicker/AndroidManifest.xml
+++ b/WallpaperPicker/AndroidManifest.xml
@@ -4,7 +4,7 @@
         android:versionCode="1"
         android:versionName="1.0"
         >
-  
-    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
+
+    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
     <application/>
 </manifest>
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
new file mode 100644
index 0000000..45118bf
--- /dev/null
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
@@ -0,0 +1,405 @@
+/**
+ * Copyright (C) 2015 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.gallery3d.common;
+
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
+
+    public interface OnBitmapCroppedHandler {
+        public void onBitmapCropped(byte[] imageBytes);
+    }
+
+    private static final int DEFAULT_COMPRESS_QUALITY = 90;
+    private static final String LOGTAG = "BitmapCropTask";
+
+    Uri mInUri = null;
+    Context mContext;
+    String mInFilePath;
+    byte[] mInImageBytes;
+    int mInResId = 0;
+    RectF mCropBounds = null;
+    int mOutWidth, mOutHeight;
+    int mRotation;
+    boolean mSetWallpaper;
+    boolean mSaveCroppedBitmap;
+    Bitmap mCroppedBitmap;
+    Runnable mOnEndRunnable;
+    Resources mResources;
+    BitmapCropTask.OnBitmapCroppedHandler mOnBitmapCroppedHandler;
+    boolean mNoCrop;
+
+    public BitmapCropTask(Context c, String filePath,
+            RectF cropBounds, int rotation, int outWidth, int outHeight,
+            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+        mContext = c;
+        mInFilePath = filePath;
+        init(cropBounds, rotation,
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+    }
+
+    public BitmapCropTask(byte[] imageBytes,
+            RectF cropBounds, int rotation, int outWidth, int outHeight,
+            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+        mInImageBytes = imageBytes;
+        init(cropBounds, rotation,
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+    }
+
+    public BitmapCropTask(Context c, Uri inUri,
+            RectF cropBounds, int rotation, int outWidth, int outHeight,
+            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+        mContext = c;
+        mInUri = inUri;
+        init(cropBounds, rotation,
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+    }
+
+    public BitmapCropTask(Context c, Resources res, int inResId,
+            RectF cropBounds, int rotation, int outWidth, int outHeight,
+            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+        mContext = c;
+        mInResId = inResId;
+        mResources = res;
+        init(cropBounds, rotation,
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+    }
+
+    private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
+            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+        mCropBounds = cropBounds;
+        mRotation = rotation;
+        mOutWidth = outWidth;
+        mOutHeight = outHeight;
+        mSetWallpaper = setWallpaper;
+        mSaveCroppedBitmap = saveCroppedBitmap;
+        mOnEndRunnable = onEndRunnable;
+    }
+
+    public void setOnBitmapCropped(BitmapCropTask.OnBitmapCroppedHandler handler) {
+        mOnBitmapCroppedHandler = handler;
+    }
+
+    public void setNoCrop(boolean value) {
+        mNoCrop = value;
+    }
+
+    public void setOnEndRunnable(Runnable onEndRunnable) {
+        mOnEndRunnable = onEndRunnable;
+    }
+
+    // Helper to setup input stream
+    private InputStream regenerateInputStream() {
+        if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {
+            Log.w(LOGTAG, "cannot read original file, no input URI, resource ID, or " +
+                    "image byte array given");
+        } else {
+            try {
+                if (mInUri != null) {
+                    return new BufferedInputStream(
+                            mContext.getContentResolver().openInputStream(mInUri));
+                } else if (mInFilePath != null) {
+                    return mContext.openFileInput(mInFilePath);
+                } else if (mInImageBytes != null) {
+                    return new BufferedInputStream(new ByteArrayInputStream(mInImageBytes));
+                } else {
+                    return new BufferedInputStream(mResources.openRawResource(mInResId));
+                }
+            } catch (FileNotFoundException e) {
+                Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
+            }
+        }
+        return null;
+    }
+
+    public Point getImageBounds() {
+        InputStream is = regenerateInputStream();
+        if (is != null) {
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inJustDecodeBounds = true;
+            BitmapFactory.decodeStream(is, null, options);
+            Utils.closeSilently(is);
+            if (options.outWidth != 0 && options.outHeight != 0) {
+                return new Point(options.outWidth, options.outHeight);
+            }
+        }
+        return null;
+    }
+
+    public void setCropBounds(RectF cropBounds) {
+        mCropBounds = cropBounds;
+    }
+
+    public Bitmap getCroppedBitmap() {
+        return mCroppedBitmap;
+    }
+    public boolean cropBitmap() {
+        boolean failure = false;
+
+
+        WallpaperManager wallpaperManager = null;
+        if (mSetWallpaper) {
+            wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
+        }
+
+
+        if (mSetWallpaper && mNoCrop) {
+            try {
+                InputStream is = regenerateInputStream();
+                if (is != null) {
+                    wallpaperManager.setStream(is);
+                    Utils.closeSilently(is);
+                }
+            } catch (IOException e) {
+                Log.w(LOGTAG, "cannot write stream to wallpaper", e);
+                failure = true;
+            }
+            return !failure;
+        } else {
+            // Find crop bounds (scaled to original image size)
+            Rect roundedTrueCrop = new Rect();
+            Matrix rotateMatrix = new Matrix();
+            Matrix inverseRotateMatrix = new Matrix();
+
+            Point bounds = getImageBounds();
+            if (mRotation > 0) {
+                rotateMatrix.setRotate(mRotation);
+                inverseRotateMatrix.setRotate(-mRotation);
+
+                mCropBounds.roundOut(roundedTrueCrop);
+                mCropBounds = new RectF(roundedTrueCrop);
+
+                if (bounds == null) {
+                    Log.w(LOGTAG, "cannot get bounds for image");
+                    failure = true;
+                    return false;
+                }
+
+                float[] rotatedBounds = new float[] { bounds.x, bounds.y };
+                rotateMatrix.mapPoints(rotatedBounds);
+                rotatedBounds[0] = Math.abs(rotatedBounds[0]);
+                rotatedBounds[1] = Math.abs(rotatedBounds[1]);
+
+                mCropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2);
+                inverseRotateMatrix.mapRect(mCropBounds);
+                mCropBounds.offset(bounds.x/2, bounds.y/2);
+
+            }
+
+            mCropBounds.roundOut(roundedTrueCrop);
+
+            if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
+                Log.w(LOGTAG, "crop has bad values for full size image");
+                failure = true;
+                return false;
+            }
+
+            // See how much we're reducing the size of the image
+            int scaleDownSampleSize = Math.max(1, Math.min(roundedTrueCrop.width() / mOutWidth,
+                    roundedTrueCrop.height() / mOutHeight));
+            // Attempt to open a region decoder
+            BitmapRegionDecoder decoder = null;
+            InputStream is = null;
+            try {
+                is = regenerateInputStream();
+                if (is == null) {
+                    Log.w(LOGTAG, "cannot get input stream for uri=" + mInUri.toString());
+                    failure = true;
+                    return false;
+                }
+                decoder = BitmapRegionDecoder.newInstance(is, false);
+                Utils.closeSilently(is);
+            } catch (IOException e) {
+                Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
+            } finally {
+               Utils.closeSilently(is);
+               is = null;
+            }
+
+            Bitmap crop = null;
+            if (decoder != null) {
+                // Do region decoding to get crop bitmap
+                BitmapFactory.Options options = new BitmapFactory.Options();
+                if (scaleDownSampleSize > 1) {
+                    options.inSampleSize = scaleDownSampleSize;
+                }
+                crop = decoder.decodeRegion(roundedTrueCrop, options);
+                decoder.recycle();
+            }
+
+            if (crop == null) {
+                // BitmapRegionDecoder has failed, try to crop in-memory
+                is = regenerateInputStream();
+                Bitmap fullSize = null;
+                if (is != null) {
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    if (scaleDownSampleSize > 1) {
+                        options.inSampleSize = scaleDownSampleSize;
+                    }
+                    fullSize = BitmapFactory.decodeStream(is, null, options);
+                    Utils.closeSilently(is);
+                }
+                if (fullSize != null) {
+                    // Find out the true sample size that was used by the decoder
+                    scaleDownSampleSize = bounds.x / fullSize.getWidth();
+                    mCropBounds.left /= scaleDownSampleSize;
+                    mCropBounds.top /= scaleDownSampleSize;
+                    mCropBounds.bottom /= scaleDownSampleSize;
+                    mCropBounds.right /= scaleDownSampleSize;
+                    mCropBounds.roundOut(roundedTrueCrop);
+
+                    // Adjust values to account for issues related to rounding
+                    if (roundedTrueCrop.width() > fullSize.getWidth()) {
+                        // Adjust the width
+                        roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth();
+                    }
+                    if (roundedTrueCrop.right > fullSize.getWidth()) {
+                        // Adjust the left value
+                        int adjustment = roundedTrueCrop.left -
+                                Math.max(0, roundedTrueCrop.right - roundedTrueCrop.width());
+                        roundedTrueCrop.left -= adjustment;
+                        roundedTrueCrop.right -= adjustment;
+                    }
+                    if (roundedTrueCrop.height() > fullSize.getHeight()) {
+                        // Adjust the height
+                        roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight();
+                    }
+                    if (roundedTrueCrop.bottom > fullSize.getHeight()) {
+                        // Adjust the top value
+                        int adjustment = roundedTrueCrop.top -
+                                Math.max(0, roundedTrueCrop.bottom - roundedTrueCrop.height());
+                        roundedTrueCrop.top -= adjustment;
+                        roundedTrueCrop.bottom -= adjustment;
+                    }
+
+                    crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
+                            roundedTrueCrop.top, roundedTrueCrop.width(),
+                            roundedTrueCrop.height());
+                }
+            }
+
+            if (crop == null) {
+                Log.w(LOGTAG, "cannot decode file: " + mInUri.toString());
+                failure = true;
+                return false;
+            }
+            if (mOutWidth > 0 && mOutHeight > 0 || mRotation > 0) {
+                float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() };
+                rotateMatrix.mapPoints(dimsAfter);
+                dimsAfter[0] = Math.abs(dimsAfter[0]);
+                dimsAfter[1] = Math.abs(dimsAfter[1]);
+
+                if (!(mOutWidth > 0 && mOutHeight > 0)) {
+                    mOutWidth = Math.round(dimsAfter[0]);
+                    mOutHeight = Math.round(dimsAfter[1]);
+                }
+
+                RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]);
+                RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
+
+                Matrix m = new Matrix();
+                if (mRotation == 0) {
+                    m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+                } else {
+                    Matrix m1 = new Matrix();
+                    m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f);
+                    Matrix m2 = new Matrix();
+                    m2.setRotate(mRotation);
+                    Matrix m3 = new Matrix();
+                    m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f);
+                    Matrix m4 = new Matrix();
+                    m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+
+                    Matrix c1 = new Matrix();
+                    c1.setConcat(m2, m1);
+                    Matrix c2 = new Matrix();
+                    c2.setConcat(m4, m3);
+                    m.setConcat(c2, c1);
+                }
+
+                Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
+                        (int) returnRect.height(), Bitmap.Config.ARGB_8888);
+                if (tmp != null) {
+                    Canvas c = new Canvas(tmp);
+                    Paint p = new Paint();
+                    p.setFilterBitmap(true);
+                    c.drawBitmap(crop, m, p);
+                    crop = tmp;
+                }
+            }
+
+            if (mSaveCroppedBitmap) {
+                mCroppedBitmap = crop;
+            }
+
+            // Compress to byte array
+            ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
+            if (crop.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
+                // If we need to set to the wallpaper, set it
+                if (mSetWallpaper && wallpaperManager != null) {
+                    try {
+                        byte[] outByteArray = tmpOut.toByteArray();
+                        wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+                        if (mOnBitmapCroppedHandler != null) {
+                            mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
+                        }
+                    } catch (IOException e) {
+                        Log.w(LOGTAG, "cannot write stream to wallpaper", e);
+                        failure = true;
+                    }
+                }
+            } else {
+                Log.w(LOGTAG, "cannot compress bitmap");
+                failure = true;
+            }
+        }
+        return !failure; // True if any of the operations failed
+    }
+
+    @Override
+    protected Boolean doInBackground(Void... params) {
+        return cropBitmap();
+    }
+
+    @Override
+    protected void onPostExecute(Boolean result) {
+        if (mOnEndRunnable != null) {
+            mOnEndRunnable.run();
+        }
+    }
+}
\ No newline at end of file
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java
index a671ed2..3470017 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java
@@ -16,87 +16,32 @@
 
 package com.android.gallery3d.common;
 
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
-import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
+import android.net.Uri;
 import android.os.Build;
-import android.util.FloatMath;
 import android.util.Log;
+import android.view.WindowManager;
 
-import java.io.ByteArrayOutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import com.android.gallery3d.exif.ExifInterface;
+import com.android.launcher3.WallpaperCropActivity;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 
 public class BitmapUtils {
+
     private static final String TAG = "BitmapUtils";
-    private static final int DEFAULT_JPEG_QUALITY = 90;
-    public static final int UNCONSTRAINED = -1;
-
-    private BitmapUtils(){}
-
-    /*
-     * Compute the sample size as a function of minSideLength
-     * and maxNumOfPixels.
-     * minSideLength is used to specify that minimal width or height of a
-     * bitmap.
-     * maxNumOfPixels is used to specify the maximal size in pixels that is
-     * tolerable in terms of memory usage.
-     *
-     * The function returns a sample size based on the constraints.
-     * Both size and minSideLength can be passed in as UNCONSTRAINED,
-     * which indicates no care of the corresponding constraint.
-     * The functions prefers returning a sample size that
-     * generates a smaller bitmap, unless minSideLength = UNCONSTRAINED.
-     *
-     * Also, the function rounds up the sample size to a power of 2 or multiple
-     * of 8 because BitmapFactory only honors sample size this way.
-     * For example, BitmapFactory downsamples an image by 2 even though the
-     * request is 3. So we round up the sample size to avoid OOM.
-     */
-    public static int computeSampleSize(int width, int height,
-            int minSideLength, int maxNumOfPixels) {
-        int initialSize = computeInitialSampleSize(
-                width, height, minSideLength, maxNumOfPixels);
-
-        return initialSize <= 8
-                ? Utils.nextPowerOf2(initialSize)
-                : (initialSize + 7) / 8 * 8;
-    }
-
-    private static int computeInitialSampleSize(int w, int h,
-            int minSideLength, int maxNumOfPixels) {
-        if (maxNumOfPixels == UNCONSTRAINED
-                && minSideLength == UNCONSTRAINED) return 1;
-
-        int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
-                (int) FloatMath.ceil(FloatMath.sqrt((float) (w * h) / maxNumOfPixels));
-
-        if (minSideLength == UNCONSTRAINED) {
-            return lowerBound;
-        } else {
-            int sampleSize = Math.min(w / minSideLength, h / minSideLength);
-            return Math.max(sampleSize, lowerBound);
-        }
-    }
-
-    // This computes a sample size which makes the longer side at least
-    // minSideLength long. If that's not possible, return 1.
-    public static int computeSampleSizeLarger(int w, int h,
-            int minSideLength) {
-        int initialSize = Math.max(w / minSideLength, h / minSideLength);
-        if (initialSize <= 1) return 1;
-
-        return initialSize <= 8
-                ? Utils.prevPowerOf2(initialSize)
-                : initialSize / 8 * 8;
-    }
 
     // Find the min x that 1 / x >= scale
     public static int computeSampleSizeLarger(float scale) {
-        int initialSize = (int) FloatMath.floor(1f / scale);
+        int initialSize = (int) Math.floor(1f / scale);
         if (initialSize <= 1) return 1;
 
         return initialSize <= 8
@@ -104,15 +49,6 @@
                 : initialSize / 8 * 8;
     }
 
-    // Find the max x that 1 / x <= scale.
-    public static int computeSampleSize(float scale) {
-        Utils.assertTrue(scale > 0);
-        int initialSize = Math.max(1, (int) FloatMath.ceil(1 / scale));
-        return initialSize <= 8
-                ? Utils.nextPowerOf2(initialSize)
-                : (initialSize + 7) / 8 * 8;
-    }
-
     public static Bitmap resizeBitmapByScale(
             Bitmap bitmap, float scale, boolean recycle) {
         int width = Math.round(bitmap.getWidth() * scale);
@@ -136,125 +72,104 @@
         return config;
     }
 
-    public static Bitmap resizeDownBySideLength(
-            Bitmap bitmap, int maxLength, boolean recycle) {
-        int srcWidth = bitmap.getWidth();
-        int srcHeight = bitmap.getHeight();
-        float scale = Math.min(
-                (float) maxLength / srcWidth, (float) maxLength / srcHeight);
-        if (scale >= 1.0f) return bitmap;
-        return resizeBitmapByScale(bitmap, scale, recycle);
+    /**
+     * As a ratio of screen height, the total distance we want the parallax effect to span
+     * horizontally
+     */
+    public static float wallpaperTravelToScreenWidthRatio(int width, int height) {
+        float aspectRatio = width / (float) height;
+
+        // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
+        // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
+        // We will use these two data points to extrapolate how much the wallpaper parallax effect
+        // to span (ie travel) at any aspect ratio:
+
+        final float ASPECT_RATIO_LANDSCAPE = 16/10f;
+        final float ASPECT_RATIO_PORTRAIT = 10/16f;
+        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
+        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
+
+        // To find out the desired width at different aspect ratios, we use the following two
+        // formulas, where the coefficient on x is the aspect ratio (width/height):
+        //   (16/10)x + y = 1.5
+        //   (10/16)x + y = 1.2
+        // We solve for x and y and end up with a final formula:
+        final float x =
+            (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
+            (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
+        final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
+        return x * aspectRatio + y;
     }
 
-    public static Bitmap resizeAndCropCenter(Bitmap bitmap, int size, boolean recycle) {
-        int w = bitmap.getWidth();
-        int h = bitmap.getHeight();
-        if (w == size && h == size) return bitmap;
+    private static Point sDefaultWallpaperSize;
 
-        // scale the image so that the shorter side equals to the target;
-        // the longer side will be center-cropped.
-        float scale = (float) size / Math.min(w,  h);
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    public static Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
+        if (sDefaultWallpaperSize == null) {
+            Point minDims = new Point();
+            Point maxDims = new Point();
+            windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
 
-        Bitmap target = Bitmap.createBitmap(size, size, getConfig(bitmap));
-        int width = Math.round(scale * bitmap.getWidth());
-        int height = Math.round(scale * bitmap.getHeight());
-        Canvas canvas = new Canvas(target);
-        canvas.translate((size - width) / 2f, (size - height) / 2f);
-        canvas.scale(scale, scale);
-        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
-        canvas.drawBitmap(bitmap, 0, 0, paint);
-        if (recycle) bitmap.recycle();
-        return target;
-    }
+            int maxDim = Math.max(maxDims.x, maxDims.y);
+            int minDim = Math.max(minDims.x, minDims.y);
 
-    public static void recycleSilently(Bitmap bitmap) {
-        if (bitmap == null) return;
-        try {
-            bitmap.recycle();
-        } catch (Throwable t) {
-            Log.w(TAG, "unable recycle bitmap", t);
-        }
-    }
+            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                Point realSize = new Point();
+                windowManager.getDefaultDisplay().getRealSize(realSize);
+                maxDim = Math.max(realSize.x, realSize.y);
+                minDim = Math.min(realSize.x, realSize.y);
+            }
 
-    public static Bitmap rotateBitmap(Bitmap source, int rotation, boolean recycle) {
-        if (rotation == 0) return source;
-        int w = source.getWidth();
-        int h = source.getHeight();
-        Matrix m = new Matrix();
-        m.postRotate(rotation);
-        Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, w, h, m, true);
-        if (recycle) source.recycle();
-        return bitmap;
-    }
-
-    public static Bitmap createVideoThumbnail(String filePath) {
-        // MediaMetadataRetriever is available on API Level 8
-        // but is hidden until API Level 10
-        Class<?> clazz = null;
-        Object instance = null;
-        try {
-            clazz = Class.forName("android.media.MediaMetadataRetriever");
-            instance = clazz.newInstance();
-
-            Method method = clazz.getMethod("setDataSource", String.class);
-            method.invoke(instance, filePath);
-
-            // The method name changes between API Level 9 and 10.
-            if (Build.VERSION.SDK_INT <= 9) {
-                return (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
+            // We need to ensure that there is enough extra space in the wallpaper
+            // for the intended parallax effects
+            final int defaultWidth, defaultHeight;
+            if (res.getConfiguration().smallestScreenWidthDp >= 720) {
+                defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+                defaultHeight = maxDim;
             } else {
-                byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
-                if (data != null) {
-                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
-                    if (bitmap != null) return bitmap;
-                }
-                return (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
+                defaultWidth = Math.max((int) (minDim * WallpaperCropActivity.WALLPAPER_SCREENS_SPAN), maxDim);
+                defaultHeight = maxDim;
             }
-        } catch (IllegalArgumentException ex) {
-            // Assume this is a corrupt video file
-        } catch (RuntimeException ex) {
-            // Assume this is a corrupt video file.
-        } catch (InstantiationException e) {
-            Log.e(TAG, "createVideoThumbnail", e);
-        } catch (InvocationTargetException e) {
-            Log.e(TAG, "createVideoThumbnail", e);
-        } catch (ClassNotFoundException e) {
-            Log.e(TAG, "createVideoThumbnail", e);
-        } catch (NoSuchMethodException e) {
-            Log.e(TAG, "createVideoThumbnail", e);
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "createVideoThumbnail", e);
-        } finally {
-            try {
-                if (instance != null) {
-                    clazz.getMethod("release").invoke(instance);
-                }
-            } catch (Exception ignored) {
-            }
+            sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
         }
-        return null;
+        return sDefaultWallpaperSize;
     }
 
-    public static byte[] compressToBytes(Bitmap bitmap) {
-        return compressToBytes(bitmap, DEFAULT_JPEG_QUALITY);
+    public static int getRotationFromExif(Context context, Uri uri) {
+        return BitmapUtils.getRotationFromExifHelper(null, 0, context, uri);
     }
 
-    public static byte[] compressToBytes(Bitmap bitmap, int quality) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(65536);
-        bitmap.compress(CompressFormat.JPEG, quality, baos);
-        return baos.toByteArray();
+    public static int getRotationFromExif(Resources res, int resId) {
+        return BitmapUtils.getRotationFromExifHelper(res, resId, null, null);
     }
 
-    public static boolean isSupportedByRegionDecoder(String mimeType) {
-        if (mimeType == null) return false;
-        mimeType = mimeType.toLowerCase();
-        return mimeType.startsWith("image/") &&
-                (!mimeType.equals("image/gif") && !mimeType.endsWith("bmp"));
-    }
-
-    public static boolean isRotationSupported(String mimeType) {
-        if (mimeType == null) return false;
-        mimeType = mimeType.toLowerCase();
-        return mimeType.equals("image/jpeg");
+    private static int getRotationFromExifHelper(Resources res, int resId, Context context, Uri uri) {
+        ExifInterface ei = new ExifInterface();
+        InputStream is = null;
+        BufferedInputStream bis = null;
+        try {
+            if (uri != null) {
+                is = context.getContentResolver().openInputStream(uri);
+                bis = new BufferedInputStream(is);
+                ei.readExif(bis);
+            } else {
+                is = res.openRawResource(resId);
+                bis = new BufferedInputStream(is);
+                ei.readExif(bis);
+            }
+            Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+            if (ori != null) {
+                return ExifInterface.getRotationForOrientationValue(ori.shortValue());
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Getting exif data failed", e);
+        } catch (NullPointerException e) {
+            // Sometimes the ExifInterface has an internal NPE if Exif data isn't valid
+            Log.w(TAG, "Getting exif data failed", e);
+        } finally {
+            Utils.closeSilently(bis);
+            Utils.closeSilently(is);
+        }
+        return 0;
     }
 }
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/Utils.java b/WallpaperPicker/src/com/android/gallery3d/common/Utils.java
index 614a081..8466c22 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/Utils.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/Utils.java
@@ -16,32 +16,16 @@
 
 package com.android.gallery3d.common;
 
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.database.Cursor;
-import android.os.Build;
+import android.graphics.RectF;
 import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.io.InterruptedIOException;
 
 public class Utils {
     private static final String TAG = "Utils";
-    private static final String DEBUG_TAG = "GalleryDebug";
-
-    private static final long POLY64REV = 0x95AC9329AC4BC9B5L;
-    private static final long INITIALCRC = 0xFFFFFFFFFFFFFFFFL;
-
-    private static long[] sCrcTable = new long[256];
-
-    private static final boolean IS_DEBUG_BUILD =
-            Build.TYPE.equals("eng") || Build.TYPE.equals("userdebug");
-
-    private static final String MASK_STRING = "********************************";
 
     // Throws AssertionError if the input is false.
     public static void assertTrue(boolean cond) {
@@ -50,28 +34,6 @@
         }
     }
 
-    // Throws AssertionError with the message. We had a method having the form
-    //   assertTrue(boolean cond, String message, Object ... args);
-    // However a call to that method will cause memory allocation even if the
-    // condition is false (due to autoboxing generated by "Object ... args"),
-    // so we don't use that anymore.
-    public static void fail(String message, Object ... args) {
-        throw new AssertionError(
-                args.length == 0 ? message : String.format(message, args));
-    }
-
-    // Throws NullPointerException if the input is null.
-    public static <T> T checkNotNull(T object) {
-        if (object == null) throw new NullPointerException();
-        return object;
-    }
-
-    // Returns true if two input Object are both null or equal
-    // to each other.
-    public static boolean equals(Object a, Object b) {
-        return (a == b) || (a == null ? false : a.equals(b));
-    }
-
     // Returns the next power of two.
     // Returns the input if it is already power of 2.
     // Throws IllegalArgumentException if the input is <= 0 or
@@ -102,87 +64,6 @@
         return x;
     }
 
-    // Returns the input value x clamped to the range [min, max].
-    public static float clamp(float x, float min, float max) {
-        if (x > max) return max;
-        if (x < min) return min;
-        return x;
-    }
-
-    // Returns the input value x clamped to the range [min, max].
-    public static long clamp(long x, long min, long max) {
-        if (x > max) return max;
-        if (x < min) return min;
-        return x;
-    }
-
-    public static boolean isOpaque(int color) {
-        return color >>> 24 == 0xFF;
-    }
-
-    public static void swap(int[] array, int i, int j) {
-        int temp = array[i];
-        array[i] = array[j];
-        array[j] = temp;
-    }
-
-    /**
-     * A function thats returns a 64-bit crc for string
-     *
-     * @param in input string
-     * @return a 64-bit crc value
-     */
-    public static final long crc64Long(String in) {
-        if (in == null || in.length() == 0) {
-            return 0;
-        }
-        return crc64Long(getBytes(in));
-    }
-
-    static {
-        // http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c
-        long part;
-        for (int i = 0; i < 256; i++) {
-            part = i;
-            for (int j = 0; j < 8; j++) {
-                long x = ((int) part & 1) != 0 ? POLY64REV : 0;
-                part = (part >> 1) ^ x;
-            }
-            sCrcTable[i] = part;
-        }
-    }
-
-    public static final long crc64Long(byte[] buffer) {
-        long crc = INITIALCRC;
-        for (int k = 0, n = buffer.length; k < n; ++k) {
-            crc = sCrcTable[(((int) crc) ^ buffer[k]) & 0xff] ^ (crc >> 8);
-        }
-        return crc;
-    }
-
-    public static byte[] getBytes(String in) {
-        byte[] result = new byte[in.length() * 2];
-        int output = 0;
-        for (char ch : in.toCharArray()) {
-            result[output++] = (byte) (ch & 0xFF);
-            result[output++] = (byte) (ch >> 8);
-        }
-        return result;
-    }
-
-    public static void closeSilently(Closeable c) {
-        if (c == null) return;
-        try {
-            c.close();
-        } catch (IOException t) {
-            Log.w(TAG, "close fail ", t);
-        }
-    }
-
-    public static int compare(long a, long b) {
-        return a < b ? -1 : a == b ? 0 : 1;
-    }
-
     public static int ceilLog2(float value) {
         int i;
         for (i = 0; i < 31; i++) {
@@ -199,6 +80,15 @@
         return i - 1;
     }
 
+    public static void closeSilently(Closeable c) {
+        if (c == null) return;
+        try {
+            c.close();
+        } catch (IOException t) {
+            Log.w(TAG, "close fail ", t);
+        }
+    }
+
     public static void closeSilently(ParcelFileDescriptor fd) {
         try {
             if (fd != null) fd.close();
@@ -215,126 +105,25 @@
         }
     }
 
-    public static float interpolateAngle(
-            float source, float target, float progress) {
-        // interpolate the angle from source to target
-        // We make the difference in the range of [-179, 180], this is the
-        // shortest path to change source to target.
-        float diff = target - source;
-        if (diff < 0) diff += 360f;
-        if (diff > 180) diff -= 360f;
-
-        float result = source + diff * progress;
-        return result < 0 ? result + 360f : result;
-    }
-
-    public static float interpolateScale(
-            float source, float target, float progress) {
-        return source + progress * (target - source);
-    }
-
-    public static String ensureNotNull(String value) {
-        return value == null ? "" : value;
-    }
-
-    public static float parseFloatSafely(String content, float defaultValue) {
-        if (content == null) return defaultValue;
-        try {
-            return Float.parseFloat(content);
-        } catch (NumberFormatException e) {
-            return defaultValue;
+    public static RectF getMaxCropRect(
+            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
+        RectF cropRect = new RectF();
+        // Get a crop rect that will fit this
+        if (inWidth / (float) inHeight > outWidth / (float) outHeight) {
+             cropRect.top = 0;
+             cropRect.bottom = inHeight;
+             cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2;
+             cropRect.right = inWidth - cropRect.left;
+             if (leftAligned) {
+                 cropRect.right -= cropRect.left;
+                 cropRect.left = 0;
+             }
+        } else {
+            cropRect.left = 0;
+            cropRect.right = inWidth;
+            cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2;
+            cropRect.bottom = inHeight - cropRect.top;
         }
-    }
-
-    public static int parseIntSafely(String content, int defaultValue) {
-        if (content == null) return defaultValue;
-        try {
-            return Integer.parseInt(content);
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    public static boolean isNullOrEmpty(String exifMake) {
-        return TextUtils.isEmpty(exifMake);
-    }
-
-    public static void waitWithoutInterrupt(Object object) {
-        try {
-            object.wait();
-        } catch (InterruptedException e) {
-            Log.w(TAG, "unexpected interrupt: " + object);
-        }
-    }
-
-    public static boolean handleInterrruptedException(Throwable e) {
-        // A helper to deal with the interrupt exception
-        // If an interrupt detected, we will setup the bit again.
-        if (e instanceof InterruptedIOException
-                || e instanceof InterruptedException) {
-            Thread.currentThread().interrupt();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @return String with special XML characters escaped.
-     */
-    public static String escapeXml(String s) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0, len = s.length(); i < len; ++i) {
-            char c = s.charAt(i);
-            switch (c) {
-                case '<':  sb.append("&lt;"); break;
-                case '>':  sb.append("&gt;"); break;
-                case '\"': sb.append("&quot;"); break;
-                case '\'': sb.append("&#039;"); break;
-                case '&':  sb.append("&amp;"); break;
-                default: sb.append(c);
-            }
-        }
-        return sb.toString();
-    }
-
-    public static String getUserAgent(Context context) {
-        PackageInfo packageInfo;
-        try {
-            packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
-        } catch (NameNotFoundException e) {
-            throw new IllegalStateException("getPackageInfo failed");
-        }
-        return String.format("%s/%s; %s/%s/%s/%s; %s/%s/%s",
-                packageInfo.packageName,
-                packageInfo.versionName,
-                Build.BRAND,
-                Build.DEVICE,
-                Build.MODEL,
-                Build.ID,
-                Build.VERSION.SDK_INT,
-                Build.VERSION.RELEASE,
-                Build.VERSION.INCREMENTAL);
-    }
-
-    public static String[] copyOf(String[] source, int newSize) {
-        String[] result = new String[newSize];
-        newSize = Math.min(source.length, newSize);
-        System.arraycopy(source, 0, result, 0, newSize);
-        return result;
-    }
-
-    // Mask information for debugging only. It returns <code>info.toString()</code> directly
-    // for debugging build (i.e., 'eng' and 'userdebug') and returns a mask ("****")
-    // in release build to protect the information (e.g. for privacy issue).
-    public static String maskDebugInfo(Object info) {
-        if (info == null) return null;
-        String s = info.toString();
-        int length = Math.min(s.length(), MASK_STRING.length());
-        return IS_DEBUG_BUILD ? s : MASK_STRING.substring(0, length);
-    }
-
-    // This method should be ONLY used for debugging.
-    public static void debug(String message, Object ... args) {
-        Log.v(DEBUG_TAG, String.format(message, args));
+        return cropRect;
     }
 }
diff --git a/WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java
index 2e77b90..0f3efb7 100644
--- a/WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java
+++ b/WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java
@@ -27,7 +27,6 @@
 // If a BasicTexture is loaded into GL memory, it has a GL texture id.
 public abstract class BasicTexture implements Texture {
 
-    @SuppressWarnings("unused")
     private static final String TAG = "BasicTexture";
     protected static final int UNSPECIFIED = -1;
 
diff --git a/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
index 4ead131..933260b 100644
--- a/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
+++ b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
@@ -23,8 +23,6 @@
 import android.opengl.Matrix;
 import android.util.Log;
 
-import com.android.gallery3d.util.IntArray;
-
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -698,6 +696,7 @@
     }
 
     private void prepareTexture(BasicTexture texture, int program, ShaderParameter[] params) {
+        deleteRecycledResources();
         GLES20.glUseProgram(program);
         checkError();
         enableBlending(!texture.isOpaque() || getAlpha() < OPAQUE_ALPHA);
diff --git a/WallpaperPicker/src/com/android/gallery3d/util/IntArray.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/IntArray.java
similarity index 97%
rename from WallpaperPicker/src/com/android/gallery3d/util/IntArray.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/IntArray.java
index 2c4dc2c..f123624 100644
--- a/WallpaperPicker/src/com/android/gallery3d/util/IntArray.java
+++ b/WallpaperPicker/src/com/android/gallery3d/glrenderer/IntArray.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.gallery3d.util;
+package com.android.gallery3d.glrenderer;
 
 public class IntArray {
     private static final int INIT_CAPACITY = 8;
diff --git a/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java b/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
index 88f4461..0a9050c 100644
--- a/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
+++ b/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
@@ -122,8 +122,8 @@
             Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
             preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                     mInfo.getComponent());
-            a.onLiveWallpaperPickerLaunch(mInfo);
-            a.startActivityForResultSafely(preview, WallpaperPickerActivity.PICK_LIVE_WALLPAPER);
+            a.startActivityForResultSafely(preview,
+                    WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY);
         }
     }
 
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index fa8ec64..0ddb79e 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.app.WallpaperManager;
@@ -25,42 +26,40 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Canvas;
 import android.graphics.Matrix;
-import android.graphics.Paint;
 import android.graphics.Point;
-import android.graphics.Rect;
 import android.graphics.RectF;
 import android.net.Uri;
-import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.Toast;
 
+import com.android.gallery3d.common.BitmapCropTask;
+import com.android.gallery3d.common.BitmapUtils;
 import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.exif.ExifInterface;
 import com.android.photos.BitmapRegionTileSource;
 import com.android.photos.BitmapRegionTileSource.BitmapSource;
+import com.android.photos.BitmapRegionTileSource.BitmapSource.InBitmapProvider;
+import com.android.photos.views.TiledImageRenderer.TileSource;
 
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.WeakHashMap;
 
-public class WallpaperCropActivity extends Activity {
+public class WallpaperCropActivity extends Activity implements Handler.Callback {
     private static final String LOGTAG = "Launcher3.CropActivity";
 
     protected static final String WALLPAPER_WIDTH_KEY = "wallpaper.width";
     protected static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height";
-    private static final int DEFAULT_COMPRESS_QUALITY = 90;
+
     /**
      * The maximum bitmap size we allow to be returned through the intent.
      * Intents have a maximum of 1MB in total size. However, the Bitmap seems to
@@ -69,17 +68,31 @@
      * array instead of a Bitmap instance to avoid overhead.
      */
     public static final int MAX_BMAP_IN_INTENT = 750000;
-    private static final float WALLPAPER_SCREENS_SPAN = 2f;
+    public static final float WALLPAPER_SCREENS_SPAN = 2f;
 
-    protected static Point sDefaultWallpaperSize;
+    private static final int MSG_LOAD_IMAGE = 1;
 
     protected CropView mCropView;
+    protected View mProgressView;
     protected Uri mUri;
     protected View mSetWallpaperButton;
 
+    private HandlerThread mLoaderThread;
+    private Handler mLoaderHandler;
+    private LoadRequest mCurrentLoadRequest;
+    private byte[] mTempStorageForDecoding = new byte[16 * 1024];
+    // A weak-set of reusable bitmaps
+    private Set<Bitmap> mReusableBitmaps =
+            Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>());
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        mLoaderThread = new HandlerThread("wallpaper_loader");
+        mLoaderThread.start();
+        mLoaderHandler = new Handler(mLoaderThread.getLooper(), this);
+
         init();
         if (!enableRotation()) {
             setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
@@ -90,6 +103,7 @@
         setContentView(R.layout.wallpaper_cropper);
 
         mCropView = (CropView) findViewById(R.id.cropView);
+        mProgressView = findViewById(R.id.loading);
 
         Intent cropIntent = getIntent();
         final Uri imageUri = cropIntent.getData();
@@ -130,7 +144,7 @@
                 }
             }
         };
-        setCropViewTileSource(bitmapSource, true, false, onLoad);
+        setCropViewTileSource(bitmapSource, true, false, null, onLoad);
     }
 
     @Override
@@ -138,65 +152,134 @@
         if (mCropView != null) {
             mCropView.destroy();
         }
+        if (mLoaderThread != null) {
+            mLoaderThread.quit();
+        }
         super.onDestroy();
     }
 
-    public void setCropViewTileSource(
-            final BitmapRegionTileSource.BitmapSource bitmapSource, final boolean touchEnabled,
-            final boolean moveToLeft, final Runnable postExecute) {
-        final Context context = WallpaperCropActivity.this;
-        final View progressView = findViewById(R.id.loading);
-        final AsyncTask<Void, Void, Void> loadBitmapTask = new AsyncTask<Void, Void, Void>() {
-            protected Void doInBackground(Void...args) {
-                if (!isCancelled()) {
-                    try {
-                        bitmapSource.loadInBackground();
-                    } catch (SecurityException securityException) {
-                        if (isDestroyed()) {
-                            // Temporarily granted permissions are revoked when the activity
-                            // finishes, potentially resulting in a SecurityException here.
-                            // Even though {@link #isDestroyed} might also return true in different
-                            // situations where the configuration changes, we are fine with
-                            // catching these cases here as well.
-                            cancel(false);
-                        } else {
-                            // otherwise it had a different cause and we throw it further
-                            throw securityException;
+    /**
+     * This is called on {@link #mLoaderThread}
+     */
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (msg.what == MSG_LOAD_IMAGE) {
+            final LoadRequest req = (LoadRequest) msg.obj;
+            try {
+                req.src.loadInBackground(new InBitmapProvider() {
+
+                    @Override
+                    public Bitmap forPixelCount(int count) {
+                        synchronized (mReusableBitmaps) {
+                            Iterator<Bitmap> itr = mReusableBitmaps.iterator();
+                            while (itr.hasNext()) {
+                                Bitmap b = itr.next();
+                                if (b.getWidth() * b.getHeight() >= count) {
+                                    itr.remove();
+                                    return b;
+                                }
+                            }
                         }
+                        return null;
                     }
-                }
-                return null;
-            }
-            protected void onPostExecute(Void arg) {
-                if (!isCancelled()) {
-                    progressView.setVisibility(View.INVISIBLE);
-                    if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) {
-                        mCropView.setTileSource(
-                                new BitmapRegionTileSource(context, bitmapSource), null);
-                        mCropView.setTouchEnabled(touchEnabled);
-                        if (moveToLeft) {
-                            mCropView.moveToLeft();
-                        }
-                    }
-                }
-                if (postExecute != null) {
-                    postExecute.run();
+                });
+            } catch (SecurityException securityException) {
+                if (isDestroyed()) {
+                    // Temporarily granted permissions are revoked when the activity
+                    // finishes, potentially resulting in a SecurityException here.
+                    // Even though {@link #isDestroyed} might also return true in different
+                    // situations where the configuration changes, we are fine with
+                    // catching these cases here as well.
+                    return true;
+                } else {
+                    // otherwise it had a different cause and we throw it further
+                    throw securityException;
                 }
             }
-        };
+
+            req.result = new BitmapRegionTileSource(this, req.src, mTempStorageForDecoding);
+            runOnUiThread(new Runnable() {
+
+                @Override
+                public void run() {
+                    if (req == mCurrentLoadRequest) {
+                        onLoadRequestComplete(req,
+                                req.src.getLoadingState() == BitmapSource.State.LOADED);
+                    } else {
+                        addReusableBitmap(req.result);
+                    }
+                }
+            });
+            return true;
+        }
+        return false;
+    }
+
+    private void addReusableBitmap(TileSource src) {
+        synchronized (mReusableBitmaps) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
+                    && src instanceof BitmapRegionTileSource) {
+                Bitmap preview = ((BitmapRegionTileSource) src).getBitmap();
+                if (preview != null && preview.isMutable()) {
+                    mReusableBitmaps.add(preview);
+                }
+            }
+        }
+    }
+
+    protected void onLoadRequestComplete(LoadRequest req, boolean success) {
+        mCurrentLoadRequest = null;
+        if (success) {
+            TileSource oldSrc = mCropView.getTileSource();
+            mCropView.setTileSource(req.result, null);
+            mCropView.setTouchEnabled(req.touchEnabled);
+            if (req.moveToLeft) {
+                mCropView.moveToLeft();
+            }
+            if (req.scaleProvider != null) {
+                mCropView.setScale(req.scaleProvider.getScale(req.result));
+            }
+
+            // Free last image
+            if (oldSrc != null) {
+                // Call yield instead of recycle, as we only want to free GL resource.
+                // We can still reuse the bitmap for decoding any other image.
+                oldSrc.getPreview().yield();
+            }
+            addReusableBitmap(oldSrc);
+        }
+        if (req.postExecute != null) {
+            req.postExecute.run();
+        }
+    }
+
+    public final void setCropViewTileSource(BitmapSource bitmapSource, boolean touchEnabled,
+            boolean moveToLeft, CropViewScaleProvider scaleProvider, Runnable postExecute) {
+        final LoadRequest req = new LoadRequest();
+        req.moveToLeft = moveToLeft;
+        req.src = bitmapSource;
+        req.touchEnabled = touchEnabled;
+        req.postExecute = postExecute;
+        req.scaleProvider = scaleProvider;
+        mCurrentLoadRequest = req;
+
+        // Remove any pending requests
+        mLoaderHandler.removeMessages(MSG_LOAD_IMAGE);
+        Message.obtain(mLoaderHandler, MSG_LOAD_IMAGE, req).sendToTarget();
+
         // We don't want to show the spinner every time we load an image, because that would be
         // annoying; instead, only start showing the spinner if loading the image has taken
         // longer than 1 sec (ie 1000 ms)
-        progressView.postDelayed(new Runnable() {
+        mProgressView.postDelayed(new Runnable() {
             public void run() {
-                if (loadBitmapTask.getStatus() != AsyncTask.Status.FINISHED) {
-                    progressView.setVisibility(View.VISIBLE);
+                if (mCurrentLoadRequest == req) {
+                    mProgressView.setVisibility(View.VISIBLE);
                 }
             }
         }, 1000);
-        loadBitmapTask.execute();
     }
 
+
     public boolean enableRotation() {
         return getResources().getBoolean(R.bool.allow_rotation);
     }
@@ -205,111 +288,8 @@
         return LauncherFiles.WALLPAPER_CROP_PREFERENCES_KEY;
     }
 
-    // As a ratio of screen height, the total distance we want the parallax effect to span
-    // horizontally
-    private static float wallpaperTravelToScreenWidthRatio(int width, int height) {
-        float aspectRatio = width / (float) height;
-
-        // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
-        // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
-        // We will use these two data points to extrapolate how much the wallpaper parallax effect
-        // to span (ie travel) at any aspect ratio:
-
-        final float ASPECT_RATIO_LANDSCAPE = 16/10f;
-        final float ASPECT_RATIO_PORTRAIT = 10/16f;
-        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
-        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
-
-        // To find out the desired width at different aspect ratios, we use the following two
-        // formulas, where the coefficient on x is the aspect ratio (width/height):
-        //   (16/10)x + y = 1.5
-        //   (10/16)x + y = 1.2
-        // We solve for x and y and end up with a final formula:
-        final float x =
-            (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
-            (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
-        final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
-        return x * aspectRatio + y;
-    }
-
-    static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
-        if (sDefaultWallpaperSize == null) {
-            Point minDims = new Point();
-            Point maxDims = new Point();
-            windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
-
-            int maxDim = Math.max(maxDims.x, maxDims.y);
-            int minDim = Math.max(minDims.x, minDims.y);
-
-            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
-                Point realSize = new Point();
-                windowManager.getDefaultDisplay().getRealSize(realSize);
-                maxDim = Math.max(realSize.x, realSize.y);
-                minDim = Math.min(realSize.x, realSize.y);
-            }
-
-            // We need to ensure that there is enough extra space in the wallpaper
-            // for the intended parallax effects
-            final int defaultWidth, defaultHeight;
-            if (isScreenLarge(res)) {
-                defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
-                defaultHeight = maxDim;
-            } else {
-                defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
-                defaultHeight = maxDim;
-            }
-            sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
-        }
-        return sDefaultWallpaperSize;
-    }
-
-    public static int getRotationFromExif(String path) {
-        return getRotationFromExifHelper(path, null, 0, null, null);
-    }
-
-    public static int getRotationFromExif(Context context, Uri uri) {
-        return getRotationFromExifHelper(null, null, 0, context, uri);
-    }
-
-    public static int getRotationFromExif(Resources res, int resId) {
-        return getRotationFromExifHelper(null, res, resId, null, null);
-    }
-
-    private static int getRotationFromExifHelper(
-            String path, Resources res, int resId, Context context, Uri uri) {
-        ExifInterface ei = new ExifInterface();
-        InputStream is = null;
-        BufferedInputStream bis = null;
-        try {
-            if (path != null) {
-                ei.readExif(path);
-            } else if (uri != null) {
-                is = context.getContentResolver().openInputStream(uri);
-                bis = new BufferedInputStream(is);
-                ei.readExif(bis);
-            } else {
-                is = res.openRawResource(resId);
-                bis = new BufferedInputStream(is);
-                ei.readExif(bis);
-            }
-            Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
-            if (ori != null) {
-                return ExifInterface.getRotationForOrientationValue(ori.shortValue());
-            }
-        } catch (IOException e) {
-            Log.w(LOGTAG, "Getting exif data failed", e);
-        } catch (NullPointerException e) {
-            // Sometimes the ExifInterface has an internal NPE if Exif data isn't valid
-            Log.w(LOGTAG, "Getting exif data failed", e);
-        } finally {
-            Utils.closeSilently(bis);
-            Utils.closeSilently(is);
-        }
-        return 0;
-    }
-
     protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) {
-        int rotation = getRotationFromExif(this, uri);
+        int rotation = BitmapUtils.getRotationFromExif(this, uri);
         BitmapCropTask cropTask = new BitmapCropTask(
                 this, uri, null, rotation, 0, 0, true, false, null);
         final Point bounds = cropTask.getImageBounds();
@@ -331,11 +311,11 @@
             Resources res, int resId, final boolean finishActivityWhenDone) {
         // crop this image and scale it down to the default wallpaper size for
         // this device
-        int rotation = getRotationFromExif(res, resId);
+        int rotation = BitmapUtils.getRotationFromExif(res, resId);
         Point inSize = mCropView.getSourceDimensions();
-        Point outSize = getDefaultWallpaperSize(getResources(),
+        Point outSize = BitmapUtils.getDefaultWallpaperSize(getResources(),
                 getWindowManager());
-        RectF crop = getMaxCropRect(
+        RectF crop = Utils.getMaxCropRect(
                 inSize.x, inSize.y, outSize.x, outSize.y, false);
         Runnable onEndCrop = new Runnable() {
             public void run() {
@@ -353,13 +333,9 @@
         cropTask.execute();
     }
 
-    private static boolean isScreenLarge(Resources res) {
-        Configuration config = res.getConfiguration();
-        return config.smallestScreenWidthDp >= 720;
-    }
-
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     protected void cropImageAndSetWallpaper(Uri uri,
-            OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
+            BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
         boolean centerCrop = getResources().getBoolean(R.bool.center_crop);
         // Get the crop
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
@@ -370,7 +346,7 @@
         d.getSize(displaySize);
         boolean isPortrait = displaySize.x < displaySize.y;
 
-        Point defaultWallpaperSize = getDefaultWallpaperSize(getResources(),
+        Point defaultWallpaperSize = BitmapUtils.getDefaultWallpaperSize(getResources(),
                 getWindowManager());
         // Get the crop
         RectF cropRect = mCropView.getCrop();
@@ -452,372 +428,6 @@
         cropTask.execute();
     }
 
-    public interface OnBitmapCroppedHandler {
-        public void onBitmapCropped(byte[] imageBytes);
-    }
-
-    protected static class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
-        Uri mInUri = null;
-        Context mContext;
-        String mInFilePath;
-        byte[] mInImageBytes;
-        int mInResId = 0;
-        RectF mCropBounds = null;
-        int mOutWidth, mOutHeight;
-        int mRotation;
-        String mOutputFormat = "jpg"; // for now
-        boolean mSetWallpaper;
-        boolean mSaveCroppedBitmap;
-        Bitmap mCroppedBitmap;
-        Runnable mOnEndRunnable;
-        Resources mResources;
-        OnBitmapCroppedHandler mOnBitmapCroppedHandler;
-        boolean mNoCrop;
-
-        public BitmapCropTask(Context c, String filePath,
-                RectF cropBounds, int rotation, int outWidth, int outHeight,
-                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
-            mContext = c;
-            mInFilePath = filePath;
-            init(cropBounds, rotation,
-                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
-        }
-
-        public BitmapCropTask(byte[] imageBytes,
-                RectF cropBounds, int rotation, int outWidth, int outHeight,
-                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
-            mInImageBytes = imageBytes;
-            init(cropBounds, rotation,
-                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
-        }
-
-        public BitmapCropTask(Context c, Uri inUri,
-                RectF cropBounds, int rotation, int outWidth, int outHeight,
-                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
-            mContext = c;
-            mInUri = inUri;
-            init(cropBounds, rotation,
-                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
-        }
-
-        public BitmapCropTask(Context c, Resources res, int inResId,
-                RectF cropBounds, int rotation, int outWidth, int outHeight,
-                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
-            mContext = c;
-            mInResId = inResId;
-            mResources = res;
-            init(cropBounds, rotation,
-                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
-        }
-
-        private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
-                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
-            mCropBounds = cropBounds;
-            mRotation = rotation;
-            mOutWidth = outWidth;
-            mOutHeight = outHeight;
-            mSetWallpaper = setWallpaper;
-            mSaveCroppedBitmap = saveCroppedBitmap;
-            mOnEndRunnable = onEndRunnable;
-        }
-
-        public void setOnBitmapCropped(OnBitmapCroppedHandler handler) {
-            mOnBitmapCroppedHandler = handler;
-        }
-
-        public void setNoCrop(boolean value) {
-            mNoCrop = value;
-        }
-
-        public void setOnEndRunnable(Runnable onEndRunnable) {
-            mOnEndRunnable = onEndRunnable;
-        }
-
-        // Helper to setup input stream
-        private InputStream regenerateInputStream() {
-            if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {
-                Log.w(LOGTAG, "cannot read original file, no input URI, resource ID, or " +
-                        "image byte array given");
-            } else {
-                try {
-                    if (mInUri != null) {
-                        return new BufferedInputStream(
-                                mContext.getContentResolver().openInputStream(mInUri));
-                    } else if (mInFilePath != null) {
-                        return mContext.openFileInput(mInFilePath);
-                    } else if (mInImageBytes != null) {
-                        return new BufferedInputStream(new ByteArrayInputStream(mInImageBytes));
-                    } else {
-                        return new BufferedInputStream(mResources.openRawResource(mInResId));
-                    }
-                } catch (FileNotFoundException e) {
-                    Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
-                }
-            }
-            return null;
-        }
-
-        public Point getImageBounds() {
-            InputStream is = regenerateInputStream();
-            if (is != null) {
-                BitmapFactory.Options options = new BitmapFactory.Options();
-                options.inJustDecodeBounds = true;
-                BitmapFactory.decodeStream(is, null, options);
-                Utils.closeSilently(is);
-                if (options.outWidth != 0 && options.outHeight != 0) {
-                    return new Point(options.outWidth, options.outHeight);
-                }
-            }
-            return null;
-        }
-
-        public void setCropBounds(RectF cropBounds) {
-            mCropBounds = cropBounds;
-        }
-
-        public Bitmap getCroppedBitmap() {
-            return mCroppedBitmap;
-        }
-        public boolean cropBitmap() {
-            boolean failure = false;
-
-
-            WallpaperManager wallpaperManager = null;
-            if (mSetWallpaper) {
-                wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
-            }
-
-
-            if (mSetWallpaper && mNoCrop) {
-                try {
-                    InputStream is = regenerateInputStream();
-                    if (is != null) {
-                        wallpaperManager.setStream(is);
-                        Utils.closeSilently(is);
-                    }
-                } catch (IOException e) {
-                    Log.w(LOGTAG, "cannot write stream to wallpaper", e);
-                    failure = true;
-                }
-                return !failure;
-            } else {
-                // Find crop bounds (scaled to original image size)
-                Rect roundedTrueCrop = new Rect();
-                Matrix rotateMatrix = new Matrix();
-                Matrix inverseRotateMatrix = new Matrix();
-
-                Point bounds = getImageBounds();
-                if (mRotation > 0) {
-                    rotateMatrix.setRotate(mRotation);
-                    inverseRotateMatrix.setRotate(-mRotation);
-
-                    mCropBounds.roundOut(roundedTrueCrop);
-                    mCropBounds = new RectF(roundedTrueCrop);
-
-                    if (bounds == null) {
-                        Log.w(LOGTAG, "cannot get bounds for image");
-                        failure = true;
-                        return false;
-                    }
-
-                    float[] rotatedBounds = new float[] { bounds.x, bounds.y };
-                    rotateMatrix.mapPoints(rotatedBounds);
-                    rotatedBounds[0] = Math.abs(rotatedBounds[0]);
-                    rotatedBounds[1] = Math.abs(rotatedBounds[1]);
-
-                    mCropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2);
-                    inverseRotateMatrix.mapRect(mCropBounds);
-                    mCropBounds.offset(bounds.x/2, bounds.y/2);
-
-                }
-
-                mCropBounds.roundOut(roundedTrueCrop);
-
-                if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
-                    Log.w(LOGTAG, "crop has bad values for full size image");
-                    failure = true;
-                    return false;
-                }
-
-                // See how much we're reducing the size of the image
-                int scaleDownSampleSize = Math.max(1, Math.min(roundedTrueCrop.width() / mOutWidth,
-                        roundedTrueCrop.height() / mOutHeight));
-                // Attempt to open a region decoder
-                BitmapRegionDecoder decoder = null;
-                InputStream is = null;
-                try {
-                    is = regenerateInputStream();
-                    if (is == null) {
-                        Log.w(LOGTAG, "cannot get input stream for uri=" + mInUri.toString());
-                        failure = true;
-                        return false;
-                    }
-                    decoder = BitmapRegionDecoder.newInstance(is, false);
-                    Utils.closeSilently(is);
-                } catch (IOException e) {
-                    Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
-                } finally {
-                   Utils.closeSilently(is);
-                   is = null;
-                }
-
-                Bitmap crop = null;
-                if (decoder != null) {
-                    // Do region decoding to get crop bitmap
-                    BitmapFactory.Options options = new BitmapFactory.Options();
-                    if (scaleDownSampleSize > 1) {
-                        options.inSampleSize = scaleDownSampleSize;
-                    }
-                    crop = decoder.decodeRegion(roundedTrueCrop, options);
-                    decoder.recycle();
-                }
-
-                if (crop == null) {
-                    // BitmapRegionDecoder has failed, try to crop in-memory
-                    is = regenerateInputStream();
-                    Bitmap fullSize = null;
-                    if (is != null) {
-                        BitmapFactory.Options options = new BitmapFactory.Options();
-                        if (scaleDownSampleSize > 1) {
-                            options.inSampleSize = scaleDownSampleSize;
-                        }
-                        fullSize = BitmapFactory.decodeStream(is, null, options);
-                        Utils.closeSilently(is);
-                    }
-                    if (fullSize != null) {
-                        // Find out the true sample size that was used by the decoder
-                        scaleDownSampleSize = bounds.x / fullSize.getWidth();
-                        mCropBounds.left /= scaleDownSampleSize;
-                        mCropBounds.top /= scaleDownSampleSize;
-                        mCropBounds.bottom /= scaleDownSampleSize;
-                        mCropBounds.right /= scaleDownSampleSize;
-                        mCropBounds.roundOut(roundedTrueCrop);
-
-                        // Adjust values to account for issues related to rounding
-                        if (roundedTrueCrop.width() > fullSize.getWidth()) {
-                            // Adjust the width
-                            roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth();
-                        }
-                        if (roundedTrueCrop.right > fullSize.getWidth()) {
-                            // Adjust the left value
-                            int adjustment = roundedTrueCrop.left -
-                                    Math.max(0, roundedTrueCrop.right - roundedTrueCrop.width());
-                            roundedTrueCrop.left -= adjustment;
-                            roundedTrueCrop.right -= adjustment;
-                        }
-                        if (roundedTrueCrop.height() > fullSize.getHeight()) {
-                            // Adjust the height
-                            roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight();
-                        }
-                        if (roundedTrueCrop.bottom > fullSize.getHeight()) {
-                            // Adjust the top value
-                            int adjustment = roundedTrueCrop.top -
-                                    Math.max(0, roundedTrueCrop.bottom - roundedTrueCrop.height());
-                            roundedTrueCrop.top -= adjustment;
-                            roundedTrueCrop.bottom -= adjustment;
-                        }
-
-                        crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
-                                roundedTrueCrop.top, roundedTrueCrop.width(),
-                                roundedTrueCrop.height());
-                    }
-                }
-
-                if (crop == null) {
-                    Log.w(LOGTAG, "cannot decode file: " + mInUri.toString());
-                    failure = true;
-                    return false;
-                }
-                if (mOutWidth > 0 && mOutHeight > 0 || mRotation > 0) {
-                    float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() };
-                    rotateMatrix.mapPoints(dimsAfter);
-                    dimsAfter[0] = Math.abs(dimsAfter[0]);
-                    dimsAfter[1] = Math.abs(dimsAfter[1]);
-
-                    if (!(mOutWidth > 0 && mOutHeight > 0)) {
-                        mOutWidth = Math.round(dimsAfter[0]);
-                        mOutHeight = Math.round(dimsAfter[1]);
-                    }
-
-                    RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]);
-                    RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
-
-                    Matrix m = new Matrix();
-                    if (mRotation == 0) {
-                        m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
-                    } else {
-                        Matrix m1 = new Matrix();
-                        m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f);
-                        Matrix m2 = new Matrix();
-                        m2.setRotate(mRotation);
-                        Matrix m3 = new Matrix();
-                        m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f);
-                        Matrix m4 = new Matrix();
-                        m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
-
-                        Matrix c1 = new Matrix();
-                        c1.setConcat(m2, m1);
-                        Matrix c2 = new Matrix();
-                        c2.setConcat(m4, m3);
-                        m.setConcat(c2, c1);
-                    }
-
-                    Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
-                            (int) returnRect.height(), Bitmap.Config.ARGB_8888);
-                    if (tmp != null) {
-                        Canvas c = new Canvas(tmp);
-                        Paint p = new Paint();
-                        p.setFilterBitmap(true);
-                        c.drawBitmap(crop, m, p);
-                        crop = tmp;
-                    }
-                }
-
-                if (mSaveCroppedBitmap) {
-                    mCroppedBitmap = crop;
-                }
-
-                // Get output compression format
-                CompressFormat cf =
-                        convertExtensionToCompressFormat(getFileExtension(mOutputFormat));
-
-                // Compress to byte array
-                ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
-                if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
-                    // If we need to set to the wallpaper, set it
-                    if (mSetWallpaper && wallpaperManager != null) {
-                        try {
-                            byte[] outByteArray = tmpOut.toByteArray();
-                            wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
-                            if (mOnBitmapCroppedHandler != null) {
-                                mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
-                            }
-                        } catch (IOException e) {
-                            Log.w(LOGTAG, "cannot write stream to wallpaper", e);
-                            failure = true;
-                        }
-                    }
-                } else {
-                    Log.w(LOGTAG, "cannot compress bitmap");
-                    failure = true;
-                }
-            }
-            return !failure; // True if any of the operations failed
-        }
-
-        @Override
-        protected Boolean doInBackground(Void... params) {
-            return cropBitmap();
-        }
-
-        @Override
-        protected void onPostExecute(Boolean result) {
-            if (mOnEndRunnable != null) {
-                mOnEndRunnable.run();
-            }
-        }
-    }
-
     protected void updateWallpaperDimensions(int width, int height) {
         String spKey = getSharedPreferencesKey();
         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
@@ -835,11 +445,11 @@
                 sp, getWindowManager(), WallpaperManager.getInstance(this), true);
     }
 
-    static public void suggestWallpaperDimension(Resources res,
+    public static void suggestWallpaperDimension(Resources res,
             final SharedPreferences sharedPrefs,
             WindowManager windowManager,
             final WallpaperManager wallpaperManager, boolean fallBackToDefaults) {
-        final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
+        final Point defaultWallpaperSize = BitmapUtils.getDefaultWallpaperSize(res, windowManager);
         // If we have saved a wallpaper width/height, use that instead
 
         int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, -1);
@@ -860,39 +470,17 @@
         }
     }
 
-    protected static RectF getMaxCropRect(
-            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
-        RectF cropRect = new RectF();
-        // Get a crop rect that will fit this
-        if (inWidth / (float) inHeight > outWidth / (float) outHeight) {
-             cropRect.top = 0;
-             cropRect.bottom = inHeight;
-             cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2;
-             cropRect.right = inWidth - cropRect.left;
-             if (leftAligned) {
-                 cropRect.right -= cropRect.left;
-                 cropRect.left = 0;
-             }
-        } else {
-            cropRect.left = 0;
-            cropRect.right = inWidth;
-            cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2;
-            cropRect.bottom = inHeight - cropRect.top;
-        }
-        return cropRect;
+    static class LoadRequest {
+        BitmapSource src;
+        boolean touchEnabled;
+        boolean moveToLeft;
+        Runnable postExecute;
+        CropViewScaleProvider scaleProvider;
+
+        TileSource result;
     }
 
-    protected static CompressFormat convertExtensionToCompressFormat(String extension) {
-        return extension.equals("png") ? CompressFormat.PNG : CompressFormat.JPEG;
-    }
-
-    protected static String getFileExtension(String requestFormat) {
-        String outputFormat = (requestFormat == null)
-                ? "jpg"
-                : requestFormat;
-        outputFormat = outputFormat.toLowerCase();
-        return (outputFormat.equals("png") || outputFormat.equals("gif"))
-                ? "png" // We don't support gif compression.
-                : "jpg";
+    interface CropViewScaleProvider {
+        float getScale(TileSource src);
     }
 }
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 09e0963..cbed61b 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -20,7 +20,6 @@
 import android.annotation.TargetApi;
 import android.app.ActionBar;
 import android.app.Activity;
-import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.Intent;
@@ -70,8 +69,12 @@
 import android.widget.LinearLayout;
 import android.widget.Toast;
 
+import com.android.gallery3d.common.BitmapCropTask;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
 import com.android.photos.BitmapRegionTileSource;
 import com.android.photos.BitmapRegionTileSource.BitmapSource;
+import com.android.photos.views.TiledImageRenderer.TileSource;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -83,7 +86,6 @@
 
     public static final int IMAGE_PICK = 5;
     public static final int PICK_WALLPAPER_THIRD_PARTY_ACTIVITY = 6;
-    public static final int PICK_LIVE_WALLPAPER = 7;
     private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
     private static final String SELECTED_INDEX = "SELECTED_INDEX";
     private static final int FLAG_POST_DELAY_MILLIS = 200;
@@ -102,9 +104,7 @@
 
     ArrayList<Uri> mTempWallpaperTiles = new ArrayList<Uri>();
     private SavedWallpaperImages mSavedImages;
-    private WallpaperInfo mLiveWallpaperInfoOnPickerLaunch;
     private int mSelectedIndex = -1;
-    private WallpaperInfo mLastClickedLiveWallpaperInfo;
 
     public static abstract class WallpaperTileInfo {
         protected View mView;
@@ -169,12 +169,12 @@
             }
             mBitmapSource = new BitmapRegionTileSource.UriBitmapSource(
                     a, mUri, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
-            a.setCropViewTileSource(mBitmapSource, true, false, onLoad);
+            a.setCropViewTileSource(mBitmapSource, true, false, null, onLoad);
         }
         @Override
         public void onSave(final WallpaperPickerActivity a) {
             boolean finishActivityWhenDone = true;
-            OnBitmapCroppedHandler h = new OnBitmapCroppedHandler() {
+            BitmapCropTask.OnBitmapCroppedHandler h = new BitmapCropTask.OnBitmapCroppedHandler() {
                 public void onBitmapCropped(byte[] imageBytes) {
                     Point thumbSize = getDefaultThumbnailSize(a.getResources());
                     // rotation is set to 0 since imageBytes has already been correctly rotated
@@ -206,7 +206,7 @@
         public void onClick(WallpaperPickerActivity a) {
             BitmapRegionTileSource.UriBitmapSource bitmapSource =
                     new BitmapRegionTileSource.UriBitmapSource(a, Uri.fromFile(mFile), 1024);
-            a.setCropViewTileSource(bitmapSource, false, true, null);
+            a.setCropViewTileSource(bitmapSource, false, true, null, null);
         }
         @Override
         public void onSave(WallpaperPickerActivity a) {
@@ -232,22 +232,22 @@
             mThumb = thumb;
         }
         @Override
-        public void onClick(WallpaperPickerActivity a) {
+        public void onClick(final WallpaperPickerActivity a) {
             BitmapRegionTileSource.ResourceBitmapSource bitmapSource =
                     new BitmapRegionTileSource.ResourceBitmapSource(
                             mResources, mResId, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
-            bitmapSource.loadInBackground();
-            BitmapRegionTileSource source = new BitmapRegionTileSource(a, bitmapSource);
-            CropView v = a.getCropView();
-            v.setTileSource(source, null);
-            Point wallpaperSize = WallpaperCropActivity.getDefaultWallpaperSize(
-                    a.getResources(), a.getWindowManager());
-            RectF crop = WallpaperCropActivity.getMaxCropRect(
-                    source.getImageWidth(), source.getImageHeight(),
-                    wallpaperSize.x, wallpaperSize.y, false);
-            v.setScale(wallpaperSize.x / crop.width());
-            v.setTouchEnabled(false);
-            a.setSystemWallpaperVisiblity(false);
+            a.setCropViewTileSource(bitmapSource, false, false, new CropViewScaleProvider() {
+
+                @Override
+                public float getScale(TileSource src) {
+                    Point wallpaperSize = BitmapUtils.getDefaultWallpaperSize(
+                            a.getResources(), a.getWindowManager());
+                    RectF crop = Utils.getMaxCropRect(
+                            src.getImageWidth(), src.getImageHeight(),
+                            wallpaperSize.x, wallpaperSize.y, false);
+                    return wallpaperSize.x / crop.width();
+                }
+            }, null);
         }
         @Override
         public void onSave(WallpaperPickerActivity a) {
@@ -272,21 +272,26 @@
         @Override
         public void onClick(WallpaperPickerActivity a) {
             CropView c = a.getCropView();
-
             Drawable defaultWallpaper = WallpaperManager.getInstance(a).getBuiltInDrawable(
                     c.getWidth(), c.getHeight(), false, 0.5f, 0.5f);
-
             if (defaultWallpaper == null) {
                 Log.w(TAG, "Null default wallpaper encountered.");
                 c.setTileSource(null, null);
                 return;
             }
 
-            c.setTileSource(
-                    new DrawableTileSource(a, defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE), null);
-            c.setScale(1f);
-            c.setTouchEnabled(false);
-            a.setSystemWallpaperVisiblity(false);
+            LoadRequest req = new LoadRequest();
+            req.moveToLeft = false;
+            req.touchEnabled = false;
+            req.scaleProvider = new CropViewScaleProvider() {
+
+                @Override
+                public float getScale(TileSource src) {
+                    return 1f;
+                }
+            };
+            req.result = new DrawableTileSource(a, defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE);
+            a.onLoadRequestComplete(req, true);
         }
         @Override
         public void onSave(WallpaperPickerActivity a) {
@@ -349,24 +354,11 @@
     }
 
     @Override
-    public void setCropViewTileSource(BitmapSource bitmapSource,
-                                      boolean touchEnabled,
-                                      boolean moveToLeft,
-                                      final Runnable postExecute) {
-        // we also want to show our own wallpaper instead of the one in the background
-        Runnable showPostExecuteRunnable = new Runnable() {
-            @Override
-            public void run() {
-                if(postExecute != null) {
-                    postExecute.run();
-                }
-                setSystemWallpaperVisiblity(false);
-            }
-        };
-        super.setCropViewTileSource(bitmapSource,
-                touchEnabled,
-                moveToLeft,
-                showPostExecuteRunnable);
+    protected void onLoadRequestComplete(LoadRequest req, boolean success) {
+        super.onLoadRequestComplete(req, success);
+        if (success) {
+            setSystemWallpaperVisiblity(false);
+        }
     }
 
     // called by onCreate; this is subclassed to overwrite WallpaperCropActivity
@@ -376,6 +368,9 @@
         mCropView = (CropView) findViewById(R.id.cropView);
         mCropView.setVisibility(View.INVISIBLE);
 
+        mProgressView = findViewById(R.id.loading);
+
+
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
         mCropView.setTouchCallback(new CropView.TouchCallback() {
             ViewPropertyAnimator mAnim;
@@ -500,10 +495,9 @@
         if (lastPhoto != null) {
             ImageView galleryThumbnailBg =
                     (ImageView) pickImageTile.findViewById(R.id.wallpaper_image);
-            galleryThumbnailBg.setImageBitmap(getThumbnailOfLastPhoto());
+            galleryThumbnailBg.setImageBitmap(lastPhoto);
             int colorOverlay = getResources().getColor(R.color.wallpaper_picker_translucent_gray);
             galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP);
-
         }
 
         PickImageInfo pickImageInfo = new PickImageInfo();
@@ -812,7 +806,7 @@
         rotatedBounds[0] = Math.abs(rotatedBounds[0]);
         rotatedBounds[1] = Math.abs(rotatedBounds[1]);
 
-        RectF cropRect = WallpaperCropActivity.getMaxCropRect(
+        RectF cropRect = Utils.getMaxCropRect(
                 (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned);
         cropTask.setCropBounds(cropRect);
 
@@ -839,7 +833,7 @@
         new AsyncTask<Void, Bitmap, Bitmap>() {
             protected Bitmap doInBackground(Void...args) {
                 try {
-                    int rotation = WallpaperCropActivity.getRotationFromExif(context, uri);
+                    int rotation = BitmapUtils.getRotationFromExif(context, uri);
                     return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, false);
                 } catch (SecurityException securityException) {
                     if (isDestroyed()) {
@@ -885,25 +879,10 @@
                 Uri uri = data.getData();
                 addTemporaryWallpaperTile(uri, false);
             }
-        } else if (requestCode == PICK_WALLPAPER_THIRD_PARTY_ACTIVITY) {
+        } else if (requestCode == PICK_WALLPAPER_THIRD_PARTY_ACTIVITY && resultCode == RESULT_OK) {
+            // Something was set on the third-party activity.
             setResult(RESULT_OK);
             finish();
-        } else if (requestCode == PICK_LIVE_WALLPAPER) {
-            WallpaperManager wm = WallpaperManager.getInstance(this);
-            final WallpaperInfo oldLiveWallpaper = mLiveWallpaperInfoOnPickerLaunch;
-            final WallpaperInfo clickedWallpaper = mLastClickedLiveWallpaperInfo;
-            WallpaperInfo newLiveWallpaper = wm.getWallpaperInfo();
-            // Try to figure out if a live wallpaper was set;
-            if (newLiveWallpaper != null &&
-                    (oldLiveWallpaper == null
-                            || !oldLiveWallpaper.getComponent()
-                                    .equals(newLiveWallpaper.getComponent())
-                            || clickedWallpaper.getComponent()
-                                    .equals(oldLiveWallpaper.getComponent()))) {
-                // Return if a live wallpaper was set
-                setResult(RESULT_OK);
-                finish();
-            }
         }
     }
 
@@ -1024,7 +1003,7 @@
         } else {
             Resources res = getResources();
             Point defaultThumbSize = getDefaultThumbnailSize(res);
-            int rotation = WallpaperCropActivity.getRotationFromExif(res, resId);
+            int rotation = BitmapUtils.getRotationFromExif(res, resId);
             thumb = createThumbnail(
                     defaultThumbSize, this, null, null, sysRes, resId, rotation, false);
             if (thumb != null) {
@@ -1110,11 +1089,6 @@
         return mSavedImages;
     }
 
-    public void onLiveWallpaperPickerLaunch(WallpaperInfo info) {
-        mLastClickedLiveWallpaperInfo = info;
-        mLiveWallpaperInfoOnPickerLaunch = WallpaperManager.getInstance(this).getWallpaperInfo();
-    }
-
     static class ZeroPaddingDrawable extends LevelListDrawable {
         public ZeroPaddingDrawable(Drawable d) {
             super();
diff --git a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
index 66ece4f..15f97e5 100644
--- a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
+++ b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Canvas;
@@ -28,7 +27,6 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
-import android.os.Build.VERSION_CODES;
 import android.util.Log;
 
 import com.android.gallery3d.common.BitmapUtils;
@@ -148,8 +146,6 @@
 
     private static final String TAG = "BitmapRegionTileSource";
 
-    private static final boolean REUSE_BITMAP =
-            Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
     private static final int GL_SIZE_LIMIT = 2048;
     // This must be no larger than half the size of the GL_SIZE_LIMIT
     // due to decodePreview being allowed to be up to 2x the size of the target
@@ -158,14 +154,14 @@
     public static abstract class BitmapSource {
         private SimpleBitmapRegionDecoder mDecoder;
         private Bitmap mPreview;
-        private int mPreviewSize;
+        private final int mPreviewSize;
         private int mRotation;
         public enum State { NOT_LOADED, LOADED, ERROR_LOADING };
         private State mState = State.NOT_LOADED;
         public BitmapSource(int previewSize) {
-            mPreviewSize = previewSize;
+            mPreviewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
         }
-        public boolean loadInBackground() {
+        public boolean loadInBackground(InBitmapProvider bitmapProvider) {
             ExifInterface ei = new ExifInterface();
             if (readExif(ei)) {
                 Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
@@ -181,15 +177,33 @@
                 int width = mDecoder.getWidth();
                 int height = mDecoder.getHeight();
                 if (mPreviewSize != 0) {
-                    int previewSize = Math.min(mPreviewSize, MAX_PREVIEW_SIZE);
                     BitmapFactory.Options opts = new BitmapFactory.Options();
                     opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
                     opts.inPreferQualityOverSpeed = true;
 
-                    float scale = (float) previewSize / Math.max(width, height);
+                    float scale = (float) mPreviewSize / Math.max(width, height);
                     opts.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
                     opts.inJustDecodeBounds = false;
-                    mPreview = loadPreviewBitmap(opts);
+                    opts.inMutable = true;
+
+                    if (bitmapProvider != null) {
+                        int expectedPixles = (width / opts.inSampleSize) * (height / opts.inSampleSize);
+                        Bitmap reusableBitmap = bitmapProvider.forPixelCount(expectedPixles);
+                        if (reusableBitmap != null) {
+                            // Try loading with reusable bitmap
+                            opts.inBitmap = reusableBitmap;
+                            try {
+                                mPreview = loadPreviewBitmap(opts);
+                            } catch (IllegalArgumentException e) {
+                                Log.d(TAG, "Unable to reusage bitmap", e);
+                                opts.inBitmap = null;
+                                mPreview = null;
+                            }
+                        }
+                    }
+                    if (mPreview == null) {
+                        mPreview = loadPreviewBitmap(opts);
+                    }
                 }
                 mState = State.LOADED;
                 return true;
@@ -208,10 +222,6 @@
             return mPreview;
         }
 
-        public int getPreviewSize() {
-            return mPreviewSize;
-        }
-
         public int getRotation() {
             return mRotation;
         }
@@ -219,6 +229,10 @@
         public abstract boolean readExif(ExifInterface ei);
         public abstract SimpleBitmapRegionDecoder loadBitmapRegionDecoder();
         public abstract Bitmap loadPreviewBitmap(BitmapFactory.Options options);
+
+        public interface InBitmapProvider {
+            Bitmap forPixelCount(int count);
+        }
     }
 
     public static class FilePathBitmapSource extends BitmapSource {
@@ -306,13 +320,13 @@
                 Utils.closeSilently(is);
                 return true;
             } catch (FileNotFoundException e) {
-                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                Log.d("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return false;
             } catch (IOException e) {
-                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                Log.d("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return false;
             } catch (NullPointerException e) {
-                Log.e("BitmapRegionTileSource", "Failed to read EXIF for URI " + mUri, e);
+                Log.d("BitmapRegionTileSource", "Failed to read EXIF for URI " + mUri, e);
                 return false;
             } finally {
                 Utils.closeSilently(is);
@@ -372,11 +386,9 @@
 
     // For use only by getTile
     private Rect mWantRegion = new Rect();
-    private Rect mOverlapRegion = new Rect();
     private BitmapFactory.Options mOptions;
-    private Canvas mCanvas;
 
-    public BitmapRegionTileSource(Context context, BitmapSource source) {
+    public BitmapRegionTileSource(Context context, BitmapSource source, byte[] tempStorage) {
         mTileSize = TiledImageRenderer.suggestedTileSize(context);
         mRotation = source.getRotation();
         mDecoder = source.getBitmapRegionDecoder();
@@ -386,27 +398,26 @@
             mOptions = new BitmapFactory.Options();
             mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
             mOptions.inPreferQualityOverSpeed = true;
-            mOptions.inTempStorage = new byte[16 * 1024];
-            int previewSize = source.getPreviewSize();
-            if (previewSize != 0) {
-                previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
-                // Although this is the same size as the Bitmap that is likely already
-                // loaded, the lifecycle is different and interactions are on a different
-                // thread. Thus to simplify, this source will decode its own bitmap.
-                Bitmap preview = decodePreview(source, previewSize);
-                if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
+            mOptions.inTempStorage = tempStorage;
+
+            Bitmap preview = source.getPreviewBitmap();
+            if (preview != null &&
+                    preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
                     mPreview = new BitmapTexture(preview);
-                } else {
-                    Log.w(TAG, String.format(
-                            "Failed to create preview of apropriate size! "
-                            + " in: %dx%d, out: %dx%d",
-                            mWidth, mHeight,
-                            preview.getWidth(), preview.getHeight()));
-                }
+            } else {
+                Log.w(TAG, String.format(
+                        "Failed to create preview of apropriate size! "
+                        + " in: %dx%d, out: %dx%d",
+                        mWidth, mHeight,
+                        preview.getWidth(), preview.getHeight()));
             }
         }
     }
 
+    public Bitmap getBitmap() {
+        return mPreview instanceof BitmapTexture ? ((BitmapTexture) mPreview).getBitmap() : null;
+    }
+
     @Override
     public int getTileSize() {
         return mTileSize;
@@ -435,10 +446,6 @@
     @Override
     public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
         int tileSize = getTileSize();
-        if (!REUSE_BITMAP) {
-            return getTileWithoutReusingBitmap(level, x, y, tileSize);
-        }
-
         int t = tileSize << level;
         mWantRegion.set(x, y, x + t, y + t);
 
@@ -462,64 +469,4 @@
         }
         return bitmap;
     }
-
-    private Bitmap getTileWithoutReusingBitmap(
-            int level, int x, int y, int tileSize) {
-
-        int t = tileSize << level;
-        mWantRegion.set(x, y, x + t, y + t);
-
-        mOverlapRegion.set(0, 0, mWidth, mHeight);
-
-        mOptions.inSampleSize = (1 << level);
-        Bitmap bitmap = mDecoder.decodeRegion(mOverlapRegion, mOptions);
-
-        if (bitmap == null) {
-            Log.w(TAG, "fail in decoding region");
-        }
-
-        if (mWantRegion.equals(mOverlapRegion)) {
-            return bitmap;
-        }
-
-        Bitmap result = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
-        if (mCanvas == null) {
-            mCanvas = new Canvas();
-        }
-        mCanvas.setBitmap(result);
-        mCanvas.drawBitmap(bitmap,
-                (mOverlapRegion.left - mWantRegion.left) >> level,
-                (mOverlapRegion.top - mWantRegion.top) >> level, null);
-        mCanvas.setBitmap(null);
-        return result;
-    }
-
-    /**
-     * Note that the returned bitmap may have a long edge that's longer
-     * than the targetSize, but it will always be less than 2x the targetSize
-     */
-    private Bitmap decodePreview(BitmapSource source, int targetSize) {
-        Bitmap result = source.getPreviewBitmap();
-        if (result == null) {
-            return null;
-        }
-
-        // We need to resize down if the decoder does not support inSampleSize
-        // or didn't support the specified inSampleSize (some decoders only do powers of 2)
-        float scale = (float) targetSize / (float) (Math.max(result.getWidth(), result.getHeight()));
-
-        if (scale <= 0.5) {
-            result = BitmapUtils.resizeBitmapByScale(result, scale, true);
-        }
-        return ensureGLCompatibleBitmap(result);
-    }
-
-    private static Bitmap ensureGLCompatibleBitmap(Bitmap bitmap) {
-        if (bitmap == null || bitmap.getConfig() != null) {
-            return bitmap;
-        }
-        Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
-        bitmap.recycle();
-        return newBitmap;
-    }
 }
diff --git a/WallpaperPicker/src/com/android/photos/views/BlockingGLTextureView.java b/WallpaperPicker/src/com/android/photos/views/BlockingGLTextureView.java
deleted file mode 100644
index 8a05051..0000000
--- a/WallpaperPicker/src/com/android/photos/views/BlockingGLTextureView.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2013 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.photos.views;
-
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.opengl.GLSurfaceView.Renderer;
-import android.opengl.GLUtils;
-import android.util.Log;
-import android.view.TextureView;
-import android.view.TextureView.SurfaceTextureListener;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * A TextureView that supports blocking rendering for synchronous drawing
- */
-public class BlockingGLTextureView extends TextureView
-        implements SurfaceTextureListener {
-
-    private RenderThread mRenderThread;
-
-    public BlockingGLTextureView(Context context) {
-        super(context);
-        setSurfaceTextureListener(this);
-    }
-
-    public void setRenderer(Renderer renderer) {
-        if (mRenderThread != null) {
-            throw new IllegalArgumentException("Renderer already set");
-        }
-        mRenderThread = new RenderThread(renderer);
-    }
-
-    public void render() {
-        mRenderThread.render();
-    }
-
-    public void destroy() {
-        if (mRenderThread != null) {
-            mRenderThread.finish();
-            mRenderThread = null;
-        }
-    }
-
-    @Override
-    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
-            int height) {
-        mRenderThread.setSurface(surface);
-        mRenderThread.setSize(width, height);
-    }
-
-    @Override
-    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
-            int height) {
-        mRenderThread.setSize(width, height);
-    }
-
-    @Override
-    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
-        if (mRenderThread != null) {
-            mRenderThread.setSurface(null);
-        }
-        return false;
-    }
-
-    @Override
-    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroy();
-        } catch (Throwable t) {
-            // Ignore
-        }
-        super.finalize();
-    }
-
-    /**
-     * An EGL helper class.
-     */
-
-    private static class EglHelper {
-        private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
-        private static final int EGL_OPENGL_ES2_BIT = 4;
-
-        EGL10 mEgl;
-        EGLDisplay mEglDisplay;
-        EGLSurface mEglSurface;
-        EGLConfig mEglConfig;
-        EGLContext mEglContext;
-
-        private EGLConfig chooseEglConfig() {
-            int[] configsCount = new int[1];
-            EGLConfig[] configs = new EGLConfig[1];
-            int[] configSpec = getConfig();
-            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
-                throw new IllegalArgumentException("eglChooseConfig failed " +
-                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
-            } else if (configsCount[0] > 0) {
-                return configs[0];
-            }
-            return null;
-        }
-
-        private static int[] getConfig() {
-            return new int[] {
-                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-                    EGL10.EGL_RED_SIZE, 8,
-                    EGL10.EGL_GREEN_SIZE, 8,
-                    EGL10.EGL_BLUE_SIZE, 8,
-                    EGL10.EGL_ALPHA_SIZE, 8,
-                    EGL10.EGL_DEPTH_SIZE, 0,
-                    EGL10.EGL_STENCIL_SIZE, 0,
-                    EGL10.EGL_NONE
-            };
-        }
-
-        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
-            int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
-            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attribList);
-        }
-
-        /**
-         * Initialize EGL for a given configuration spec.
-         */
-        public void start() {
-            /*
-             * Get an EGL instance
-             */
-            mEgl = (EGL10) EGLContext.getEGL();
-
-            /*
-             * Get to the default display.
-             */
-            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
-            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
-                throw new RuntimeException("eglGetDisplay failed");
-            }
-
-            /*
-             * We can now initialize EGL for that display
-             */
-            int[] version = new int[2];
-            if (!mEgl.eglInitialize(mEglDisplay, version)) {
-                throw new RuntimeException("eglInitialize failed");
-            }
-            mEglConfig = chooseEglConfig();
-
-            /*
-            * Create an EGL context. We want to do this as rarely as we can, because an
-            * EGL context is a somewhat heavy object.
-            */
-            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
-
-            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
-                mEglContext = null;
-                throwEglException("createContext");
-            }
-
-            mEglSurface = null;
-        }
-
-        /**
-         * Create an egl surface for the current SurfaceTexture surface. If a surface
-         * already exists, destroy it before creating the new surface.
-         *
-         * @return true if the surface was created successfully.
-         */
-        public boolean createSurface(SurfaceTexture surface) {
-            /*
-             * Check preconditions.
-             */
-            if (mEgl == null) {
-                throw new RuntimeException("egl not initialized");
-            }
-            if (mEglDisplay == null) {
-                throw new RuntimeException("eglDisplay not initialized");
-            }
-            if (mEglConfig == null) {
-                throw new RuntimeException("mEglConfig not initialized");
-            }
-
-            /*
-             *  The window size has changed, so we need to create a new
-             *  surface.
-             */
-            destroySurfaceImp();
-
-            /*
-             * Create an EGL surface we can render into.
-             */
-            if (surface != null) {
-                mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surface, null);
-            } else {
-                mEglSurface = null;
-            }
-
-            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
-                int error = mEgl.eglGetError();
-                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
-                    Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
-                }
-                return false;
-            }
-
-            /*
-             * Before we can issue GL commands, we need to make sure
-             * the context is current and bound to a surface.
-             */
-            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-                /*
-                 * Could not make the context current, probably because the underlying
-                 * SurfaceView surface has been destroyed.
-                 */
-                logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
-                return false;
-            }
-
-            return true;
-        }
-
-        /**
-         * Create a GL object for the current EGL context.
-         */
-        public GL10 createGL() {
-            return (GL10) mEglContext.getGL();
-        }
-
-        /**
-         * Display the current render surface.
-         * @return the EGL error code from eglSwapBuffers.
-         */
-        public int swap() {
-            if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
-                return mEgl.eglGetError();
-            }
-            return EGL10.EGL_SUCCESS;
-        }
-
-        public void destroySurface() {
-            destroySurfaceImp();
-        }
-
-        private void destroySurfaceImp() {
-            if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
-                mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
-                        EGL10.EGL_NO_SURFACE,
-                        EGL10.EGL_NO_CONTEXT);
-                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
-                mEglSurface = null;
-            }
-        }
-
-        public void finish() {
-            if (mEglContext != null) {
-                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
-                mEglContext = null;
-            }
-            if (mEglDisplay != null) {
-                mEgl.eglTerminate(mEglDisplay);
-                mEglDisplay = null;
-            }
-        }
-
-        private void throwEglException(String function) {
-            throwEglException(function, mEgl.eglGetError());
-        }
-
-        public static void throwEglException(String function, int error) {
-            String message = formatEglError(function, error);
-            throw new RuntimeException(message);
-        }
-
-        public static void logEglErrorAsWarning(String tag, String function, int error) {
-            Log.w(tag, formatEglError(function, error));
-        }
-
-        public static String formatEglError(String function, int error) {
-            return function + " failed: " + error;
-        }
-
-    }
-
-    private static class RenderThread extends Thread {
-        private static final int INVALID = -1;
-        private static final int RENDER = 1;
-        private static final int CHANGE_SURFACE = 2;
-        private static final int RESIZE_SURFACE = 3;
-        private static final int FINISH = 4;
-
-        private EglHelper mEglHelper = new EglHelper();
-
-        private Object mLock = new Object();
-        private int mExecMsgId = INVALID;
-        private SurfaceTexture mSurface;
-        private Renderer mRenderer;
-        private int mWidth, mHeight;
-
-        private boolean mFinished = false;
-        private GL10 mGL;
-
-        public RenderThread(Renderer renderer) {
-            super("RenderThread");
-            mRenderer = renderer;
-            start();
-        }
-
-        private void checkRenderer() {
-            if (mRenderer == null) {
-                throw new IllegalArgumentException("Renderer is null!");
-            }
-        }
-
-        private void checkSurface() {
-            if (mSurface == null) {
-                throw new IllegalArgumentException("surface is null!");
-            }
-        }
-
-        public void setSurface(SurfaceTexture surface) {
-            // If the surface is null we're being torn down, don't need a
-            // renderer then
-            if (surface != null) {
-                checkRenderer();
-            }
-            mSurface = surface;
-            exec(CHANGE_SURFACE);
-        }
-
-        public void setSize(int width, int height) {
-            checkRenderer();
-            checkSurface();
-            mWidth = width;
-            mHeight = height;
-            exec(RESIZE_SURFACE);
-        }
-
-        public void render() {
-            checkRenderer();
-            if (mSurface != null) {
-                exec(RENDER);
-                mSurface.updateTexImage();
-            }
-        }
-
-        public void finish() {
-            mSurface = null;
-            exec(FINISH);
-            try {
-                join();
-            } catch (InterruptedException e) {
-                // Ignore
-            }
-        }
-
-        private void exec(int msgid) {
-            synchronized (mLock) {
-                if (mExecMsgId != INVALID) {
-                    throw new IllegalArgumentException(
-                            "Message already set - multithreaded access?");
-                }
-                mExecMsgId = msgid;
-                mLock.notify();
-                try {
-                    mLock.wait();
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-        }
-
-        private void handleMessageLocked(int what) {
-            switch (what) {
-            case CHANGE_SURFACE:
-                if (mEglHelper.createSurface(mSurface)) {
-                    mGL = mEglHelper.createGL();
-                    mRenderer.onSurfaceCreated(mGL, mEglHelper.mEglConfig);
-                }
-                break;
-            case RESIZE_SURFACE:
-                mRenderer.onSurfaceChanged(mGL, mWidth, mHeight);
-                break;
-            case RENDER:
-                mRenderer.onDrawFrame(mGL);
-                mEglHelper.swap();
-                break;
-            case FINISH:
-                mEglHelper.destroySurface();
-                mEglHelper.finish();
-                mFinished = true;
-                break;
-            }
-        }
-
-        @Override
-        public void run() {
-            synchronized (mLock) {
-                mEglHelper.start();
-                while (!mFinished) {
-                    while (mExecMsgId == INVALID) {
-                        try {
-                            mLock.wait();
-                        } catch (InterruptedException e) {
-                            // Ignore
-                        }
-                    }
-                    handleMessageLocked(mExecMsgId);
-                    mExecMsgId = INVALID;
-                    mLock.notify();
-                }
-                mExecMsgId = FINISH;
-            }
-        }
-    }
-}
diff --git a/WallpaperPicker/src/android/util/Pools.java b/WallpaperPicker/src/com/android/photos/views/Pools.java
similarity index 98%
rename from WallpaperPicker/src/android/util/Pools.java
rename to WallpaperPicker/src/com/android/photos/views/Pools.java
index 40bab1e..c60f2f0 100644
--- a/WallpaperPicker/src/android/util/Pools.java
+++ b/WallpaperPicker/src/com/android/photos/views/Pools.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.util;
+package com.android.photos.views;
 
 /**
  * Helper class for crating pools of objects. An example use looks like this:
diff --git a/WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java b/WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java
index c4e493b..f9b7ab4 100644
--- a/WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java
+++ b/WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java
@@ -20,11 +20,9 @@
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.support.v4.util.LongSparseArray;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.Pools.Pool;
-import android.util.Pools.SynchronizedPool;
+import android.util.LongSparseArray;
 import android.view.View;
 import android.view.WindowManager;
 
@@ -32,6 +30,8 @@
 import com.android.gallery3d.glrenderer.BasicTexture;
 import com.android.gallery3d.glrenderer.GLCanvas;
 import com.android.gallery3d.glrenderer.UploadedTexture;
+import com.android.photos.views.Pools.Pool;
+import com.android.photos.views.Pools.SynchronizedPool;
 
 /**
  * Handles laying out, decoding, and drawing of tiles in GL
diff --git a/WallpaperPicker/src/com/android/photos/views/TiledImageView.java b/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
index 94063b0..56ee7a6 100644
--- a/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
+++ b/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
@@ -16,8 +16,6 @@
 
 package com.android.photos.views;
 
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -28,11 +26,9 @@
 import android.graphics.RectF;
 import android.opengl.GLSurfaceView;
 import android.opengl.GLSurfaceView.Renderer;
-import android.os.Build;
 import android.util.AttributeSet;
 import android.view.Choreographer;
 import android.view.Choreographer.FrameCallback;
-import android.view.View;
 import android.widget.FrameLayout;
 
 import com.android.gallery3d.glrenderer.BasicTexture;
@@ -43,18 +39,10 @@
 import javax.microedition.khronos.opengles.GL10;
 
 /**
- * Shows an image using {@link TiledImageRenderer} using either {@link GLSurfaceView}
- * or {@link BlockingGLTextureView}.
+ * Shows an image using {@link TiledImageRenderer} using either {@link GLSurfaceView}.
  */
 public class TiledImageView extends FrameLayout {
 
-    private static final boolean USE_TEXTURE_VIEW = false;
-    private static final boolean IS_SUPPORTED =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
-    private static final boolean USE_CHOREOGRAPHER =
-            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
-
-    private BlockingGLTextureView mTextureView;
     private GLSurfaceView mGLSurfaceView;
     private boolean mInvalPending = false;
     private FrameCallback mFrameCallback;
@@ -79,35 +67,19 @@
     protected Object mLock = new Object();
     protected ImageRendererWrapper mRenderer;
 
-    public static boolean isTilingSupported() {
-        return IS_SUPPORTED;
-    }
-
     public TiledImageView(Context context) {
         this(context, null);
     }
 
     public TiledImageView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        if (!IS_SUPPORTED) {
-            return;
-        }
-
         mRenderer = new ImageRendererWrapper();
         mRenderer.image = new TiledImageRenderer(this);
-        View view;
-        if (USE_TEXTURE_VIEW) {
-            mTextureView = new BlockingGLTextureView(context);
-            mTextureView.setRenderer(new TileRenderer());
-            view = mTextureView;
-        } else {
-            mGLSurfaceView = new GLSurfaceView(context);
-            mGLSurfaceView.setEGLContextClientVersion(2);
-            mGLSurfaceView.setRenderer(new TileRenderer());
-            mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
-            view = mGLSurfaceView;
-        }
-        addView(view, new LayoutParams(
+        mGLSurfaceView = new GLSurfaceView(context);
+        mGLSurfaceView.setEGLContextClientVersion(2);
+        mGLSurfaceView.setRenderer(new TileRenderer());
+        mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+        addView(mGLSurfaceView, new LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
         //setTileSource(new ColoredTiles());
     }
@@ -117,22 +89,11 @@
         super.setVisibility(visibility);
         // need to update inner view's visibility because it seems like we're causing it to draw
         // from {@link #dispatchDraw} or {@link #invalidate} even if we are invisible.
-        if (USE_TEXTURE_VIEW) {
-            mTextureView.setVisibility(visibility);
-        } else {
-            mGLSurfaceView.setVisibility(visibility);
-        }
+        mGLSurfaceView.setVisibility(visibility);
     }
 
     public void destroy() {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        if (USE_TEXTURE_VIEW) {
-            mTextureView.destroy();
-        } else {
-            mGLSurfaceView.queueEvent(mFreeTextures);
-        }
+        mGLSurfaceView.queueEvent(mFreeTextures);
     }
 
     private Runnable mFreeTextures = new Runnable() {
@@ -144,27 +105,14 @@
     };
 
     public void onPause() {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        if (!USE_TEXTURE_VIEW) {
-            mGLSurfaceView.onPause();
-        }
+        mGLSurfaceView.onPause();
     }
 
     public void onResume() {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        if (!USE_TEXTURE_VIEW) {
-            mGLSurfaceView.onResume();
-        }
+        mGLSurfaceView.onResume();
     }
 
     public void setTileSource(TileSource source, Runnable isReadyCallback) {
-        if (!IS_SUPPORTED) {
-            return;
-        }
         synchronized (mLock) {
             mRenderer.source = source;
             mRenderer.isReadyCallback = isReadyCallback;
@@ -177,13 +125,14 @@
         invalidate();
     }
 
+    public TileSource getTileSource() {
+        return mRenderer.source;
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right,
             int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        if (!IS_SUPPORTED) {
-            return;
-        }
         synchronized (mLock) {
             updateScaleIfNecessaryLocked(mRenderer);
         }
@@ -200,43 +149,10 @@
     }
 
     @Override
-    protected void dispatchDraw(Canvas canvas) {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        if (USE_TEXTURE_VIEW) {
-            mTextureView.render();
-        }
-        super.dispatchDraw(canvas);
-    }
-
-    @SuppressLint("NewApi")
-    @Override
-    public void setTranslationX(float translationX) {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        super.setTranslationX(translationX);
-    }
-
-    @Override
     public void invalidate() {
-        if (!IS_SUPPORTED) {
-            return;
-        }
-        if (USE_TEXTURE_VIEW) {
-            super.invalidate();
-            mTextureView.invalidate();
-        } else {
-            if (USE_CHOREOGRAPHER) {
-                invalOnVsync();
-            } else {
-                mGLSurfaceView.requestRender();
-            }
-        }
+        invalOnVsync();
     }
 
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     private void invalOnVsync() {
         if (!mInvalPending) {
             mInvalPending = true;
@@ -255,9 +171,6 @@
 
     private RectF mTempRectF = new RectF();
     public void positionFromMatrix(Matrix matrix) {
-        if (!IS_SUPPORTED) {
-            return;
-        }
         if (mRenderer.source != null) {
             final int rotation = mRenderer.source.getRotation();
             final boolean swap = !(rotation % 180 == 0);
diff --git a/protos/backup.proto b/protos/backup.proto
index 44c4b09..09330ee 100644
--- a/protos/backup.proto
+++ b/protos/backup.proto
@@ -72,6 +72,17 @@
 }
 
 message Favorite {
+  // Type of the app, this target represents
+  enum TargetType {
+    TARGET_NONE = 0;
+    TARGET_PHONE = 1;
+    TARGET_MESSENGER = 2;
+    TARGET_EMAIL = 3;
+    TARGET_BROWSER = 4;
+    TARGET_GALLERY = 5;
+    TARGET_CAMERA = 6;
+  }
+
   required int64 id = 1;
   required int32 itemType = 2;
   optional string title = 3;
@@ -90,6 +101,7 @@
   optional string iconPackage = 16;
   optional string iconResource = 17;
   optional bytes icon = 18;
+  optional TargetType targetType = 19 [default = TARGET_NONE];
  }
 
 message Screen {
diff --git a/res/xml/app_target_browser.xml b/res/xml/app_target_browser.xml
new file mode 100644
index 0000000..d7c3ed5
--- /dev/null
+++ b/res/xml/app_target_browser.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+    <favorite launcher:uri="http://www.example.com/" />
+
+</resolve>
\ No newline at end of file
diff --git a/res/xml/app_target_camera.xml b/res/xml/app_target_camera.xml
new file mode 100644
index 0000000..f65a2b1
--- /dev/null
+++ b/res/xml/app_target_camera.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+    <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+
+</resolve>
\ No newline at end of file
diff --git a/res/xml/app_target_email.xml b/res/xml/app_target_email.xml
new file mode 100644
index 0000000..44f0a40
--- /dev/null
+++ b/res/xml/app_target_email.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+    <favorite launcher:uri="mailto:" />
+
+</resolve>
\ No newline at end of file
diff --git a/res/xml/app_target_gallery.xml b/res/xml/app_target_gallery.xml
new file mode 100644
index 0000000..c9d3492
--- /dev/null
+++ b/res/xml/app_target_gallery.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+    <favorite launcher:uri="#Intent;type=images/*;end" />
+
+</resolve>
\ No newline at end of file
diff --git a/res/xml/app_target_messenger.xml b/res/xml/app_target_messenger.xml
new file mode 100644
index 0000000..278eb5c
--- /dev/null
+++ b/res/xml/app_target_messenger.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+    <favorite launcher:uri="sms:" />
+    <favorite launcher:uri="smsto:" />
+    <favorite launcher:uri="mms:" />
+    <favorite launcher:uri="mmsto:" />
+
+</resolve>
\ No newline at end of file
diff --git a/res/xml/app_target_phone.xml b/res/xml/app_target_phone.xml
new file mode 100644
index 0000000..5d6ca31
--- /dev/null
+++ b/res/xml/app_target_phone.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<resolve xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+    <favorite launcher:uri="tel:123" />
+    <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+
+</resolve>
\ No newline at end of file
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 3820660..908bd3d 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -116,7 +116,7 @@
 
     private final Context mContext;
     private final AppWidgetHost mAppWidgetHost;
-    private final LayoutParserCallback mCallback;
+    protected final LayoutParserCallback mCallback;
 
     protected final PackageManager mPackageManager;
     protected final Resources mSourceRes;
@@ -126,13 +126,20 @@
 
     private final long[] mTemp = new long[2];
     private final ContentValues mValues;
-    private final String mRootTag;
+    protected final String mRootTag;
 
     protected SQLiteDatabase mDb;
 
     public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost,
             LayoutParserCallback callback, Resources res,
             int layoutId, String rootTag) {
+        this(context, appWidgetHost, callback, res, layoutId, rootTag,
+                LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile().hotseatAllAppsRank);
+    }
+
+    public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost,
+            LayoutParserCallback callback, Resources res,
+            int layoutId, String rootTag, int hotseatAllAppsRank) {
         mContext = context;
         mAppWidgetHost = appWidgetHost;
         mCallback = callback;
@@ -143,8 +150,7 @@
 
         mSourceRes = res;
         mLayoutId = layoutId;
-        mHotseatAllAppsRank = LauncherAppState.getInstance()
-                .getDynamicGrid().getDeviceProfile().hotseatAllAppsRank;
+        mHotseatAllAppsRank = hotseatAllAppsRank;
     }
 
     /**
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index e6865b2..72e2891 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -578,11 +578,11 @@
         mInterceptTouchListener = listener;
     }
 
-    int getCountX() {
+    public int getCountX() {
         return mCountX;
     }
 
-    int getCountY() {
+    public int getCountY() {
         return mCountY;
     }
 
diff --git a/src/com/android/launcher3/CommonAppTypeParser.java b/src/com/android/launcher3/CommonAppTypeParser.java
new file mode 100644
index 0000000..fe2fbd7
--- /dev/null
+++ b/src/com/android/launcher3/CommonAppTypeParser.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.XmlResourceParser;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.backup.BackupProtos.Favorite;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * A class that parses content values corresponding to some common app types.
+ */
+public class CommonAppTypeParser implements LayoutParserCallback {
+    private static final String TAG = "CommonAppTypeParser";
+
+    // Including TARGET_NONE
+    public static final int SUPPORTED_TYPE_COUNT = 7;
+
+    private static final int RESTORE_FLAG_BIT_SHIFT = 4;
+
+
+    private final long mItemId;
+    private final int mResId;
+    private final Context mContext;
+
+    ContentValues parsedValues;
+    Intent parsedIntent;
+    String parsedTitle;
+
+    public CommonAppTypeParser(long itemId, int itemType, Context context) {
+        mItemId = itemId;
+        mContext = context;
+        mResId = getResourceForItemType(itemType);
+    }
+
+    @Override
+    public long generateNewItemId() {
+        return mItemId;
+    }
+
+    @Override
+    public long insertAndCheck(SQLiteDatabase db, ContentValues values) {
+        parsedValues = values;
+
+        // Remove unwanted values
+        values.put(Favorites.ICON_TYPE, (Integer) null);
+        values.put(Favorites.ICON_PACKAGE, (String) null);
+        values.put(Favorites.ICON_RESOURCE, (String) null);
+        values.put(Favorites.ICON, (byte[]) null);
+        return 1;
+    }
+
+    /**
+     * Tries to find a suitable app to the provided app type.
+     */
+    public boolean findDefaultApp() {
+        if (mResId == 0) {
+            return false;
+        }
+
+        parsedIntent = null;
+        parsedValues = null;
+        new MyLayoutParser().parseValues();
+        return (parsedValues != null) && (parsedIntent != null);
+    }
+
+    private class MyLayoutParser extends DefaultLayoutParser {
+
+        public MyLayoutParser() {
+            super(mContext, null, CommonAppTypeParser.this,
+                    mContext.getResources(), mResId, TAG_RESOLVE, 0);
+        }
+
+        @Override
+        protected long addShortcut(String title, Intent intent, int type) {
+            if (type == Favorites.ITEM_TYPE_APPLICATION) {
+                parsedIntent = intent;
+                parsedTitle = title;
+            }
+            return super.addShortcut(title, intent, type);
+        }
+
+        public void parseValues() {
+            XmlResourceParser parser = mSourceRes.getXml(mLayoutId);
+            try {
+                beginDocument(parser, mRootTag);
+                new ResolveParser().parseAndAdd(parser);
+            } catch (IOException | XmlPullParserException e) {
+                Log.e(TAG, "Unable to parse default app info", e);
+            }
+            parser.close();
+        }
+    }
+
+    public static int getResourceForItemType(int type) {
+        switch (type) {
+            case Favorite.TARGET_PHONE:
+                return R.xml.app_target_phone;
+
+            case Favorite.TARGET_MESSENGER:
+                return R.xml.app_target_messenger;
+
+            case Favorite.TARGET_EMAIL:
+                return R.xml.app_target_email;
+
+            case Favorite.TARGET_BROWSER:
+                return R.xml.app_target_browser;
+
+            case Favorite.TARGET_GALLERY:
+                return R.xml.app_target_gallery;
+
+            case Favorite.TARGET_CAMERA:
+                return R.xml.app_target_camera;
+
+            default:
+                return 0;
+        }
+    }
+
+    public static int encodeItemTypeToFlag(int itemType) {
+        return itemType << RESTORE_FLAG_BIT_SHIFT;
+    }
+
+    public static int decodeItemTypeFromFlag(int flag) {
+        return (flag & ShortcutInfo.FLAG_RESTORED_APP_TYPE) >> RESTORE_FLAG_BIT_SHIFT;
+    }
+
+}
diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java
index 986ae81..6c3008b 100644
--- a/src/com/android/launcher3/DefaultLayoutParser.java
+++ b/src/com/android/launcher3/DefaultLayoutParser.java
@@ -28,15 +28,15 @@
 public class DefaultLayoutParser extends AutoInstallsLayout {
     private static final String TAG = "DefaultLayoutParser";
 
-    private static final String TAG_RESOLVE = "resolve";
+    protected static final String TAG_RESOLVE = "resolve";
     private static final String TAG_FAVORITES = "favorites";
-    private static final String TAG_FAVORITE = "favorite";
+    protected static final String TAG_FAVORITE = "favorite";
     private static final String TAG_APPWIDGET = "appwidget";
     private static final String TAG_SHORTCUT = "shortcut";
     private static final String TAG_FOLDER = "folder";
     private static final String TAG_PARTNER_FOLDER = "partner-folder";
 
-    private static final String ATTR_URI = "uri";
+    protected static final String ATTR_URI = "uri";
     private static final String ATTR_CONTAINER = "container";
     private static final String ATTR_SCREEN = "screen";
     private static final String ATTR_FOLDER_ITEMS = "folderItems";
@@ -44,7 +44,12 @@
     public DefaultLayoutParser(Context context, AppWidgetHost appWidgetHost,
             LayoutParserCallback callback, Resources sourceRes, int layoutId) {
         super(context, appWidgetHost, callback, sourceRes, layoutId, TAG_FAVORITES);
-        Log.e(TAG, "Default layout parser initialized");
+    }
+
+    public DefaultLayoutParser(Context context, AppWidgetHost appWidgetHost,
+            LayoutParserCallback callback, Resources sourceRes, int layoutId, String rootTag,
+            int hotseatAllAppsRank) {
+        super(context, appWidgetHost, callback, sourceRes, layoutId, rootTag, hotseatAllAppsRank);
     }
 
     @Override
@@ -196,7 +201,7 @@
     /**
      * Contains a list of <favorite> nodes, and accepts the first successfully parsed node.
      */
-    private class ResolveParser implements TagParser {
+    protected class ResolveParser implements TagParser {
 
         private final AppShortcutWithUriParser mChildParser = new AppShortcutWithUriParser();
 
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index e607047..c02d73c 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 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.
@@ -17,20 +17,20 @@
 package com.android.launcher3;
 
 import android.content.res.Configuration;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ScrollView;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import com.android.launcher3.util.FocusLogic;
 
 /**
  * A keyboard listener we set on all the workspace icons.
  */
 class IconKeyEventListener implements View.OnKeyListener {
+    @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         return FocusHelper.handleIconKeyEvent(v, keyCode, event);
     }
@@ -40,6 +40,7 @@
  * A keyboard listener we set on all the workspace icons.
  */
 class FolderKeyEventListener implements View.OnKeyListener {
+    @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         return FocusHelper.handleFolderKeyEvent(v, keyCode, event);
     }
@@ -49,14 +50,337 @@
  * A keyboard listener we set on all the hotseat buttons.
  */
 class HotseatIconKeyEventListener implements View.OnKeyListener {
+    @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
-        final Configuration configuration = v.getResources().getConfiguration();
-        return FocusHelper.handleHotseatButtonKeyEvent(v, keyCode, event, configuration.orientation);
+        return FocusHelper.handleHotseatButtonKeyEvent(v, keyCode, event);
     }
 }
 
 public class FocusHelper {
 
+    private static final String TAG = "FocusHelper";
+    private static final boolean DEBUG = false;
+
+    //
+    // Key code handling methods.
+    //
+
+    /**
+     * Handles key events in the all apps screen.
+     */
+    static boolean handleAppsCustomizeKeyEvent(View v, int keyCode, KeyEvent e) {
+        boolean consume = FocusLogic.shouldConsume(keyCode);
+        if (e.getAction() == KeyEvent.ACTION_UP) {
+            return consume;
+        }
+        if (DEBUG) {
+            Log.v(TAG, String.format("Handle ALL APPS keyevent=[%s].",
+                    KeyEvent.keyCodeToString(keyCode)));
+        }
+
+        // Initialize variables.
+        ViewGroup parentLayout;
+        ViewGroup itemContainer;
+        int countX;
+        int countY;
+        if (v.getParent() instanceof ShortcutAndWidgetContainer) {
+            itemContainer = (ViewGroup) v.getParent();
+            parentLayout = (ViewGroup) itemContainer.getParent();
+            countX = ((CellLayout) parentLayout).getCountX();
+            countY = ((CellLayout) parentLayout).getCountY();
+        } else if (v.getParent() instanceof ViewGroup) {
+            itemContainer = parentLayout = (ViewGroup) v.getParent();
+            countX = ((PagedViewGridLayout) parentLayout).getCellCountX();
+            countY = ((PagedViewGridLayout) parentLayout).getCellCountY();
+        } else {
+            throw new IllegalStateException(
+                    "Parent of the focused item inside all apps screen is not a supported type.");
+        }
+        final int iconIndex = itemContainer.indexOfChild(v);
+        final PagedView container = (PagedView) parentLayout.getParent();
+        final int pageIndex = container.indexToPage(container.indexOfChild(parentLayout));
+        final int pageCount = container.getChildCount();
+        ViewGroup newParent = null;
+        View child = null;
+        int[][] matrix = FocusLogic.createFullMatrix(countX, countY, true);
+
+        // Process focus.
+        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX, countY, matrix,
+                iconIndex, pageIndex, pageCount);
+        if (newIconIndex == FocusLogic.NOOP) {
+            return consume;
+        }
+        switch (newIconIndex) {
+            case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
+                newParent = getAppsCustomizePage(container, pageIndex - 1);
+                if (newParent != null) {
+                    container.snapToPage(pageIndex - 1);
+                    child = newParent.getChildAt(0);
+                }
+            case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
+                newParent = getAppsCustomizePage(container, pageIndex - 1);
+                if (newParent != null) {
+                    container.snapToPage(pageIndex - 1);
+                    child = newParent.getChildAt(newParent.getChildCount() - 1);
+                }
+                break;
+            case FocusLogic.NEXT_PAGE_FIRST_ITEM:
+                newParent = getAppsCustomizePage(container, pageIndex + 1);
+                if (newParent != null) {
+                    container.snapToPage(pageIndex + 1);
+                    child = newParent.getChildAt(0);
+                }
+                break;
+            case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
+                child = container.getChildAt(0);
+                break;
+            case FocusLogic.CURRENT_PAGE_LAST_ITEM:
+                child = itemContainer.getChildAt(itemContainer.getChildCount() - 1);
+                break;
+            default: // Go to some item on the current page.
+                child = itemContainer.getChildAt(newIconIndex);
+                break;
+        }
+        if (child != null) {
+            child.requestFocus();
+            playSoundEffect(keyCode, v);
+        }
+        return consume;
+    }
+
+    /**
+     * Handles key events in the workspace hot seat (bottom of the screen).
+     * <p>Currently we don't special case for the phone UI in different orientations, even though
+     * the hotseat is on the side in landscape mode. This is to ensure that accessibility
+     * consistency is maintained across rotations.
+     */
+    static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e) {
+        boolean consume = FocusLogic.shouldConsume(keyCode);
+        if (e.getAction() == KeyEvent.ACTION_UP || !consume) {
+            return consume;
+        }
+        int orientation = v.getResources().getConfiguration().orientation;
+
+        if (DEBUG) {
+            Log.v(TAG, String.format(
+                    "Handle HOTSEAT BUTTONS keyevent=[%s] on hotseat buttons, orientation=%d",
+                    KeyEvent.keyCodeToString(keyCode), orientation));
+        }
+
+        // Initialize the variables.
+        final ShortcutAndWidgetContainer hotseatParent = (ShortcutAndWidgetContainer) v.getParent();
+        final CellLayout hotseatLayout = (CellLayout) hotseatParent.getParent();
+        Workspace workspace = (Workspace) v.getRootView().findViewById(R.id.workspace);
+        int pageIndex = workspace.getCurrentPage();
+        int pageCount = workspace.getChildCount();
+        int countX, countY;
+        int iconIndex = findIndexOfView(hotseatParent, v);
+
+        final CellLayout iconLayout = (CellLayout) workspace.getChildAt(pageIndex);
+        final ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
+
+        ViewGroup parent = null;
+        int[][] matrix;
+
+        if (keyCode == KeyEvent.KEYCODE_DPAD_UP &&
+                orientation == Configuration.ORIENTATION_PORTRAIT) {
+            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout, orientation);
+            // TODO: hotseat indexing should be symmetric.
+            iconIndex += iconParent.getChildCount();
+            countX = iconLayout.getCountX();
+            countY = iconLayout.getCountY() + hotseatLayout.getCountY();
+            parent = iconParent;
+        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
+                orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            matrix = FocusLogic.createSparseMatrix(iconLayout, hotseatLayout, orientation);
+            // TODO: hotseat indexing should be symmetric.
+            iconIndex += iconParent.getChildCount();
+            countX = iconLayout.getCountX() + hotseatLayout.getCountX();
+            countY = iconLayout.getCountY();
+            parent = iconParent;
+        } else {
+            // For other KEYCODE_DPAD_LEFT and KEYCODE_DPAD_RIGHT navigation, do not use the
+            // matrix extended with hotseat.
+            matrix = FocusLogic.createSparseMatrix(hotseatLayout);
+            parent = hotseatParent;
+            countX = hotseatLayout.getCountX();
+            countY = hotseatLayout.getCountY();
+
+        }
+
+        // Process the focus.
+        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX, countY, matrix,
+                iconIndex, pageIndex, pageCount);
+
+        if (iconParent.getChildCount() <= newIconIndex &&
+                newIconIndex < iconParent.getChildCount() + hotseatParent.getChildCount()) {
+            newIconIndex -= iconParent.getChildCount();
+        }
+        if (parent != null) {
+            View newIcon = parent.getChildAt(newIconIndex);
+            if (newIcon != null) {
+                newIcon.requestFocus();
+                playSoundEffect(keyCode, v);
+            }
+        }
+        return consume;
+    }
+
+    /**
+     * Handles key events in a workspace containing icons.
+     */
+    static boolean handleIconKeyEvent(View v, int keyCode, KeyEvent e) {
+        boolean consume = FocusLogic.shouldConsume(keyCode);
+        if (e.getAction() == KeyEvent.ACTION_UP || !consume) {
+            return consume;
+        }
+        int orientation = v.getResources().getConfiguration().orientation;
+        if (DEBUG) {
+            Log.v(TAG, String.format("Handle WORKSPACE ICONS keyevent=[%s] orientation=%d",
+                    KeyEvent.keyCodeToString(keyCode), orientation));
+        }
+
+        // Initialize the variables.
+        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
+        final CellLayout layout = (CellLayout) parent.getParent();
+        final Workspace workspace = (Workspace) layout.getParent();
+        final ViewGroup launcher = (ViewGroup) workspace.getParent();
+        final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.search_drop_target_bar);
+        final ViewGroup hotseat = (ViewGroup) launcher.findViewById(R.id.hotseat);
+        int pageIndex = workspace.indexOfChild(layout);
+        int pageCount = workspace.getChildCount();
+        final int countX = layout.getCountX();
+        int countY = layout.getCountY();
+        final int iconIndex = findIndexOfView(parent, v);
+
+        CellLayout hotseatLayout = (CellLayout) hotseat.getChildAt(0);
+        ShortcutAndWidgetContainer hotseatParent = hotseatLayout.getShortcutsAndWidgets();
+        int[][] matrix;
+
+        // KEYCODE_DPAD_DOWN in portrait (KEYCODE_DPAD_LEFT in landscape) is the only key allowed
+        // to take a user to the hotseat. For other dpad navigation, do not use the matrix extended
+        // with the hotseat.
+        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN &&
+                orientation == Configuration.ORIENTATION_PORTRAIT) {
+            matrix = FocusLogic.createSparseMatrix(layout, hotseatLayout, orientation);
+            countY = countY + 1;
+        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
+                orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            matrix = FocusLogic.createSparseMatrix(layout, hotseatLayout, orientation);
+            countY = countY + 1;
+        } else {
+            matrix = FocusLogic.createSparseMatrix(layout);
+        }
+
+        // Process the focus.
+        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX, countY, matrix,
+                iconIndex, pageIndex, pageCount);
+        View newIcon = null;
+        switch (newIconIndex) {
+            case FocusLogic.NOOP:
+                if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+                    newIcon = tabs;
+                }
+                break;
+            case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
+                parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+                newIcon = parent.getChildAt(0);
+                workspace.snapToPage(pageIndex - 1);
+            case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
+                parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+                newIcon = parent.getChildAt(parent.getChildCount() - 1);
+                workspace.snapToPage(pageIndex - 1);
+                break;
+            case FocusLogic.NEXT_PAGE_FIRST_ITEM:
+                parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
+                newIcon = parent.getChildAt(0);
+                workspace.snapToPage(pageIndex - 1);
+                break;
+            case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
+                newIcon = parent.getChildAt(0);
+                break;
+            case FocusLogic.CURRENT_PAGE_LAST_ITEM:
+                newIcon = parent.getChildAt(parent.getChildCount() - 1);
+                break;
+            default:
+                // current page, some item.
+                if (0 <= newIconIndex && newIconIndex < parent.getChildCount()) {
+                    newIcon = parent.getChildAt(newIconIndex);
+                } else if (parent.getChildCount() <= newIconIndex &&
+                        newIconIndex < parent.getChildCount() + hotseatParent.getChildCount()) {
+                    newIcon = hotseatParent.getChildAt(newIconIndex - parent.getChildCount());
+                }
+                break;
+        }
+        if (newIcon != null) {
+            newIcon.requestFocus();
+            playSoundEffect(keyCode, v);
+        }
+        return consume;
+    }
+
+    /**
+     * Handles key events for items in a Folder.
+     */
+    static boolean handleFolderKeyEvent(View v, int keyCode, KeyEvent e) {
+        boolean consume = FocusLogic.shouldConsume(keyCode);
+        if (e.getAction() == KeyEvent.ACTION_UP || !consume) {
+            return consume;
+        }
+        if (DEBUG) {
+            Log.v(TAG, String.format("Handle FOLDER keyevent=[%s].",
+                    KeyEvent.keyCodeToString(keyCode)));
+        }
+
+        // Initialize the variables.
+        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
+        final CellLayout layout = (CellLayout) parent.getParent();
+        final ScrollView scrollView = (ScrollView) layout.getParent();
+        final Folder folder = (Folder) scrollView.getParent();
+        View title = folder.mFolderName;
+        Workspace workspace = (Workspace) v.getRootView().findViewById(R.id.workspace);
+        final int countX = layout.getCountX();
+        final int countY = layout.getCountY();
+        final int iconIndex = findIndexOfView(parent, v);
+        int pageIndex = workspace.indexOfChild(layout);
+        int pageCount = workspace.getChildCount();
+        int[][] map = FocusLogic.createFullMatrix(countX, countY, true /* incremental order index */
+                );
+
+        // Process the focus.
+        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX, countY, map, iconIndex,
+                pageIndex, pageCount);
+        View newIcon = null;
+        switch (newIconIndex) {
+            case FocusLogic.NOOP:
+                if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+                    newIcon = title;
+                }
+                break;
+            case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
+            case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
+            case FocusLogic.NEXT_PAGE_FIRST_ITEM:
+            case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
+            case FocusLogic.CURRENT_PAGE_LAST_ITEM:
+                if (DEBUG) {
+                    Log.v(TAG, "Page advance handling not supported on folder icons.");
+                }
+                break;
+            default: // current page some item.
+                newIcon = parent.getChildAt(newIconIndex);
+                break;
+        }
+        if (newIcon != null) {
+            newIcon.requestFocus();
+            playSoundEffect(keyCode, v);
+        }
+        return consume;
+    }
+
+    //
+    // Helper methods.
+    //
+
     /**
      * Returns the Viewgroup containing page contents for the page at the index specified.
      */
@@ -70,243 +394,6 @@
     }
 
     /**
-     * Handles key events in a PageViewCellLayout containing PagedViewIcons.
-     */
-    static boolean handleAppsCustomizeKeyEvent(View v, int keyCode, KeyEvent e) {
-        ViewGroup parentLayout;
-        ViewGroup itemContainer;
-        int countX;
-        int countY;
-        if (v.getParent() instanceof ShortcutAndWidgetContainer) {
-            itemContainer = (ViewGroup) v.getParent();
-            parentLayout = (ViewGroup) itemContainer.getParent();
-            countX = ((CellLayout) parentLayout).getCountX();
-            countY = ((CellLayout) parentLayout).getCountY();
-        } else {
-            itemContainer = parentLayout = (ViewGroup) v.getParent();
-            countX = ((PagedViewGridLayout) parentLayout).getCellCountX();
-            countY = ((PagedViewGridLayout) parentLayout).getCellCountY();
-        }
-
-        // Note we have an extra parent because of the
-        // PagedViewCellLayout/PagedViewCellLayoutChildren relationship
-        final PagedView container = (PagedView) parentLayout.getParent();
-        final int iconIndex = itemContainer.indexOfChild(v);
-        final int itemCount = itemContainer.getChildCount();
-        final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parentLayout));
-        final int pageCount = container.getChildCount();
-
-        final int x = iconIndex % countX;
-        final int y = iconIndex / countX;
-
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        ViewGroup newParent = null;
-        // Side pages do not always load synchronously, so check before focusing child siblings
-        // willy-nilly
-        View child = null;
-        boolean wasHandled = false;
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    // Select the previous icon or the last icon on the previous page
-                    if (iconIndex > 0) {
-                        itemContainer.getChildAt(iconIndex - 1).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                    } else {
-                        if (pageIndex > 0) {
-                            newParent = getAppsCustomizePage(container, pageIndex - 1);
-                            if (newParent != null) {
-                                container.snapToPage(pageIndex - 1);
-                                child = newParent.getChildAt(newParent.getChildCount() - 1);
-                                if (child != null) {
-                                    child.requestFocus();
-                                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                                }
-                            }
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    // Select the next icon or the first icon on the next page
-                    if (iconIndex < (itemCount - 1)) {
-                        itemContainer.getChildAt(iconIndex + 1).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                    } else {
-                        if (pageIndex < (pageCount - 1)) {
-                            newParent = getAppsCustomizePage(container, pageIndex + 1);
-                            if (newParent != null) {
-                                container.snapToPage(pageIndex + 1);
-                                child = newParent.getChildAt(0);
-                                if (child != null) {
-                                    child.requestFocus();
-                                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                                }
-                            }
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the previous row, otherwise select the tab bar
-                    if (y > 0) {
-                        int newiconIndex = ((y - 1) * countX) + x;
-                        itemContainer.getChildAt(newiconIndex).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the next row, otherwise do nothing
-                    if (y < (countY - 1)) {
-                        int newiconIndex = Math.min(itemCount - 1, ((y + 1) * countX) + x);
-                        int newIconY = newiconIndex / countX;
-                        if (newIconY != y) {
-                            itemContainer.getChildAt(newiconIndex).requestFocus();
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_PAGE_UP:
-                if (handleKeyEvent) {
-                    // Select the first icon on the previous page, or the first icon on this page
-                    // if there is no previous page
-                    if (pageIndex > 0) {
-                        newParent = getAppsCustomizePage(container, pageIndex - 1);
-                        if (newParent != null) {
-                            container.snapToPage(pageIndex - 1);
-                            child = newParent.getChildAt(0);
-                            if (child != null) {
-                                child.requestFocus();
-                                v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                            }
-                        }
-                    } else {
-                        itemContainer.getChildAt(0).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_PAGE_DOWN:
-                if (handleKeyEvent) {
-                    // Select the first icon on the next page, or the last icon on this page
-                    // if there is no next page
-                    if (pageIndex < (pageCount - 1)) {
-                        newParent = getAppsCustomizePage(container, pageIndex + 1);
-                        if (newParent != null) {
-                            container.snapToPage(pageIndex + 1);
-                            child = newParent.getChildAt(0);
-                            if (child != null) {
-                                child.requestFocus();
-                                v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                            }
-                        }
-                    } else {
-                        itemContainer.getChildAt(itemCount - 1).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_MOVE_HOME:
-                if (handleKeyEvent) {
-                    // Select the first icon on this page
-                    itemContainer.getChildAt(0).requestFocus();
-                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_MOVE_END:
-                if (handleKeyEvent) {
-                    // Select the last icon on this page
-                    itemContainer.getChildAt(itemCount - 1).requestFocus();
-                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                }
-                wasHandled = true;
-                break;
-            default: break;
-        }
-        return wasHandled;
-    }
-
-    /**
-     * Handles key events in the workspace hotseat (bottom of the screen).
-     */
-    static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) {
-        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
-        final CellLayout layout = (CellLayout) parent.getParent();
-
-        // NOTE: currently we don't special case for the phone UI in different
-        // orientations, even though the hotseat is on the side in landscape mode. This
-        // is to ensure that accessibility consistency is maintained across rotations.
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        boolean wasHandled = false;
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
-                    int myIndex = views.indexOf(v);
-                    // Select the previous button, otherwise do nothing
-                    if (myIndex > 0) {
-                        views.get(myIndex - 1).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
-                    int myIndex = views.indexOf(v);
-                    // Select the next button, otherwise do nothing
-                    if (myIndex < views.size() - 1) {
-                        views.get(myIndex + 1).requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-                if (handleKeyEvent) {
-                    final Workspace workspace = (Workspace)
-                            v.getRootView().findViewById(R.id.workspace);
-                    if (workspace != null) {
-                        int pageIndex = workspace.getCurrentPage();
-                        CellLayout topLayout = (CellLayout) workspace.getChildAt(pageIndex);
-                        ShortcutAndWidgetContainer children = topLayout.getShortcutsAndWidgets();
-                        final View newIcon = getIconInDirection(layout, children, -1, 1);
-                        // Select the first bubble text view in the current page of the workspace
-                        if (newIcon != null) {
-                            newIcon.requestFocus();
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                        } else {
-                            workspace.requestFocus();
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                // Do nothing
-                wasHandled = true;
-                break;
-            default: break;
-        }
-        return wasHandled;
-    }
-
-    /**
      * Private helper method to get the CellLayoutChildren given a CellLayout index.
      */
     private static ShortcutAndWidgetContainer getCellLayoutChildrenForIndex(
@@ -315,359 +402,38 @@
         return parent.getShortcutsAndWidgets();
     }
 
-    /**
-     * Private helper method to sort all the CellLayout children in order of their (x,y) spatially
-     * from top left to bottom right.
-     */
-    private static ArrayList<View> getCellLayoutChildrenSortedSpatially(CellLayout layout,
-            ViewGroup parent) {
-        // First we order each the CellLayout children by their x,y coordinates
-        final int cellCountX = layout.getCountX();
-        final int count = parent.getChildCount();
-        ArrayList<View> views = new ArrayList<View>();
-        for (int j = 0; j < count; ++j) {
-            views.add(parent.getChildAt(j));
-        }
-        Collections.sort(views, new Comparator<View>() {
-            @Override
-            public int compare(View lhs, View rhs) {
-                CellLayout.LayoutParams llp = (CellLayout.LayoutParams) lhs.getLayoutParams();
-                CellLayout.LayoutParams rlp = (CellLayout.LayoutParams) rhs.getLayoutParams();
-                int lvIndex = (llp.cellY * cellCountX) + llp.cellX;
-                int rvIndex = (rlp.cellY * cellCountX) + rlp.cellX;
-                return lvIndex - rvIndex;
-            }
-        });
-        return views;
-    }
-    /**
-     * Private helper method to find the index of the next BubbleTextView or FolderIcon in the 
-     * direction delta.
-     * 
-     * @param delta either -1 or 1 depending on the direction we want to search
-     */
-    private static View findIndexOfIcon(ArrayList<View> views, int i, int delta) {
-        // Then we find the next BubbleTextView offset by delta from i
-        final int count = views.size();
-        int newI = i + delta;
-        while (0 <= newI && newI < count) {
-            View newV = views.get(newI);
-            if (newV instanceof BubbleTextView || newV instanceof FolderIcon) {
-                return newV;
-            }
-            newI += delta;
-        }
-        return null;
-    }
-    private static View getIconInDirection(CellLayout layout, ViewGroup parent, int i,
-            int delta) {
-        final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
-        return findIndexOfIcon(views, i, delta);
-    }
-    private static View getIconInDirection(CellLayout layout, ViewGroup parent, View v,
-            int delta) {
-        final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
-        return findIndexOfIcon(views, views.indexOf(v), delta);
-    }
-    /**
-     * Private helper method to find the next closest BubbleTextView or FolderIcon in the direction 
-     * delta on the next line.
-     * 
-     * @param delta either -1 or 1 depending on the line and direction we want to search
-     */
-    private static View getClosestIconOnLine(CellLayout layout, ViewGroup parent, View v,
-            int lineDelta) {
-        final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
-        final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
-        final int cellCountY = layout.getCountY();
-        final int row = lp.cellY;
-        final int newRow = row + lineDelta;
-        if (0 <= newRow && newRow < cellCountY) {
-            float closestDistance = Float.MAX_VALUE;
-            int closestIndex = -1;
-            int index = views.indexOf(v);
-            int endIndex = (lineDelta < 0) ? -1 : views.size();
-            while (index != endIndex) {
-                View newV = views.get(index);
-                CellLayout.LayoutParams tmpLp = (CellLayout.LayoutParams) newV.getLayoutParams();
-                boolean satisfiesRow = (lineDelta < 0) ? (tmpLp.cellY < row) : (tmpLp.cellY > row);
-                if (satisfiesRow &&
-                        (newV instanceof BubbleTextView || newV instanceof FolderIcon)) {
-                    float tmpDistance = (float) Math.sqrt(Math.pow(tmpLp.cellX - lp.cellX, 2) +
-                            Math.pow(tmpLp.cellY - lp.cellY, 2));
-                    if (tmpDistance < closestDistance) {
-                        closestIndex = index;
-                        closestDistance = tmpDistance;
-                    }
-                }
-                if (index <= endIndex) {
-                    ++index;
-                } else {
-                    --index;
-                }
-            }
-            if (closestIndex > -1) {
-                return views.get(closestIndex);
+    private static int findIndexOfView(ViewGroup parent, View v) {
+        for (int i = 0; i < parent.getChildCount(); i++) {
+            if (v != null && v.equals(parent.getChildAt(i))) {
+                return i;
             }
         }
-        return null;
+        return -1;
     }
 
     /**
-     * Handles key events in a Workspace containing.
+     * Helper method to be used for playing sound effects.
      */
-    static boolean handleIconKeyEvent(View v, int keyCode, KeyEvent e) {
-        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
-        final CellLayout layout = (CellLayout) parent.getParent();
-        final Workspace workspace = (Workspace) layout.getParent();
-        final ViewGroup launcher = (ViewGroup) workspace.getParent();
-        final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.search_drop_target_bar);
-        final ViewGroup hotseat = (ViewGroup) launcher.findViewById(R.id.hotseat);
-        int pageIndex = workspace.indexOfChild(layout);
-        int pageCount = workspace.getChildCount();
-
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        boolean wasHandled = false;
+    private static void playSoundEffect(int keyCode, View v) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    // Select the previous icon or the last icon on the previous page if possible
-                    View newIcon = getIconInDirection(layout, parent, v, -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                    } else {
-                        if (pageIndex > 0) {
-                            parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
-                            newIcon = getIconInDirection(layout, parent,
-                                    parent.getChildCount(), -1);
-                            if (newIcon != null) {
-                                newIcon.requestFocus();
-                            } else {
-                                // Snap to the previous page
-                                workspace.snapToPage(pageIndex - 1);
-                            }
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                        }
-                    }
-                }
-                wasHandled = true;
+                v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
                 break;
             case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    // Select the next icon or the first icon on the next page if possible
-                    View newIcon = getIconInDirection(layout, parent, v, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                    } else {
-                        if (pageIndex < (pageCount - 1)) {
-                            parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
-                            newIcon = getIconInDirection(layout, parent, -1, 1);
-                            if (newIcon != null) {
-                                newIcon.requestFocus();
-                            } else {
-                                // Snap to the next page
-                                workspace.snapToPage(pageIndex + 1);
-                            }
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the previous line, otherwise select the tab bar
-                    View newIcon = getClosestIconOnLine(layout, parent, v, -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        wasHandled = true;
-                    } else {
-                        tabs.requestFocus();
-                    }
-                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                }
+                v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
                 break;
             case KeyEvent.KEYCODE_DPAD_DOWN:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the next line, otherwise select the button bar
-                    View newIcon = getClosestIconOnLine(layout, parent, v, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                        wasHandled = true;
-                    } else if (hotseat != null) {
-                        hotseat.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                    }
-                }
-                break;
-            case KeyEvent.KEYCODE_PAGE_UP:
-                if (handleKeyEvent) {
-                    // Select the first icon on the previous page or the first icon on this page
-                    // if there is no previous page
-                    if (pageIndex > 0) {
-                        parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
-                        View newIcon = getIconInDirection(layout, parent, -1, 1);
-                        if (newIcon != null) {
-                            newIcon.requestFocus();
-                        } else {
-                            // Snap to the previous page
-                            workspace.snapToPage(pageIndex - 1);
-                        }
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    } else {
-                        View newIcon = getIconInDirection(layout, parent, -1, 1);
-                        if (newIcon != null) {
-                            newIcon.requestFocus();
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
             case KeyEvent.KEYCODE_PAGE_DOWN:
-                if (handleKeyEvent) {
-                    // Select the first icon on the next page or the last icon on this page
-                    // if there is no previous page
-                    if (pageIndex < (pageCount - 1)) {
-                        parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
-                        View newIcon = getIconInDirection(layout, parent, -1, 1);
-                        if (newIcon != null) {
-                            newIcon.requestFocus();
-                        } else {
-                            // Snap to the next page
-                            workspace.snapToPage(pageIndex + 1);
-                        }
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                    } else {
-                        View newIcon = getIconInDirection(layout, parent,
-                                parent.getChildCount(), -1);
-                        if (newIcon != null) {
-                            newIcon.requestFocus();
-                            v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_MOVE_HOME:
-                if (handleKeyEvent) {
-                    // Select the first icon on this page
-                    View newIcon = getIconInDirection(layout, parent, -1, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    }
-                }
-                wasHandled = true;
-                break;
             case KeyEvent.KEYCODE_MOVE_END:
-                if (handleKeyEvent) {
-                    // Select the last icon on this page
-                    View newIcon = getIconInDirection(layout, parent,
-                            parent.getChildCount(), -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                    }
-                }
-                wasHandled = true;
-                break;
-            default: break;
-        }
-        return wasHandled;
-    }
-
-    /**
-     * Handles key events for items in a Folder.
-     */
-    static boolean handleFolderKeyEvent(View v, int keyCode, KeyEvent e) {
-        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
-        final CellLayout layout = (CellLayout) parent.getParent();
-        final ScrollView scrollView = (ScrollView) layout.getParent();
-        final Folder folder = (Folder) scrollView.getParent();
-        View title = folder.mFolderName;
-
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        boolean wasHandled = false;
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    // Select the previous icon
-                    View newIcon = getIconInDirection(layout, parent, v, -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    // Select the next icon
-                    View newIcon = getIconInDirection(layout, parent, v, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                    } else {
-                        title.requestFocus();
-                    }
-                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                }
-                wasHandled = true;
+                v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
                 break;
             case KeyEvent.KEYCODE_DPAD_UP:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the previous line
-                    View newIcon = getClosestIconOnLine(layout, parent, v, -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the next line
-                    View newIcon = getClosestIconOnLine(layout, parent, v, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                    } else {
-                        title.requestFocus();
-                    }
-                    v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                }
-                wasHandled = true;
-                break;
+            case KeyEvent.KEYCODE_PAGE_UP:
             case KeyEvent.KEYCODE_MOVE_HOME:
-                if (handleKeyEvent) {
-                    // Select the first icon on this page
-                    View newIcon = getIconInDirection(layout, parent, -1, 1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                    }
-                }
-                wasHandled = true;
+                v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
                 break;
-            case KeyEvent.KEYCODE_MOVE_END:
-                if (handleKeyEvent) {
-                    // Select the last icon on this page
-                    View newIcon = getIconInDirection(layout, parent,
-                            parent.getChildCount(), -1);
-                    if (newIcon != null) {
-                        newIcon.requestFocus();
-                        v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                    }
-                }
-                wasHandled = true;
+            default:
                 break;
-            default: break;
         }
-        return wasHandled;
     }
 }
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 66b6568..6925477 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -21,12 +21,13 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.SystemClock;
-import android.support.v4.widget.AutoScrollHelper;
 import android.text.InputType;
 import android.text.Selection;
 import android.text.Spannable;
@@ -123,8 +124,6 @@
 
     private boolean mDestroyed;
 
-    private AutoScrollHelper mAutoScrollHelper;
-
     private Runnable mDeferredAction;
     private boolean mDeferDropAfterUninstall;
     private boolean mUninstallSuccessful;
@@ -208,7 +207,6 @@
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType() |
                 InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
-        mAutoScrollHelper = new FolderAutoScrollHelper(mScrollView);
     }
 
     private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@@ -700,6 +698,7 @@
         }
     }
 
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public boolean isLayoutRtl() {
         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
     }
@@ -715,29 +714,19 @@
         final MotionEvent translatedEv = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_MOVE, d.x, d.y, 0);
 
-        if (!mAutoScrollHelper.isEnabled()) {
-            mAutoScrollHelper.setEnabled(true);
-        }
-
-        final boolean handled = mAutoScrollHelper.onTouch(this, translatedEv);
         translatedEv.recycle();
-
-        if (handled) {
+        mTargetCell = mContent.findNearestArea(
+                (int) r[0], (int) r[1] + scrollOffset, 1, 1, mTargetCell);
+        if (isLayoutRtl()) {
+            mTargetCell[0] = mContent.getCountX() - mTargetCell[0] - 1;
+        }
+        if (mTargetCell[0] != mPreviousTargetCell[0]
+                || mTargetCell[1] != mPreviousTargetCell[1]) {
             mReorderAlarm.cancelAlarm();
-        } else {
-            mTargetCell = mContent.findNearestArea(
-                    (int) r[0], (int) r[1] + scrollOffset, 1, 1, mTargetCell);
-            if (isLayoutRtl()) {
-                mTargetCell[0] = mContent.getCountX() - mTargetCell[0] - 1;
-            }
-            if (mTargetCell[0] != mPreviousTargetCell[0]
-                    || mTargetCell[1] != mPreviousTargetCell[1]) {
-                mReorderAlarm.cancelAlarm();
-                mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
-                mReorderAlarm.setAlarm(REORDER_DELAY);
-                mPreviousTargetCell[0] = mTargetCell[0];
-                mPreviousTargetCell[1] = mTargetCell[1];
-            }
+            mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
+            mReorderAlarm.setAlarm(REORDER_DELAY);
+            mPreviousTargetCell[0] = mTargetCell[0];
+            mPreviousTargetCell[1] = mTargetCell[1];
         }
     }
 
@@ -783,8 +772,6 @@
     }
 
     public void onDragExit(DragObject d) {
-        // Exiting folder; stop the auto scroller.
-        mAutoScrollHelper.setEnabled(false);
         // We only close the folder if this is a true drag exit, ie. not because
         // a drop has occurred above the folder.
         if (!d.dragComplete) {
diff --git a/src/com/android/launcher3/FolderAutoScrollHelper.java b/src/com/android/launcher3/FolderAutoScrollHelper.java
deleted file mode 100644
index 40e8884..0000000
--- a/src/com/android/launcher3/FolderAutoScrollHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013 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.launcher3;
-
-import android.support.v4.widget.AutoScrollHelper;
-import android.widget.ScrollView;
-
-/**
- * An implementation of {@link AutoScrollHelper} that knows how to scroll
- * through a {@link Folder}.
- */
-public class FolderAutoScrollHelper extends AutoScrollHelper {
-    private static final float MAX_SCROLL_VELOCITY = 1500f;
-
-    private final ScrollView mTarget;
-
-    public FolderAutoScrollHelper(ScrollView target) {
-        super(target);
-
-        mTarget = target;
-
-        setActivationDelay(0);
-        setEdgeType(EDGE_TYPE_INSIDE_EXTEND);
-        setExclusive(true);
-        setMaximumVelocity(MAX_SCROLL_VELOCITY, MAX_SCROLL_VELOCITY);
-        setRampDownDuration(0);
-        setRampUpDuration(0);
-    }
-
-    @Override
-    public void scrollTargetBy(int deltaX, int deltaY) {
-        mTarget.scrollBy(deltaX, deltaY);
-    }
-
-    @Override
-    public boolean canTargetScrollHorizontally(int direction) {
-        // List do not scroll horizontally.
-        return false;
-    }
-
-    @Override
-    public boolean canTargetScrollVertically(int direction) {
-        return mTarget.canScrollVertically(direction);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index b08272f..289b08b 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,14 +16,12 @@
 
 package com.android.launcher3;
 
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -33,7 +31,6 @@
 import java.util.ArrayList;
 
 public class Hotseat extends FrameLayout {
-    private static final String TAG = "Hotseat";
 
     private CellLayout mContent;
 
@@ -182,38 +179,6 @@
         return false;
     }
 
-    void addAllAppsFolder(IconCache iconCache,
-            ArrayList<AppInfo> allApps, ArrayList<ComponentName> onWorkspace,
-            Launcher launcher, Workspace workspace) {
-        if (LauncherAppState.isDisableAllApps()) {
-            FolderInfo fi = new FolderInfo();
-
-            fi.cellX = getCellXFromOrder(mAllAppsButtonRank);
-            fi.cellY = getCellYFromOrder(mAllAppsButtonRank);
-            fi.spanX = 1;
-            fi.spanY = 1;
-            fi.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
-            fi.screenId = mAllAppsButtonRank;
-            fi.itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
-            fi.title = "More Apps";
-            LauncherModel.addItemToDatabase(launcher, fi, fi.container, fi.screenId, fi.cellX,
-                    fi.cellY, false);
-            FolderIcon folder = FolderIcon.fromXml(R.layout.folder_icon, launcher,
-                    getLayout(), fi, iconCache);
-            workspace.addInScreen(folder, fi.container, fi.screenId, fi.cellX, fi.cellY,
-                    fi.spanX, fi.spanY);
-
-            for (AppInfo info: allApps) {
-                ComponentName cn = info.intent.getComponent();
-                if (!onWorkspace.contains(cn)) {
-                    Log.d(TAG, "Adding to 'more apps': " + info.intent);
-                    ShortcutInfo si = info.makeShortcut();
-                    fi.add(si);
-                }
-            }
-        }
-    }
-
     void addAppsToAllAppsFolder(ArrayList<AppInfo> apps) {
         if (LauncherAppState.isDisableAllApps()) {
             View v = mContent.getChildAt(getCellXFromOrder(mAllAppsButtonRank), getCellYFromOrder(mAllAppsButtonRank));
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index cd861d4..58b0854 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -95,6 +95,7 @@
 import android.widget.Advanceable;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.launcher3.DropTarget.DragObject;
@@ -230,8 +231,6 @@
     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
     private static final int ACTIVITY_START_DELAY = 1000;
 
-    private static final Object sLock = new Object();
-
     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();
     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
 
@@ -341,8 +340,6 @@
     // it from the context.
     private SharedPreferences mSharedPrefs;
 
-    private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;
-
     // Holds the page that we need to animate to, and the icon views that we need to animate up
     // when we scroll to that page on resume.
     private ImageView mFolderIconImageView;
@@ -362,6 +359,18 @@
         }
     }
 
+    // TODO: remove this field and call method directly when Launcher3 can depend on M APIs
+    private static Method sClipRevealMethod = null;
+    static {
+        Class<?> activityOptionsClass = ActivityOptions.class;
+        try {
+            sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",
+                    View.class, int.class, int.class, int.class, int.class);
+        } catch (Exception e) {
+            // Earlier version
+        }
+    }
+
     private Runnable mBuildLayersRunnable = new Runnable() {
         public void run() {
             if (mWorkspace != null) {
@@ -1689,40 +1698,19 @@
      * Sets up transparent navigation and status bars in LMP.
      * This method is a no-op for other platform versions.
      */
-    @TargetApi(19)
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     private void setupTransparentSystemBarsForLmp() {
-        // TODO(sansid): use the APIs directly when compiling against L sdk.
-        // Currently we use reflection to access the flags and the API to set the transparency
-        // on the System bars.
         if (Utilities.isLmpOrAbove()) {
-            try {
-                getWindow().getAttributes().systemUiVisibility |=
-                        (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
-                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
-                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
-                Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(
-                        "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");
-                getWindow().addFlags(drawsSysBackgroundsField.getInt(null));
-
-                Method setStatusBarColorMethod =
-                        Window.class.getDeclaredMethod("setStatusBarColor", int.class);
-                Method setNavigationBarColorMethod =
-                        Window.class.getDeclaredMethod("setNavigationBarColor", int.class);
-                setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);
-                setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);
-            } catch (NoSuchFieldException e) {
-                Log.w(TAG, "NoSuchFieldException while setting up transparent bars");
-            } catch (NoSuchMethodException ex) {
-                Log.w(TAG, "NoSuchMethodException while setting up transparent bars");
-            } catch (IllegalAccessException e) {
-                Log.w(TAG, "IllegalAccessException while setting up transparent bars");
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG, "IllegalArgumentException while setting up transparent bars");
-            } catch (InvocationTargetException e) {
-                Log.w(TAG, "InvocationTargetException while setting up transparent bars");
-            } finally {}
+            Window window = getWindow();
+            window.getAttributes().systemUiVisibility |=
+                    (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
+                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            window.setStatusBarColor(Color.TRANSPARENT);
+            window.setNavigationBarColor(Color.TRANSPARENT);
         }
     }
 
@@ -2921,9 +2909,41 @@
 
             Bundle optsBundle = null;
             if (useLaunchAnimation) {
-                ActivityOptions opts = Utilities.isLmpOrAbove() ?
-                        ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :
-                        ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
+                ActivityOptions opts = null;
+                if (sClipRevealMethod != null) {
+                    // TODO: call method directly when Launcher3 can depend on M APIs
+                    int left = 0, top = 0;
+                    int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+                    if (v instanceof TextView) {
+                        // Launch from center of icon, not entire view
+                        TextView tv = (TextView) v;
+                        Drawable[] drawables = tv.getCompoundDrawables();
+                        if (drawables != null && drawables[1] != null) {
+                            Rect bounds = drawables[1].getBounds();
+                            left = (width - bounds.width()) / 2;
+                            top = tv.getPaddingTop();
+                            width = bounds.width();
+                            height = bounds.height();
+                        }
+                    }
+                    try {
+                        opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,
+                                left, top, width, height);
+                    } catch (IllegalAccessException e) {
+                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);
+                        sClipRevealMethod = null;
+                    } catch (InvocationTargetException e) {
+                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);
+                        sClipRevealMethod = null;
+                    }
+                }
+                if (opts == null) {
+                    opts = Utilities.isLmpOrAbove() ?
+                            ActivityOptions.makeCustomAnimation(this,
+                                    R.anim.task_open_enter, R.anim.no_anim) :
+                            ActivityOptions.makeScaleUpAnimation(v, 0, 0,
+                                    v.getMeasuredWidth(), v.getMeasuredHeight());
+                }
                 optsBundle = opts.toBundle();
             }
 
@@ -4487,10 +4507,10 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void finishBindingItems(final boolean upgradePath) {
+    public void finishBindingItems() {
         Runnable r = new Runnable() {
             public void run() {
-                finishBindingItems(upgradePath);
+                finishBindingItems();
             }
         };
         if (waitUntilResume(r)) {
@@ -4525,14 +4545,10 @@
             sPendingAddItem = null;
         }
 
-        if (upgradePath) {
-            mWorkspace.getUniqueComponents(true, null);
-            mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);
-        }
         PackageInstallerCompat.getInstance(this).onFinishBind();
 
         if (mLauncherCallbacks != null) {
-            mLauncherCallbacks.finishBindingItems(upgradePath);
+            mLauncherCallbacks.finishBindingItems(false);
         }
     }
 
@@ -4599,13 +4615,6 @@
      */
     public void bindAllApplications(final ArrayList<AppInfo> apps) {
         if (LauncherAppState.isDisableAllApps()) {
-            if (mIntentsOnWorkspaceFromUpgradePath != null) {
-                if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {
-                    getHotseat().addAllAppsFolder(mIconCache, apps,
-                            mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);
-                }
-                mIntentsOnWorkspaceFromUpgradePath = null;
-            }
             if (mAppsCustomizeContent != null) {
                 mAppsCustomizeContent.onPackagesUpdated(
                         LauncherModel.getSortedWidgetsAndShortcuts(this));
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 32bea5b..353bf3f 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -19,13 +19,16 @@
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupHelper;
 import android.app.backup.BackupManager;
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.XmlResourceParser;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -51,6 +54,9 @@
 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
 import com.google.protobuf.nano.MessageNano;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -58,7 +64,6 @@
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.zip.CRC32;
 
@@ -138,6 +143,7 @@
     private final Context mContext;
     private final HashSet<String> mExistingKeys;
     private final ArrayList<Key> mKeys;
+    private final ItemTypeMatcher[] mItemTypeMatchers;
 
     private IconCache mIconCache;
     private BackupManager mBackupManager;
@@ -154,6 +160,7 @@
         mExistingKeys = new HashSet<String>();
         mKeys = new ArrayList<Key>();
         restoreSuccessful = true;
+        mItemTypeMatchers = new ItemTypeMatcher[CommonAppTypeParser.SUPPORTED_TYPE_COUNT];
     }
 
     private void dataChanged() {
@@ -753,6 +760,17 @@
         return checksum.getValue();
     }
 
+    /**
+     * @return true if its an hotseat item, that can be replaced during restore.
+     * TODO: Extend check for folders in hotseat.
+     */
+    private boolean isReplaceableHotseatItem(Favorite favorite) {
+        return favorite.container == Favorites.CONTAINER_HOTSEAT
+                && favorite.intent != null
+                && (favorite.itemType == Favorites.ITEM_TYPE_APPLICATION
+                || favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT);
+    }
+
     /** Serialize a Favorite for persistence, including a checksum wrapper. */
     private Favorite packFavorite(Cursor c) {
         Favorite favorite = new Favorite();
@@ -785,9 +803,10 @@
             favorite.title = title;
         }
         String intentDescription = c.getString(INTENT_INDEX);
+        Intent intent = null;
         if (!TextUtils.isEmpty(intentDescription)) {
             try {
-                Intent intent = Intent.parseUri(intentDescription, 0);
+                intent = Intent.parseUri(intentDescription, 0);
                 intent.removeExtra(ItemInfo.EXTRA_PROFILE);
                 favorite.intent = intent.toUri(0);
             } catch (URISyntaxException e) {
@@ -803,6 +822,31 @@
             }
         }
 
+        if (isReplaceableHotseatItem(favorite)) {
+            if (intent != null && intent.getComponent() != null) {
+                PackageManager pm = mContext.getPackageManager();
+                ActivityInfo activity = null;;
+                try {
+                    activity = pm.getActivityInfo(intent.getComponent(), 0);
+                } catch (NameNotFoundException e) {
+                    Log.e(TAG, "Target not found", e);
+                }
+                if (activity == null) {
+                    return favorite;
+                }
+                for (int i = 0; i < mItemTypeMatchers.length; i++) {
+                    if (mItemTypeMatchers[i] == null) {
+                        mItemTypeMatchers[i] = new ItemTypeMatcher(
+                                CommonAppTypeParser.getResourceForItemType(i));
+                    }
+                    if (mItemTypeMatchers[i].matches(activity, pm)) {
+                        favorite.targetType = i;
+                        break;
+                    }
+                }
+            }
+        }
+
         return favorite;
     }
 
@@ -810,6 +854,7 @@
     private ContentValues unpackFavorite(byte[] buffer, int dataSize)
             throws IOException {
         Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
+
         ContentValues values = new ContentValues();
         values.put(Favorites._ID, favorite.id);
         values.put(Favorites.SCREEN, favorite.screen);
@@ -860,8 +905,17 @@
                 throw new InvalidBackupException("Widget not in screen bounds, aborting restore");
             }
         } else {
-            // Let LauncherModel know we've been here.
-            values.put(LauncherSettings.Favorites.RESTORED, 1);
+            // Check if it is an hotseat item, that can be replaced.
+            if (isReplaceableHotseatItem(favorite)
+                    && favorite.targetType != Favorite.TARGET_NONE
+                    && favorite.targetType < CommonAppTypeParser.SUPPORTED_TYPE_COUNT) {
+                Log.e(TAG, "Added item type flag");
+                values.put(LauncherSettings.Favorites.RESTORED,
+                        1 | CommonAppTypeParser.encodeItemTypeToFlag(favorite.targetType));
+            } else {
+                // Let LauncherModel know we've been here.
+                values.put(LauncherSettings.Favorites.RESTORED, 1);
+            }
 
             // Verify placement
             if (favorite.container == Favorites.CONTAINER_HOTSEAT) {
@@ -1128,6 +1182,9 @@
     }
 
     private class InvalidBackupException extends IOException {
+
+        private static final long serialVersionUID = 8931456637211665082L;
+
         private InvalidBackupException(Throwable cause) {
             super(cause);
         }
@@ -1136,4 +1193,54 @@
             super(reason);
         }
     }
+
+    /**
+     * A class to check if an activity can handle one of the intents from a list of
+     * predefined intents.
+     */
+    private class ItemTypeMatcher {
+
+        private final ArrayList<Intent> mIntents;
+
+        ItemTypeMatcher(int xml_res) {
+            mIntents = xml_res == 0 ? new ArrayList<Intent>() : parseIntents(xml_res);
+        }
+
+        private ArrayList<Intent> parseIntents(int xml_res) {
+            ArrayList<Intent> intents = new ArrayList<Intent>();
+            XmlResourceParser parser = mContext.getResources().getXml(xml_res);
+            try {
+                DefaultLayoutParser.beginDocument(parser, DefaultLayoutParser.TAG_RESOLVE);
+                final int depth = parser.getDepth();
+                int type;
+                while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                        parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+                    if (type != XmlPullParser.START_TAG) {
+                        continue;
+                    } else if (DefaultLayoutParser.TAG_FAVORITE.equals(parser.getName())) {
+                        final String uri = DefaultLayoutParser.getAttributeValue(
+                                parser, DefaultLayoutParser.ATTR_URI);
+                        intents.add(Intent.parseUri(uri, 0));
+                    }
+                }
+            } catch (URISyntaxException | XmlPullParserException | IOException e) {
+                Log.e(TAG, "Unable to parse " + xml_res, e);
+            } finally {
+                parser.close();
+            }
+            return intents;
+        }
+
+        public boolean matches(ActivityInfo activity, PackageManager pm) {
+            for (Intent intent : mIntents) {
+                intent.setPackage(activity.packageName);
+                ResolveInfo info = pm.resolveActivity(intent, 0);
+                if (info != null && (info.activityInfo.name.equals(activity.name)
+                        || info.activityInfo.name.equals(activity.targetActivity))) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 9f97631..3983835 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -75,7 +75,6 @@
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.TreeMap;
 
 /**
  * Maintains in-memory state of the Launcher. It is expected that there should be only one
@@ -91,9 +90,6 @@
 
     static final String TAG = "Launcher.Model";
 
-    // true = use a "More Apps" folder for non-workspace apps on upgrade
-    // false = strew non-workspace apps across the workspace on upgrade
-    public static final boolean UPGRADE_USE_MORE_APPS_FOLDER = false;
     public static final int LOADER_FLAG_NONE = 0;
     public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0;
     public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1;
@@ -199,7 +195,7 @@
         public void bindScreens(ArrayList<Long> orderedScreenIds);
         public void bindAddScreens(ArrayList<Long> orderedScreenIds);
         public void bindFolders(HashMap<Long,FolderInfo> folders);
-        public void finishBindingItems(boolean upgradePath);
+        public void finishBindingItems();
         public void bindAppWidget(LauncherAppWidgetInfo info);
         public void bindAllApplications(ArrayList<AppInfo> apps);
         public void bindAppsAdded(ArrayList<Long> newScreens,
@@ -491,13 +487,7 @@
         Runnable r = new Runnable() {
             public void run() {
                 final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
-
-                ArrayList<Long> workspaceScreens = new ArrayList<Long>();
-                TreeMap<Integer, Long> orderedScreens = loadWorkspaceScreensDb(context);
-                for (Integer i : orderedScreens.keySet()) {
-                    long screenId = orderedScreens.get(i);
-                    workspaceScreens.add(screenId);
-                }
+                ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context);
 
                 // Find appropriate space for the item.
                 Pair<Long, int[]> coords = findSpaceForItem(context, preferredScreen,
@@ -549,13 +539,7 @@
                 // Get the list of workspace screens.  We need to append to this list and
                 // can not use sBgWorkspaceScreens because loadWorkspace() may not have been
                 // called.
-                ArrayList<Long> workspaceScreens = new ArrayList<Long>();
-                TreeMap<Integer, Long> orderedScreens = loadWorkspaceScreensDb(context);
-                for (Integer i : orderedScreens.keySet()) {
-                    long screenId = orderedScreens.get(i);
-                    workspaceScreens.add(screenId);
-                }
-
+                ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context);
                 synchronized(sBgLock) {
                     for (ItemInfo item : workspaceApps) {
                         if (!allowDuplicate) {
@@ -1443,40 +1427,31 @@
         }
     }
 
-    /** Loads the workspace screens db into a map of Rank -> ScreenId */
-    private static TreeMap<Integer, Long> loadWorkspaceScreensDb(Context context) {
+    /**
+     * Loads the workspace screen ids in an ordered list.
+     */
+    private static ArrayList<Long> loadWorkspaceScreensDb(Context context) {
         final ContentResolver contentResolver = context.getContentResolver();
         final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
-        final Cursor sc = contentResolver.query(screensUri, null, null, null, null);
-        TreeMap<Integer, Long> orderedScreens = new TreeMap<Integer, Long>();
 
+        // Get screens ordered by rank.
+        final Cursor sc = contentResolver.query(screensUri, null, null, null,
+                LauncherSettings.WorkspaceScreens.SCREEN_RANK);
+        ArrayList<Long> screenIds = new ArrayList<Long>();
         try {
-            final int idIndex = sc.getColumnIndexOrThrow(
-                    LauncherSettings.WorkspaceScreens._ID);
-            final int rankIndex = sc.getColumnIndexOrThrow(
-                    LauncherSettings.WorkspaceScreens.SCREEN_RANK);
+            final int idIndex = sc.getColumnIndexOrThrow(LauncherSettings.WorkspaceScreens._ID);
             while (sc.moveToNext()) {
                 try {
-                    long screenId = sc.getLong(idIndex);
-                    int rank = sc.getInt(rankIndex);
-                    orderedScreens.put(rank, screenId);
+                    screenIds.add(sc.getLong(idIndex));
                 } catch (Exception e) {
-                    Launcher.addDumpLog(TAG, "Desktop items loading interrupted - invalid screens: " + e, true);
+                    Launcher.addDumpLog(TAG, "Desktop items loading interrupted"
+                            + " - invalid screens: " + e, true);
                 }
             }
         } finally {
             sc.close();
         }
-
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - loadWorkspaceScreensDb()", true);
-        ArrayList<String> orderedScreensPairs= new ArrayList<String>();
-        for (Integer i : orderedScreens.keySet()) {
-            orderedScreensPairs.add("{ " + i + ": " + orderedScreens.get(i) + " }");
-        }
-        Launcher.addDumpLog(TAG, "11683562 -   screens: " +
-                TextUtils.join(", ", orderedScreensPairs), true);
-        return orderedScreens;
+        return screenIds;
     }
 
     public boolean isAllAppsLoaded() {
@@ -1523,8 +1498,7 @@
             return mIsLoadingAndBindingWorkspace;
         }
 
-        /** Returns whether this is an upgrade path */
-        private boolean loadAndBindWorkspace() {
+        private void loadAndBindWorkspace() {
             mIsLoadingAndBindingWorkspace = true;
 
             // Load the workspace
@@ -1532,20 +1506,18 @@
                 Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded);
             }
 
-            boolean isUpgradePath = false;
             if (!mWorkspaceLoaded) {
-                isUpgradePath = loadWorkspace();
+                loadWorkspace();
                 synchronized (LoaderTask.this) {
                     if (mStopped) {
-                        return isUpgradePath;
+                        return;
                     }
                     mWorkspaceLoaded = true;
                 }
             }
 
             // Bind the workspace
-            bindWorkspace(-1, isUpgradePath);
-            return isUpgradePath;
+            bindWorkspace(-1);
         }
 
         private void waitForIdle() {
@@ -1614,15 +1586,13 @@
 
             // Divide the set of loaded items into those that we are binding synchronously, and
             // everything else that is to be bound normally (asynchronously).
-            bindWorkspace(synchronousBindPage, false);
+            bindWorkspace(synchronousBindPage);
             // XXX: For now, continue posting the binding of AllApps as there are other issues that
             //      arise from that.
             onlyBindAllApps();
         }
 
         public void run() {
-            boolean isUpgrade = false;
-
             synchronized (mLock) {
                 mIsLoaderTaskRunning = true;
             }
@@ -1639,7 +1609,7 @@
                             ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
                 }
                 if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
-                isUpgrade = loadAndBindWorkspace();
+                loadAndBindWorkspace();
 
                 if (mStopped) {
                     break keep_running;
@@ -1677,9 +1647,7 @@
             if (LauncherAppState.isDisableAllApps()) {
                 // Ensure that all the applications that are in the system are
                 // represented on the home screen.
-                if (!UPGRADE_USE_MORE_APPS_FOLDER || !isUpgrade) {
-                    verifyApplications();
-                }
+                verifyApplications();
             }
 
             // Clear out this reference, otherwise we end up holding it until all of the
@@ -1856,8 +1824,7 @@
             }
         }
 
-        /** Returns whether this is an upgrade path */
-        private boolean loadWorkspace() {
+        private void loadWorkspace() {
             // Log to disk
             Launcher.addDumpLog(TAG, "11683562 - loadWorkspace()", true);
 
@@ -1891,12 +1858,6 @@
                 LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary();
             }
 
-            // This code path is for our old migration code and should no longer be exercised
-            boolean loadedOldDb = false;
-
-            // Log to disk
-            Launcher.addDumpLog(TAG, "11683562 -   loadedOldDb: " + loadedOldDb, true);
-
             synchronized (sBgLock) {
                 clearSBgDataStructures();
                 final HashSet<String> installingPkgs = PackageInstallerCompat
@@ -1977,6 +1938,7 @@
                                 user = mUserManager.getUserForSerialNumber(serialNumber);
                                 int promiseType = c.getInt(restoredIndex);
                                 int disabledState = 0;
+                                boolean itemReplaced = false;
                                 if (user == null) {
                                     // User has been deleted remove the item.
                                     itemsToRemove.add(id);
@@ -2008,9 +1970,7 @@
                                                     ContentValues values = new ContentValues();
                                                     values.put(LauncherSettings.Favorites.INTENT,
                                                             intent.toUri(0));
-                                                    String where = BaseColumns._ID + "= ?";
-                                                    String[] args = {Long.toString(id)};
-                                                    contentResolver.update(contentUri, values, where, args);
+                                                    updateItem(id, values);
                                                 }
                                             }
 
@@ -2040,10 +2000,27 @@
                                                 ContentValues values = new ContentValues();
                                                 values.put(LauncherSettings.Favorites.RESTORED,
                                                         promiseType);
-                                                String where = BaseColumns._ID + "= ?";
-                                                String[] args = {Long.toString(id)};
-                                                contentResolver.update(contentUri, values, where, args);
+                                                updateItem(id, values);
+                                            } else if ((promiseType & ShortcutInfo.FLAG_RESTORED_APP_TYPE) != 0) {
+                                                // This is a common app. Try to replace this.
+                                                int appType = CommonAppTypeParser.decodeItemTypeFromFlag(promiseType);
+                                                CommonAppTypeParser parser = new CommonAppTypeParser(id, appType, context);
+                                                if (parser.findDefaultApp()) {
+                                                    // Default app found. Replace it.
+                                                    intent = parser.parsedIntent;
+                                                    cn = intent.getComponent();
+                                                    ContentValues values = parser.parsedValues;
+                                                    values.put(LauncherSettings.Favorites.RESTORED, 0);
+                                                    updateItem(id, values);
+                                                    restored = false;
+                                                    itemReplaced = true;
 
+                                                } else if (REMOVE_UNRESTORED_ICONS) {
+                                                    Launcher.addDumpLog(TAG,
+                                                            "Unrestored package removed: " + cn, true);
+                                                    itemsToRemove.add(id);
+                                                    continue;
+                                                }
                                             } else if (REMOVE_UNRESTORED_ICONS) {
                                                 Launcher.addDumpLog(TAG,
                                                         "Unrestored package removed: " + cn, true);
@@ -2089,7 +2066,16 @@
                                     continue;
                                 }
 
-                                if (restored) {
+                                if (itemReplaced) {
+                                    if (user.equals(UserHandleCompat.myUserHandle())) {
+                                        info = getShortcutInfo(manager, intent, user, context, null,
+                                                iconIndex, titleIndex, mLabelCache, false);
+                                    } else {
+                                        // Don't replace items for other profiles.
+                                        itemsToRemove.add(id);
+                                        continue;
+                                    }
+                                } else if (restored) {
                                     if (user.equals(UserHandleCompat.myUserHandle())) {
                                         Launcher.addDumpLog(TAG,
                                                 "constructing info for partially restored package",
@@ -2323,9 +2309,7 @@
                                                     providerName);
                                             values.put(LauncherSettings.Favorites.RESTORED,
                                                     appWidgetInfo.restoreStatus);
-                                            String where = BaseColumns._ID + "= ?";
-                                            String[] args = {Long.toString(id)};
-                                            contentResolver.update(contentUri, values, where, args);
+                                            updateItem(id, values);
                                         }
                                     }
                                     sBgItemsIdMap.put(appWidgetInfo.id, appWidgetInfo);
@@ -2346,7 +2330,7 @@
                 // Break early if we've stopped loading
                 if (mStopped) {
                     clearSBgDataStructures();
-                    return false;
+                    return;
                 }
 
                 if (itemsToRemove.size() > 0) {
@@ -2392,63 +2376,29 @@
                             null, sWorker);
                 }
 
-                if (loadedOldDb) {
-                    long maxScreenId = 0;
-                    // If we're importing we use the old screen order.
-                    for (ItemInfo item: sBgItemsIdMap.values()) {
-                        long screenId = item.screenId;
-                        if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                                !sBgWorkspaceScreens.contains(screenId)) {
-                            sBgWorkspaceScreens.add(screenId);
-                            if (screenId > maxScreenId) {
-                                maxScreenId = screenId;
-                            }
-                        }
-                    }
-                    Collections.sort(sBgWorkspaceScreens);
-                    // Log to disk
-                    Launcher.addDumpLog(TAG, "11683562 -   maxScreenId: " + maxScreenId, true);
-                    Launcher.addDumpLog(TAG, "11683562 -   sBgWorkspaceScreens: " +
-                            TextUtils.join(", ", sBgWorkspaceScreens), true);
+                sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext));
+                // Log to disk
+                Launcher.addDumpLog(TAG, "11683562 -   sBgWorkspaceScreens: " +
+                        TextUtils.join(", ", sBgWorkspaceScreens), true);
 
-                    LauncherAppState.getLauncherProvider().updateMaxScreenId(maxScreenId);
+                // Remove any empty screens
+                ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens);
+                for (ItemInfo item: sBgItemsIdMap.values()) {
+                    long screenId = item.screenId;
+                    if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
+                            unusedScreens.contains(screenId)) {
+                        unusedScreens.remove(screenId);
+                    }
+                }
+
+                // If there are any empty screens remove them, and update.
+                if (unusedScreens.size() != 0) {
+                    // Log to disk
+                    Launcher.addDumpLog(TAG, "11683562 -   unusedScreens (to be removed): " +
+                            TextUtils.join(", ", unusedScreens), true);
+
+                    sBgWorkspaceScreens.removeAll(unusedScreens);
                     updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
-
-                    // Update the max item id after we load an old db
-                    long maxItemId = 0;
-                    // If we're importing we use the old screen order.
-                    for (ItemInfo item: sBgItemsIdMap.values()) {
-                        maxItemId = Math.max(maxItemId, item.id);
-                    }
-                    LauncherAppState.getLauncherProvider().updateMaxItemId(maxItemId);
-                } else {
-                    TreeMap<Integer, Long> orderedScreens = loadWorkspaceScreensDb(mContext);
-                    for (Integer i : orderedScreens.keySet()) {
-                        sBgWorkspaceScreens.add(orderedScreens.get(i));
-                    }
-                    // Log to disk
-                    Launcher.addDumpLog(TAG, "11683562 -   sBgWorkspaceScreens: " +
-                            TextUtils.join(", ", sBgWorkspaceScreens), true);
-
-                    // Remove any empty screens
-                    ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens);
-                    for (ItemInfo item: sBgItemsIdMap.values()) {
-                        long screenId = item.screenId;
-                        if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                                unusedScreens.contains(screenId)) {
-                            unusedScreens.remove(screenId);
-                        }
-                    }
-
-                    // If there are any empty screens remove them, and update.
-                    if (unusedScreens.size() != 0) {
-                        // Log to disk
-                        Launcher.addDumpLog(TAG, "11683562 -   unusedScreens (to be removed): " +
-                                TextUtils.join(", ", unusedScreens), true);
-
-                        sBgWorkspaceScreens.removeAll(unusedScreens);
-                        updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
-                    }
                 }
 
                 if (DEBUG_LOADERS) {
@@ -2477,7 +2427,17 @@
                     }
                 }
             }
-            return loadedOldDb;
+        }
+
+        /**
+         * Partially updates the item without any notification. Must be called on the worker thread.
+         */
+        private void updateItem(long itemId, ContentValues update) {
+            mContext.getContentResolver().update(
+                    LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
+                    update,
+                    BaseColumns._ID + "= ?",
+                    new String[]{Long.toString(itemId)});
         }
 
         /** Filters the set of items who are directly or indirectly (via another container) on the
@@ -2674,7 +2634,7 @@
         /**
          * Binds all loaded data to actual views on the main thread.
          */
-        private void bindWorkspace(int synchronizeBindPage, final boolean isUpgradePath) {
+        private void bindWorkspace(int synchronizeBindPage) {
             final long t = SystemClock.uptimeMillis();
             Runnable r;
 
@@ -2778,7 +2738,7 @@
                 public void run() {
                     Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                     if (callbacks != null) {
-                        callbacks.finishBindingItems(isUpgradePath);
+                        callbacks.finishBindingItems();
                     }
 
                     // If we're profiling, ensure this is the last thing in the queue.
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 0088f26..ab1347b 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -57,7 +57,6 @@
     private static final String TAG = "Launcher.LauncherProvider";
     private static final boolean LOGD = false;
 
-    private static final int MIN_DATABASE_VERSION = 12;
     private static final int DATABASE_VERSION = 21;
 
     static final String OLD_AUTHORITY = "com.android.launcher2.settings";
@@ -66,7 +65,6 @@
     static final String TABLE_FAVORITES = "favorites";
     static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens";
     static final String PARAMETER_NOTIFY = "notify";
-    static final String UPGRADED_FROM_OLD_DATABASE = "UPGRADED_FROM_OLD_DATABASE";
     static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
 
     private static final String URI_PARAM_IS_EXTERNAL_ADD = "isExternalAdd";
@@ -251,12 +249,6 @@
         return mOpenHelper.generateNewScreenId();
     }
 
-    // This is only required one time while loading the workspace during the
-    // upgrade path, and should never be called from anywhere else.
-    public void updateMaxScreenId(long maxScreenId) {
-        mOpenHelper.updateMaxScreenId(maxScreenId);
-    }
-
     /**
      * Clears all the data for a fresh start.
      */
@@ -474,135 +466,112 @@
         private void setFlagJustLoadedOldDb() {
             String spKey = LauncherAppState.getSharedPreferencesKey();
             SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            SharedPreferences.Editor editor = sp.edit();
-            editor.putBoolean(UPGRADED_FROM_OLD_DATABASE, true);
-            editor.putBoolean(EMPTY_DATABASE_CREATED, false);
-            editor.commit();
+            sp.edit().putBoolean(EMPTY_DATABASE_CREATED, false).commit();
         }
 
         private void setFlagEmptyDbCreated() {
             String spKey = LauncherAppState.getSharedPreferencesKey();
             SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            SharedPreferences.Editor editor = sp.edit();
-            editor.putBoolean(EMPTY_DATABASE_CREATED, true);
-            editor.putBoolean(UPGRADED_FROM_OLD_DATABASE, false);
-            editor.commit();
+            sp.edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit();
         }
 
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             if (LOGD) Log.d(TAG, "onUpgrade triggered: " + oldVersion);
-
-            int version = oldVersion;
-            if (version < MIN_DATABASE_VERSION) {
-                // The version cannot be lower that this, as Launcher3 never supported a lower
+            switch (oldVersion) {
+                // The version cannot be lower that 12, as Launcher3 never supported a lower
                 // version of the DB.
-                createEmptyDB(db);
-                version = DATABASE_VERSION;
-            }
-
-            if (version < 13) {
-                // With the new shrink-wrapped and re-orderable workspaces, it makes sense
-                // to persist workspace screens and their relative order.
-                mMaxScreenId = 0;
-
-                addWorkspacesTable(db);
-                version = 13;
-            }
-
-            if (version < 14) {
-                db.beginTransaction();
-                try {
-                    // Insert new column for holding widget provider name
-                    db.execSQL("ALTER TABLE favorites " +
-                            "ADD COLUMN appWidgetProvider TEXT;");
-                    db.setTransactionSuccessful();
-                    version = 14;
-                } catch (SQLException ex) {
-                    // Old version remains, which means we wipe old data
-                    Log.e(TAG, ex.getMessage(), ex);
-                } finally {
-                    db.endTransaction();
+                case 12: {
+                    // With the new shrink-wrapped and re-orderable workspaces, it makes sense
+                    // to persist workspace screens and their relative order.
+                    mMaxScreenId = 0;
+                    addWorkspacesTable(db);
+                }
+                case 13: {
+                    db.beginTransaction();
+                    try {
+                        // Insert new column for holding widget provider name
+                        db.execSQL("ALTER TABLE favorites " +
+                                "ADD COLUMN appWidgetProvider TEXT;");
+                        db.setTransactionSuccessful();
+                    } catch (SQLException ex) {
+                        Log.e(TAG, ex.getMessage(), ex);
+                        // Old version remains, which means we wipe old data
+                        break;
+                    } finally {
+                        db.endTransaction();
+                    }
+                }
+                case 14: {
+                    db.beginTransaction();
+                    try {
+                        // Insert new column for holding update timestamp
+                        db.execSQL("ALTER TABLE favorites " +
+                                "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
+                        db.execSQL("ALTER TABLE workspaceScreens " +
+                                "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
+                        db.setTransactionSuccessful();
+                    } catch (SQLException ex) {
+                        Log.e(TAG, ex.getMessage(), ex);
+                        // Old version remains, which means we wipe old data
+                        break;
+                    } finally {
+                        db.endTransaction();
+                    }
+                }
+                case 15: {
+                    db.beginTransaction();
+                    try {
+                        // Insert new column for holding restore status
+                        db.execSQL("ALTER TABLE favorites " +
+                                "ADD COLUMN restored INTEGER NOT NULL DEFAULT 0;");
+                        db.setTransactionSuccessful();
+                    } catch (SQLException ex) {
+                        Log.e(TAG, ex.getMessage(), ex);
+                        // Old version remains, which means we wipe old data
+                        break;
+                    } finally {
+                        db.endTransaction();
+                    }
+                }
+                case 16: {
+                    // We use the db version upgrade here to identify users who may not have seen
+                    // clings yet (because they weren't available), but for whom the clings are now
+                    // available (tablet users). Because one of the possible cling flows (migration)
+                    // is very destructive (wipes out workspaces), we want to prevent this from showing
+                    // until clear data. We do so by marking that the clings have been shown.
+                    LauncherClings.synchonouslyMarkFirstRunClingDismissed(mContext);
+                }
+                case 17: {
+                    // No-op
+                }
+                case 18: {
+                    // Due to a data loss bug, some users may have items associated with screen ids
+                    // which no longer exist. Since this can cause other problems, and since the user
+                    // will never see these items anyway, we use database upgrade as an opportunity to
+                    // clean things up.
+                    removeOrphanedItems(db);
+                }
+                case 19: {
+                    // Add userId column
+                    if (!addProfileColumn(db)) {
+                        // Old version remains, which means we wipe old data
+                        break;
+                    }
+                }
+                case 20:
+                    if (!updateFolderItemsRank(db, true)) {
+                        break;
+                    }
+                case 21: {
+                    // DB Upgraded successfully
+                    return;
                 }
             }
 
-            if (version < 15) {
-                db.beginTransaction();
-                try {
-                    // Insert new column for holding update timestamp
-                    db.execSQL("ALTER TABLE favorites " +
-                            "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
-                    db.execSQL("ALTER TABLE workspaceScreens " +
-                            "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
-                    db.setTransactionSuccessful();
-                    version = 15;
-                } catch (SQLException ex) {
-                    // Old version remains, which means we wipe old data
-                    Log.e(TAG, ex.getMessage(), ex);
-                } finally {
-                    db.endTransaction();
-                }
-            }
-
-
-            if (version < 16) {
-                db.beginTransaction();
-                try {
-                    // Insert new column for holding restore status
-                    db.execSQL("ALTER TABLE favorites " +
-                            "ADD COLUMN restored INTEGER NOT NULL DEFAULT 0;");
-                    db.setTransactionSuccessful();
-                    version = 16;
-                } catch (SQLException ex) {
-                    // Old version remains, which means we wipe old data
-                    Log.e(TAG, ex.getMessage(), ex);
-                } finally {
-                    db.endTransaction();
-                }
-            }
-
-            if (version < 17) {
-                // We use the db version upgrade here to identify users who may not have seen
-                // clings yet (because they weren't available), but for whom the clings are now
-                // available (tablet users). Because one of the possible cling flows (migration)
-                // is very destructive (wipes out workspaces), we want to prevent this from showing
-                // until clear data. We do so by marking that the clings have been shown.
-                LauncherClings.synchonouslyMarkFirstRunClingDismissed(mContext);
-                version = 17;
-            }
-
-            if (version < 18) {
-                // No-op
-                version = 18;
-            }
-
-            if (version < 19) {
-                // Due to a data loss bug, some users may have items associated with screen ids
-                // which no longer exist. Since this can cause other problems, and since the user
-                // will never see these items anyway, we use database upgrade as an opportunity to
-                // clean things up.
-                removeOrphanedItems(db);
-                version = 19;
-            }
-
-            if (version < 20) {
-                // Add userId column
-                if (addProfileColumn(db)) {
-                    version = 20;
-                }
-                // else old version remains, which means we wipe old data
-            }
-
-            if (version < 21) {
-                if (updateFolderItemsRank(db, true)) {
-                    version  = 21;
-                }
-            }
-
-            if (version != DATABASE_VERSION) {
-                Log.w(TAG, "Destroying all old data.");
-                createEmptyDB(db);
-            }
+            // DB was not upgraded
+            Log.w(TAG, "Destroying all old data.");
+            createEmptyDB(db);
         }
 
         @Override
@@ -745,12 +714,6 @@
             return mMaxScreenId;
         }
 
-        public void updateMaxScreenId(long maxScreenId) {
-            // Log to disk
-            Launcher.addDumpLog(TAG, "11683562 - updateMaxScreenId(): " + maxScreenId, true);
-            mMaxScreenId = maxScreenId;
-        }
-
         private long initializeMaxScreenId(SQLiteDatabase db) {
             Cursor c = db.rawQuery("SELECT MAX(" + LauncherSettings.WorkspaceScreens._ID + ") FROM " + TABLE_WORKSPACE_SCREENS, null);
 
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 01f7931..15d6a3e 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -46,18 +46,24 @@
      * be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout
      * parsing.
      */
-    public static final int FLAG_AUTOINTALL_ICON = 2;
+    public static final int FLAG_AUTOINTALL_ICON = 2; //0B10;
 
     /**
      * The icon is being installed. If {@link FLAG_RESTORED_ICON} or {@link FLAG_AUTOINTALL_ICON}
      * is set, then the icon is either being installed or is in a broken state.
      */
-    public static final int FLAG_INSTALL_SESSION_ACTIVE = 4;
+    public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
 
     /**
      * Indicates that the widget restore has started.
      */
-    public static final int FLAG_RESTORE_STARTED = 8;
+    public static final int FLAG_RESTORE_STARTED = 8; //0B1000;
+
+    /**
+     * Indicates if it represents a common type mentioned in {@link CommonAppTypeParser}.
+     * Upto 15 different types supported.
+     */
+    public static final int FLAG_RESTORED_APP_TYPE = 0B0011110000;
 
     /**
      * The intent used to start the application.
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6cfb6b2..1a4afe8 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -43,12 +43,10 @@
 import android.graphics.Rect;
 import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
-import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcelable;
-import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
@@ -492,7 +490,7 @@
         CellLayout cl = ((CellLayout) child);
         cl.setOnInterceptTouchListener(this);
         cl.setClickable(true);
-        cl.setImportantForAccessibility(ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO);
+        cl.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
         super.onChildViewAdded(parent, child);
     }
 
@@ -561,10 +559,6 @@
     }
 
     public long insertNewWorkspaceScreen(long screenId, int insertIndex) {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - insertNewWorkspaceScreen(): " + screenId +
-                " at index: " + insertIndex, true);
-
         if (mWorkspaceScreens.containsKey(screenId)) {
             throw new RuntimeException("Screen id " + screenId + " already exists!");
         }
@@ -664,9 +658,6 @@
     }
 
     public void addExtraEmptyScreenOnDrag() {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - addExtraEmptyScreenOnDrag()", true);
-
         boolean lastChildOnScreen = false;
         boolean childOnFinalScreen = false;
 
@@ -693,9 +684,6 @@
     }
 
     public boolean addExtraEmptyScreen() {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - addExtraEmptyScreen()", true);
-
         if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
             insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
             return true;
@@ -704,9 +692,6 @@
     }
 
     private void convertFinalScreenToEmptyScreenIfNecessary() {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - convertFinalScreenToEmptyScreenIfNecessary()", true);
-
         if (mLauncher.isWorkspaceLoading()) {
             // Invalid and dangerous operation if workspace is loading
             Launcher.addDumpLog(TAG, "    - workspace loading, skip", true);
@@ -731,7 +716,6 @@
 
             // Update the model if we have changed any screens
             mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
-            Launcher.addDumpLog(TAG, "11683562 -   extra empty screen: " + finalScreenId, true);
         }
     }
 
@@ -741,8 +725,6 @@
 
     public void removeExtraEmptyScreenDelayed(final boolean animate, final Runnable onComplete,
             final int delay, final boolean stripEmptyScreens) {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - removeExtraEmptyScreen()", true);
         if (mLauncher.isWorkspaceLoading()) {
             // Don't strip empty screens if the workspace is still loading
             Launcher.addDumpLog(TAG, "    - workspace loading, skip", true);
@@ -784,9 +766,7 @@
 
     private void fadeAndRemoveEmptyScreen(int delay, int duration, final Runnable onComplete,
             final boolean stripEmptyScreens) {
-        // Log to disk
         // XXX: Do we need to update LM workspace screens below?
-        Launcher.addDumpLog(TAG, "11683562 - fadeAndRemoveEmptyScreen()", true);
         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
         PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", 0f);
 
@@ -830,8 +810,6 @@
     }
 
     public long commitExtraEmptyScreen() {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - commitExtraEmptyScreen()", true);
         if (mLauncher.isWorkspaceLoading()) {
             // Invalid and dangerous operation if workspace is loading
             Launcher.addDumpLog(TAG, "    - workspace loading, skip", true);
@@ -890,9 +868,6 @@
     }
 
     public void stripEmptyScreens() {
-        // Log to disk
-        Launcher.addDumpLog(TAG, "11683562 - stripEmptyScreens()", true);
-
         if (mLauncher.isWorkspaceLoading()) {
             // Don't strip empty screens if the workspace is still loading.
             // This is dangerous and can result in data loss.
@@ -920,7 +895,6 @@
 
         int pageShift = 0;
         for (Long id: removeScreens) {
-            Launcher.addDumpLog(TAG, "11683562 -   removing id: " + id, true);
             CellLayout cl = mWorkspaceScreens.get(id);
             mWorkspaceScreens.remove(id);
             mScreenOrder.remove(id);
@@ -2210,8 +2184,8 @@
 
     private void updateAccessibilityFlags() {
         int accessible = mState == State.NORMAL ?
-                ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES :
-                ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
+                IMPORTANT_FOR_ACCESSIBILITY_YES :
+                IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
         setImportantForAccessibility(accessible);
     }
 
@@ -4115,7 +4089,6 @@
 
         // In the case where we've prebound the widget, we remove it from the DragLayer
         if (finalView instanceof AppWidgetHostView && external) {
-            Log.d(TAG, "6557954 Animate widget drop, final view is appWidgetHostView");
             mLauncher.getDragLayer().removeView(finalView);
         }
 
@@ -4306,88 +4279,6 @@
         }
     }
 
-    ArrayList<ComponentName> getUniqueComponents(boolean stripDuplicates, ArrayList<ComponentName> duplicates) {
-        ArrayList<ComponentName> uniqueIntents = new ArrayList<ComponentName>();
-        getUniqueIntents((CellLayout) mLauncher.getHotseat().getLayout(), uniqueIntents, duplicates, false);
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            CellLayout cl = (CellLayout) getChildAt(i);
-            getUniqueIntents(cl, uniqueIntents, duplicates, false);
-        }
-        return uniqueIntents;
-    }
-
-    void getUniqueIntents(CellLayout cl, ArrayList<ComponentName> uniqueIntents,
-            ArrayList<ComponentName> duplicates, boolean stripDuplicates) {
-        int count = cl.getShortcutsAndWidgets().getChildCount();
-
-        ArrayList<View> children = new ArrayList<View>();
-        for (int i = 0; i < count; i++) {
-            View v = cl.getShortcutsAndWidgets().getChildAt(i);
-            children.add(v);
-        }
-
-        for (int i = 0; i < count; i++) {
-            View v = children.get(i);
-            ItemInfo info = (ItemInfo) v.getTag();
-            // Null check required as the AllApps button doesn't have an item info
-            if (info instanceof ShortcutInfo) {
-                ShortcutInfo si = (ShortcutInfo) info;
-                ComponentName cn = si.intent.getComponent();
-
-                Uri dataUri = si.intent.getData();
-                // If dataUri is not null / empty or if this component isn't one that would
-                // have previously showed up in the AllApps list, then this is a widget-type
-                // shortcut, so ignore it.
-                if (dataUri != null && !dataUri.equals(Uri.EMPTY)) {
-                    continue;
-                }
-
-                if (!uniqueIntents.contains(cn)) {
-                    uniqueIntents.add(cn);
-                } else {
-                    if (stripDuplicates) {
-                        cl.removeViewInLayout(v);
-                        LauncherModel.deleteItemFromDatabase(mLauncher, si);
-                    }
-                    if (duplicates != null) {
-                        duplicates.add(cn);
-                    }
-                }
-            }
-            if (v instanceof FolderIcon) {
-                FolderIcon fi = (FolderIcon) v;
-                ArrayList<View> items = fi.getFolder().getItemsInReadingOrder();
-                for (int j = 0; j < items.size(); j++) {
-                    if (items.get(j).getTag() instanceof ShortcutInfo) {
-                        ShortcutInfo si = (ShortcutInfo) items.get(j).getTag();
-                        ComponentName cn = si.intent.getComponent();
-
-                        Uri dataUri = si.intent.getData();
-                        // If dataUri is not null / empty or if this component isn't one that would
-                        // have previously showed up in the AllApps list, then this is a widget-type
-                        // shortcut, so ignore it.
-                        if (dataUri != null && !dataUri.equals(Uri.EMPTY)) {
-                            continue;
-                        }
-
-                        if (!uniqueIntents.contains(cn)) {
-                            uniqueIntents.add(cn);
-                        }  else {
-                            if (stripDuplicates) {
-                                fi.getFolderInfo().remove(si);
-                                LauncherModel.deleteItemFromDatabase(mLauncher, si);
-                            }
-                            if (duplicates != null) {
-                                duplicates.add(cn);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     void saveWorkspaceToDb() {
         saveWorkspaceScreenToDb((CellLayout) mLauncher.getHotseat().getLayout());
         int count = getChildCount();
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
index 1d41a6f..ea51aac 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
@@ -29,13 +29,15 @@
 
 
 public class LauncherActivityInfoCompatV16 extends LauncherActivityInfoCompat {
-    private ActivityInfo mActivityInfo;
-    private ComponentName mComponentName;
-    private PackageManager mPm;
+    private final ResolveInfo mResolveInfo;
+    private final ActivityInfo mActivityInfo;
+    private final ComponentName mComponentName;
+    private final PackageManager mPm;
 
     LauncherActivityInfoCompatV16(Context context, ResolveInfo info) {
         super();
-        this.mActivityInfo = info.activityInfo;
+        mResolveInfo = info;
+        mActivityInfo = info.activityInfo;
         mComponentName = new ComponentName(mActivityInfo.packageName, mActivityInfo.name);
         mPm = context.getPackageManager();
     }
@@ -49,31 +51,30 @@
     }
 
     public CharSequence getLabel() {
-        return mActivityInfo.loadLabel(mPm);
+        return mResolveInfo.loadLabel(mPm);
     }
 
     public Drawable getIcon(int density) {
-        Drawable d = null;
-        if (mActivityInfo.getIconResource() != 0) {
-            Resources resources;
+        int iconRes = mResolveInfo.getIconResource();
+        Resources resources = null;
+        Drawable icon = null;
+        // Get the preferred density icon from the app's resources
+        if (density != 0 && iconRes != 0) {
             try {
-                resources = mPm.getResourcesForApplication(mActivityInfo.packageName);
-            } catch (PackageManager.NameNotFoundException e) {
-                resources = null;
-            }
-            if (resources != null) {
-                try {
-                    d = resources.getDrawableForDensity(mActivityInfo.getIconResource(), density);
-                } catch (Resources.NotFoundException e) {
-                    // Return default icon below.
-                }
+                resources = mPm.getResourcesForApplication(mActivityInfo.applicationInfo);
+                icon = resources.getDrawableForDensity(iconRes, density);
+            } catch (NameNotFoundException | Resources.NotFoundException exc) {
             }
         }
-        if (d == null) {
-            Resources resources = Resources.getSystem();
-            d = resources.getDrawableForDensity(android.R.mipmap.sym_def_app_icon, density);
+        // Get the default density icon
+        if (icon == null) {
+            icon = mResolveInfo.loadIcon(mPm);
         }
-        return d;
+        if (icon == null) {
+            resources = Resources.getSystem();
+            icon = resources.getDrawableForDensity(android.R.mipmap.sym_def_app_icon, density);
+        }
+        return icon;
     }
 
     public ApplicationInfo getApplicationInfo() {
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
new file mode 100644
index 0000000..23375dc
--- /dev/null
+++ b/src/com/android/launcher3/util/FocusLogic.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2015 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.launcher3.util;
+
+import android.content.res.Configuration;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.ViewGroup;
+
+import com.android.launcher3.CellLayout;
+
+/**
+ * Calculates the next item that a {@link KeyEvent} should change the focus to.
+ *<p>
+ * Note, this utility class calculates everything regards to icon index and its (x,y) coordinates.
+ * Currently supports:
+ * <ul>
+ *  <li> full matrix of cells that are 1x1
+ *  <li> sparse matrix of cells that are 1x1
+ *     [ 1][  ][ 2][  ]
+ *     [  ][  ][ 3][  ]
+ *     [  ][ 4][  ][  ]
+ *     [  ][ 5][ 6][ 7]
+ * </ul>
+ * *<p>
+ * For testing, one can use a BT keyboard, or use following adb command.
+ * ex. $ adb shell input keyevent 20 // KEYCODE_DPAD_LEFT
+ */
+public class FocusLogic {
+
+    private static final String TAG = "Focus";
+    private static final boolean DEBUG = false;
+
+    // Item and page index related constant used by {@link #handleKeyEvent}.
+    public static final int NOOP = -1;
+    public static final int PREVIOUS_PAGE_FIRST_ITEM    = -2;
+    public static final int PREVIOUS_PAGE_LAST_ITEM     = -3;
+    public static final int CURRENT_PAGE_FIRST_ITEM     = -4;
+    public static final int CURRENT_PAGE_LAST_ITEM      = -5;
+    public static final int NEXT_PAGE_FIRST_ITEM        = -6;
+
+    // Matrix related constant.
+    public static final int EMPTY = -1;
+
+    /**
+     * Returns true only if this utility class handles the key code.
+     */
+    public static boolean shouldConsume(int keyCode) {
+        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ||
+                keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN ||
+                keyCode == KeyEvent.KEYCODE_MOVE_HOME || keyCode == KeyEvent.KEYCODE_MOVE_END ||
+                keyCode == KeyEvent.KEYCODE_PAGE_UP || keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
+            return true;
+        }
+        return false;
+    }
+
+    public static int handleKeyEvent(int keyCode, int cntX, int cntY, int [][] map,
+            int iconIdx, int pageIndex, int pageCount) {
+
+        if (DEBUG) {
+            Log.v(TAG, String.format(
+                    "handleKeyEvent START: cntX=%d, cntY=%d, iconIdx=%d, pageIdx=%d, pageCnt=%d",
+                    cntX, cntY, iconIdx, pageIndex, pageCount));
+        }
+
+        int newIndex = NOOP;
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+                newIndex = handleDpadHorizontal(iconIdx, cntX, cntY, map, -1 /*increment*/);
+                if (newIndex == NOOP && pageIndex > 0) {
+                    return PREVIOUS_PAGE_LAST_ITEM;
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                newIndex = handleDpadHorizontal(iconIdx, cntX, cntY, map, 1 /*increment*/);
+                if (newIndex == NOOP && pageIndex < pageCount - 1) {
+                    return NEXT_PAGE_FIRST_ITEM;
+                }
+                break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                newIndex = handleDpadVertical(iconIdx, cntX, cntY, map, 1  /*increment*/);
+                break;
+            case KeyEvent.KEYCODE_DPAD_UP:
+                newIndex = handleDpadVertical(iconIdx, cntX, cntY, map, -1  /*increment*/);
+                break;
+            case KeyEvent.KEYCODE_MOVE_HOME:
+                newIndex = handleMoveHome();
+                break;
+            case KeyEvent.KEYCODE_MOVE_END:
+                newIndex = handleMoveEnd();
+                break;
+            case KeyEvent.KEYCODE_PAGE_DOWN:
+                newIndex = handlePageDown(pageIndex, pageCount);
+                break;
+            case KeyEvent.KEYCODE_PAGE_UP:
+                newIndex = handlePageUp(pageIndex);
+                break;
+            default:
+                break;
+        }
+
+        if (DEBUG) {
+            Log.v(TAG, String.format("handleKeyEvent FINISH: index [%d -> %s]",
+                    iconIdx, getStringIndex(newIndex)));
+        }
+        return newIndex;
+    }
+
+    /**
+     * Returns a matrix of size (m x n) that has been initialized with incremental index starting
+     * with 0 or a matrix where all the values are initialized to {@link #EMPTY}.
+     *
+     * @param m                 number of columns in the matrix
+     * @param n                 number of rows in the matrix
+     * @param incrementOrder    {@code true} if the matrix contents should increment in reading
+     *                          order with 0 indexing. {@code false} if each cell should be
+     *                          initialized to {@link #EMPTY};
+     */
+    // TODO: get rid of dynamic matrix creation.
+    public static int[][] createFullMatrix(int m, int n, boolean incrementOrder) {
+        int[][] matrix = new int [m][n];
+        for (int i=0; i < m;i++) {
+            for (int j=0; j < n; j++) {
+                if (incrementOrder) {
+                    matrix[i][j] = j * m + i;
+                } else {
+                    matrix[i][j] = EMPTY;
+                }
+            }
+        }
+        return matrix;
+    }
+
+    /**
+     * Returns a matrix of size same as the {@link CellLayout} dimension that is initialized with the
+     * index of the child view.
+     */
+    // TODO: get rid of the dynamic matrix creation
+    public static int[][] createSparseMatrix(CellLayout layout) {
+        ViewGroup parent = layout.getShortcutsAndWidgets();
+        final int m = layout.getCountX();
+        final int n = layout.getCountY();
+
+        int[][] matrix = createFullMatrix(m, n, false /* initialize to #EMPTY */);
+
+        // Iterate thru the children.
+        for (int i = 0; i < parent.getChildCount(); i++ ) {
+            int cx = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellX;
+            int cy = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellY;
+            matrix[cx][cy] = i;
+        }
+        if (DEBUG) {
+            printMatrix(matrix, m, n);
+        }
+        return matrix;
+    }
+
+    /**
+     * Creates a sparse matrix that merges the icon and hotseat view group using the cell layout.
+     * The size of the returning matrix is [icon column count x (icon + hotseat row count)]
+     * in portrait orientation. In landscape, [(icon + hotseat) column count x (icon row count)]
+     */
+ // TODO: get rid of the dynamic matrix creation
+    public static int[][] createSparseMatrix(CellLayout iconLayout, CellLayout hotseatLayout,
+            int orientation) {
+
+        ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
+        ViewGroup hotseatParent = hotseatLayout.getShortcutsAndWidgets();
+
+        int m, n;
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+            m = iconLayout.getCountX();
+            n = iconLayout.getCountY() + hotseatLayout.getCountY();
+        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            m = iconLayout.getCountX() + hotseatLayout.getCountX();
+            n = iconLayout.getCountY();
+        } else {
+            throw new IllegalStateException(String.format(
+                    "orientation type=%d is not supported for key board events.", orientation));
+        }
+        int[][] matrix = createFullMatrix(m, n, false /* set all cell to empty */);
+
+        // Iterate thru the children of the top parent.
+        for (int i = 0; i < iconParent.getChildCount(); i++) {
+            int cx = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellX;
+            int cy = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellY;
+            matrix[cx][cy] = i;
+        }
+
+        // Iterate thru the children of the bottom parent
+        for(int i = 0; i < hotseatParent.getChildCount(); i++) {
+            // If the hotseat view group contains more items than topColumnCnt, then just
+            // discard them.
+            // TODO: make this more elegant. (look at DynamicGrid)
+            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                int cx = ((CellLayout.LayoutParams)
+                        hotseatParent.getChildAt(i).getLayoutParams()).cellX;
+                if (cx < iconLayout.getCountX()) {
+                    matrix[cx][iconLayout.getCountY()] = iconParent.getChildCount() + i;
+                }
+            } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+                int cy = ((CellLayout.LayoutParams)
+                        hotseatParent.getChildAt(i).getLayoutParams()).cellY;
+                if (cy < iconLayout.getCountY()) {
+                    matrix[iconLayout.getCountX()][cy] = iconParent.getChildCount() + i;
+                }
+            }
+        }
+        if (DEBUG) {
+            printMatrix(matrix, m, n);
+        }
+        return matrix;
+    }
+
+    //
+    // key event handling methods.
+    //
+
+    /**
+     * Calculates icon that has is closest to the horizontal axis in reference to the cur icon.
+     *
+     * Example of the check order for KEYCODE_DPAD_RIGHT:
+     * [  ][  ][13][14][15]
+     * [  ][ 6][ 8][10][12]
+     * [ X][ 1][ 2][ 3][ 4]
+     * [  ][ 5][ 7][ 9][11]
+     */
+    // TODO: add unit tests to verify all permutation.
+    private static int handleDpadHorizontal(int iconIdx, int cntX, int cntY,
+            int[][] matrix, int increment) {
+        if(matrix == null) {
+            throw new IllegalStateException("Dpad navigation requires a matrix.");
+        }
+        int newIconIndex = NOOP;
+
+        int xPos = -1;
+        int yPos = -1;
+        // Figure out the location of the icon.
+        for (int i = 0; i < cntX; i++) {
+            for (int j = 0; j < cntY; j++) {
+                if (matrix[i][j] == iconIdx) {
+                    xPos = i;
+                    yPos = j;
+                }
+            }
+        }
+        if (DEBUG) {
+            Log.v(TAG, String.format("\thandleDpadHorizontal: \t[x, y]=[%d, %d] iconIndex=%d",
+                    xPos, yPos, iconIdx));
+        }
+
+        // Rule1: check first in the horizontal direction
+        for (int i = xPos + increment; 0 <= i && i < cntX; i = i + increment) {
+            if (DEBUG) {
+                Log.v(TAG, String.format("\t\tsearch: \t[x, y]=[%d, %d] iconIndex=%d",
+                        i, yPos, matrix[i][yPos]));
+            }
+            if (matrix[i][yPos] != -1) {
+                newIconIndex = matrix[i][yPos];
+                return newIconIndex;
+            }
+        }
+
+        // Rule2: check (x1-n, yPos + increment),   (x1-n, yPos - increment)
+        //              (x2-n, yPos + 2*increment), (x2-n, yPos - 2*increment)
+        int nextYPos1;
+        int nextYPos2;
+        int i = -1;
+        for (int coeff = 1; coeff < cntY; coeff++) {
+            nextYPos1 = yPos + coeff * increment;
+            nextYPos2 = yPos - coeff * increment;
+            for (i = xPos + increment * coeff; 0 <= i && i < cntX; i = i + increment) {
+                if ((newIconIndex = inspectMatrix(i, nextYPos1, cntX, cntY, matrix)) != NOOP) {
+                    return newIconIndex;
+                }
+                if ((newIconIndex = inspectMatrix(i, nextYPos2, cntX, cntY, matrix)) != NOOP) {
+                    return newIconIndex;
+                }
+            }
+        }
+        return newIconIndex;
+    }
+
+    /**
+     * Calculates icon that is closest to the vertical axis in reference to the current icon.
+     *
+     * Example of the check order for KEYCODE_DPAD_DOWN:
+     * [  ][  ][  ][ X][  ][  ][  ]
+     * [  ][  ][ 5][ 1][ 4][  ][  ]
+     * [  ][10][ 7][ 2][ 6][ 9][  ]
+     * [14][12][ 9][ 3][ 8][11][13]
+     */
+    // TODO: add unit tests to verify all permutation.
+    private static int handleDpadVertical(int iconIndex, int cntX, int cntY,
+            int [][] matrix, int increment) {
+        int newIconIndex = NOOP;
+        if(matrix == null) {
+            throw new IllegalStateException("Dpad navigation requires a matrix.");
+        }
+
+        int xPos = -1;
+        int yPos = -1;
+        // Figure out the location of the icon.
+        for (int i = 0; i< cntX; i++) {
+            for (int j = 0; j < cntY; j++) {
+                if (matrix[i][j] == iconIndex) {
+                    xPos = i;
+                    yPos = j;
+                }
+            }
+        }
+
+        if (DEBUG) {
+            Log.v(TAG, String.format("\thandleDpadVertical: \t[x, y]=[%d, %d] iconIndex=%d",
+                    xPos, yPos, iconIndex));
+        }
+
+        // Rule1: check first in the dpad direction
+        for (int j = yPos + increment; 0 <= j && j <cntY && 0 <= j; j = j + increment) {
+            if (DEBUG) {
+                Log.v(TAG, String.format("\t\tsearch: \t[x, y]=[%d, %d] iconIndex=%d",
+                        xPos, j, matrix[xPos][j]));
+            }
+            if (matrix[xPos][j] != -1) {
+                newIconIndex = matrix[xPos][j];
+                return newIconIndex;
+            }
+        }
+
+        // Rule2: check (xPos + increment, y_(1-n)),   (xPos - increment, y_(1-n))
+        //              (xPos + 2*increment, y_(2-n))), (xPos - 2*increment, y_(2-n))
+        int nextXPos1;
+        int nextXPos2;
+        int j = -1;
+        for (int coeff = 1; coeff < cntX; coeff++) {
+            nextXPos1 = xPos + coeff * increment;
+            nextXPos2 = xPos - coeff * increment;
+            for (j = yPos + increment * coeff; 0 <= j && j < cntY; j = j + increment) {
+                if ((newIconIndex = inspectMatrix(nextXPos1, j, cntX, cntY, matrix)) != NOOP) {
+                    return newIconIndex;
+                }
+                if ((newIconIndex = inspectMatrix(nextXPos2, j, cntX, cntY, matrix)) != NOOP) {
+                    return newIconIndex;
+                }
+            }
+        }
+        return newIconIndex;
+    }
+
+    private static int handleMoveHome() {
+        return CURRENT_PAGE_FIRST_ITEM;
+    }
+
+    private static int handleMoveEnd() {
+        return CURRENT_PAGE_LAST_ITEM;
+    }
+
+    private static int handlePageDown(int pageIndex, int pageCount) {
+        if (pageIndex < pageCount -1) {
+            return NEXT_PAGE_FIRST_ITEM;
+        }
+        return CURRENT_PAGE_LAST_ITEM;
+    }
+
+    private static int handlePageUp(int pageIndex) {
+        if (pageIndex > 0) {
+            return PREVIOUS_PAGE_FIRST_ITEM;
+        } else {
+            return CURRENT_PAGE_FIRST_ITEM;
+        }
+    }
+
+    //
+    // Helper methods.
+    //
+
+    private static boolean isValid(int xPos, int yPos, int countX, int countY) {
+        return (0 <= xPos && xPos < countX && 0 <= yPos && yPos < countY);
+    }
+
+    private static int inspectMatrix(int x, int y, int cntX, int cntY, int[][] matrix) {
+        int newIconIndex = NOOP;
+        if (isValid(x, y, cntX, cntY)) {
+            if (matrix[x][y] != -1) {
+                newIconIndex = matrix[x][y];
+                if (DEBUG) {
+                    Log.v(TAG, String.format("\t\tinspect: \t[x, y]=[%d, %d] %d",
+                            x, y, matrix[x][y]));
+                }
+                return newIconIndex;
+            }
+        }
+        return newIconIndex;
+    }
+
+    private static String getStringIndex(int index) {
+        switch(index) {
+            case NOOP: return "NOOP";
+            case PREVIOUS_PAGE_FIRST_ITEM:  return "PREVIOUS_PAGE_FIRST";
+            case PREVIOUS_PAGE_LAST_ITEM:   return "PREVIOUS_PAGE_LAST";
+            case CURRENT_PAGE_FIRST_ITEM:   return "CURRENT_PAGE_FIRST";
+            case CURRENT_PAGE_LAST_ITEM:    return "CURRENT_PAGE_LAST";
+            case NEXT_PAGE_FIRST_ITEM:      return "NEXT_PAGE_FIRST";
+            default:
+                return Integer.toString(index);
+        }
+    }
+
+    private static void printMatrix(int[][] matrix, int m, int n) {
+        Log.v(TAG, "\tprintMap:");
+        for (int j=0; j < n; j++) {
+            String colY = "\t\t";
+            for (int i=0; i < m; i++) {
+                colY +=  String.format("%3d",matrix[i][j]);
+            }
+            Log.v(TAG, colY);
+        }
+    }
+}
