merge in honeycomb-release history after reset to master
diff --git a/res/layout-xlarge-land/launcher.xml b/res/layout-xlarge-land/launcher.xml
index 5c58a69..327b572 100644
--- a/res/layout-xlarge-land/launcher.xml
+++ b/res/layout-xlarge-land/launcher.xml
@@ -171,21 +171,6 @@
             android:src="@drawable/delete_zone_selector"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_alignRight="@id/all_apps_button"
-            android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
-            android:paddingRight="@dimen/toolbar_button_horizontal_padding"
-            android:paddingTop="@dimen/toolbar_button_vertical_padding"
-            android:paddingBottom="@dimen/toolbar_button_vertical_padding"
-            android:background="@drawable/button_bg"
-
-            android:visibility="gone"
-            launcher:direction="horizontal" />
-
-        <com.android.launcher2.ApplicationInfoDropTarget
-            android:id="@+id/info_button"
-            android:src="@drawable/ic_home_info_holo_dark"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
             android:layout_alignLeft="@id/configure_button"
             android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
             android:paddingRight="@dimen/toolbar_button_horizontal_padding"
@@ -194,9 +179,7 @@
             android:background="@drawable/button_bg"
 
             android:visibility="gone"
-            android:focusable="true"
-            android:clickable="true" />
-
+            launcher:direction="horizontal" />
     </RelativeLayout>
 
     <TabHost
diff --git a/res/layout-xlarge-port/launcher.xml b/res/layout-xlarge-port/launcher.xml
index 7bc318c..1989649 100644
--- a/res/layout-xlarge-port/launcher.xml
+++ b/res/layout-xlarge-port/launcher.xml
@@ -169,20 +169,6 @@
             android:src="@drawable/delete_zone_selector"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_alignRight="@id/all_apps_button"
-            android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
-            android:paddingRight="@dimen/toolbar_button_horizontal_padding"
-            android:paddingTop="@dimen/toolbar_button_vertical_padding"
-            android:paddingBottom="@dimen/toolbar_button_vertical_padding"
-
-            android:visibility="gone"
-            launcher:direction="horizontal" />
-
-        <com.android.launcher2.ApplicationInfoDropTarget
-            android:id="@+id/info_button"
-            android:src="@drawable/ic_home_info_holo_dark"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
             android:layout_alignLeft="@id/configure_button"
             android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
             android:paddingRight="@dimen/toolbar_button_horizontal_padding"
@@ -190,9 +176,7 @@
             android:paddingBottom="@dimen/toolbar_button_vertical_padding"
 
             android:visibility="gone"
-            android:focusable="true"
-            android:clickable="true" />
-
+            launcher:direction="horizontal" />
     </RelativeLayout>
 
     <TabHost
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index 972215a..dd6cf13 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -49,8 +49,8 @@
     <dimen name="toolbar_button_horizontal_padding">16dip</dimen>
 
     <!-- height & width of the drop rectangle for the trash icon -->
-    <dimen name="delete_zone_size">50dip</dimen>
-    <dimen name="delete_zone_padding">20dip</dimen>
+    <dimen name="delete_zone_vertical_drag_padding">20dip</dimen>
+    <dimen name="delete_zone_horizontal_drag_padding">20dip</dimen>
 
     <!-- dimensions for the wallpaper picker wallpaper thumbnail width -->
     <dimen name="wallpaper_chooser_grid_width">230dp</dimen>
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index dccc03d..5b98a15 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -205,18 +205,16 @@
     private void setupDragMode() {
         mLauncher.getWorkspace().shrink(Workspace.ShrinkState.BOTTOM_VISIBLE);
 
-        ApplicationInfoDropTarget infoButton =
-                (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.info_button);
-        infoButton.setDragAndDropEnabled(false);
         DeleteZone deleteZone = (DeleteZone) mLauncher.findViewById(R.id.delete_zone);
         deleteZone.setDragAndDropEnabled(false);
 
+        DeleteZone allAppsDeleteZone = (DeleteZone)
+                mLauncher.findViewById(R.id.all_apps_delete_zone);
+        allAppsDeleteZone.setDragAndDropEnabled(true);
+
         ApplicationInfoDropTarget allAppsInfoButton =
                 (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
         allAppsInfoButton.setDragAndDropEnabled(true);
-        DeleteZone allAppsDeleteZone = (DeleteZone)
-                mLauncher.findViewById(R.id.all_apps_delete_zone);
-        allAppsDeleteZone.setDragAndDropEnabled(true);
     }
 
     private void tearDownDragMode() {
@@ -225,18 +223,16 @@
             // deleteZone and the appInfoButton in all apps, and re-enable the instance which
             // live in the workspace
             public void run() {
-                ApplicationInfoDropTarget infoButton =
-                    (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.info_button);
-                infoButton.setDragAndDropEnabled(true);
                 DeleteZone deleteZone = (DeleteZone) mLauncher.findViewById(R.id.delete_zone);
                 deleteZone.setDragAndDropEnabled(true);
 
+                DeleteZone allAppsDeleteZone =
+                        (DeleteZone) mLauncher.findViewById(R.id.all_apps_delete_zone);
+                allAppsDeleteZone.setDragAndDropEnabled(false);
+
                 ApplicationInfoDropTarget allAppsInfoButton =
                     (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
                 allAppsInfoButton.setDragAndDropEnabled(false);
-                DeleteZone allAppsDeleteZone =
-                        (DeleteZone) mLauncher.findViewById(R.id.all_apps_delete_zone);
-                allAppsDeleteZone.setDragAndDropEnabled(false);
             }
         });
         resetCheckedGrandchildren();
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 2ee3501..9d421c6 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
 
@@ -38,8 +39,6 @@
     private static final int sFadeOutAnimationDuration = 100;
 
     private AnimatorSet mFadeAnimator;
-    private ObjectAnimator mHandleFadeAnimator;
-    private boolean mHandleWasVisibleOnDragStart;
 
     public ApplicationInfoDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -51,11 +50,16 @@
         // Set the hover paint colour
         int colour = getContext().getResources().getColor(R.color.app_info_filter);
         mHoverPaint.setColorFilter(new PorterDuffColorFilter(colour, PorterDuff.Mode.SRC_ATOP));
+
+        // For the application info drop target, we just ignore the left padding since we don't want
+        // to overlap with the delete zone padding
+        int tb = getResources().getDimensionPixelSize(R.dimen.delete_zone_vertical_drag_padding);
+        int lr = getResources().getDimensionPixelSize(R.dimen.delete_zone_horizontal_drag_padding);
+        setDragPadding(tb, lr, tb, 0);
     }
 
     public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
-
         // acceptDrop is called just before onDrop. We do the work here, rather than
         // in onDrop, because it allows us to reject the drop (by returning false)
         // so that the object being dragged isn't removed from the home screen.
@@ -94,25 +98,18 @@
                 Animator infoButtonAnimator = ObjectAnimator.ofFloat(this, "alpha", 0.0f, 1.0f);
                 infoButtonAnimator.setDuration(sFadeInAnimationDuration);
 
-                if (mHandle == mLauncher.findViewById(R.id.configure_button)) {
-                    final View divider = mLauncher.findViewById(R.id.divider_during_drag);
-                    divider.setVisibility(VISIBLE);
-                    Animator dividerAnimator = ObjectAnimator.ofFloat(divider, "alpha", 1.0f);
-                    dividerAnimator.setDuration(sFadeInAnimationDuration);
-                    mFadeAnimator.play(infoButtonAnimator).with(dividerAnimator);
-                } else {
-                    mFadeAnimator.play(infoButtonAnimator);
-                }
-                mFadeAnimator.start();
+                mFadeAnimator.play(infoButtonAnimator);
+
                 setVisibility(VISIBLE);
 
-                // Fade out the handle
-                if (mHandle != null) {
-                    mHandleWasVisibleOnDragStart = mHandle.getVisibility() == VISIBLE;
-                    if (mHandleFadeAnimator != null) mHandleFadeAnimator.cancel();
-                    mHandleFadeAnimator = ObjectAnimator.ofFloat(mHandle, "alpha", 0.0f);
-                    mHandleFadeAnimator.setDuration(sFadeOutAnimationDuration);
-                    mHandleFadeAnimator.addListener(new AnimatorListener() {
+                // Fade out the overlapping views
+                if (mOverlappingViews != null) {
+                    for (View view : mOverlappingViews) {
+                        ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 0.0f);
+                        oa.setDuration(sFadeOutAnimationDuration);
+                        mFadeAnimator.play(oa);
+                    }
+                    mFadeAnimator.addListener(new AnimatorListener() {
                         public void onAnimationStart(Animator animation) {}
                         public void onAnimationRepeat(Animator animation) {}
                         public void onAnimationEnd(Animator animation) {
@@ -122,12 +119,14 @@
                             onEndOrCancel();
                         }
                         private void onEndOrCancel() {
-                            mHandle.setVisibility(INVISIBLE);
-                            mHandleFadeAnimator = null;
+                            for (View view : mOverlappingViews) {
+                                view.setVisibility(INVISIBLE);
+                            }
+                            mFadeAnimator = null;
                         }
                     });
-                    mHandleFadeAnimator.start();
                 }
+                mFadeAnimator.start();
             }
         }
     }
@@ -141,9 +140,6 @@
         mFadeAnimator = new AnimatorSet();
         Animator infoButtonAnimator = ObjectAnimator.ofFloat(this, "alpha", 0.0f);
         infoButtonAnimator.setDuration(sFadeOutAnimationDuration);
-        final View divider = mLauncher.findViewById(R.id.divider_during_drag);
-        divider.setVisibility(VISIBLE);
-        Animator dividerAnimator = ObjectAnimator.ofFloat(divider, "alpha", 0.0f);
         mFadeAnimator.addListener(new AnimatorListener() {
             public void onAnimationStart(Animator animation) {}
             public void onAnimationRepeat(Animator animation) {}
@@ -155,20 +151,20 @@
             }
             private void onEndOrCancel() {
                 setVisibility(GONE);
-                divider.setVisibility(GONE);
                 mFadeAnimator = null;
             }
         });
-        mFadeAnimator.play(infoButtonAnimator).with(dividerAnimator);
-        mFadeAnimator.start();
+        mFadeAnimator.play(infoButtonAnimator);
 
-        // Fade in the handle
-        if (mHandle != null && mHandleWasVisibleOnDragStart) {
-            if (mHandleFadeAnimator != null) mHandleFadeAnimator.cancel();
-            mHandleFadeAnimator = ObjectAnimator.ofFloat(mHandle, "alpha", 1.0f);
-            mHandleFadeAnimator.setDuration(sFadeInAnimationDuration);
-            mHandleFadeAnimator.start();
-            mHandle.setVisibility(VISIBLE);
+        // Fade in the overlapping views
+        if (mOverlappingViews != null) {
+            for (View view : mOverlappingViews) {
+                ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 1.0f);
+                oa.setDuration(sFadeInAnimationDuration);
+                mFadeAnimator.play(oa);
+                view.setVisibility(VISIBLE);
+            }
         }
+        mFadeAnimator.start();
     }
 }
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index ef4637e..505d465 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -909,19 +909,6 @@
     }
 
     /**
-     * Estimate the size that a child with the given dimensions will take in the layout.
-     */
-    void estimateChildSize(int minWidth, int minHeight, int[] result) {
-        // Assuming it's placed at 0, 0, find where the bottom right cell will land
-        rectToCell(minWidth, minHeight, result);
-
-        // Then figure out the rect it will occupy
-        cellToRect(0, 0, result[0], result[1], mRectF);
-        result[0] = (int)mRectF.width();
-        result[1] = (int)mRectF.height();
-    }
-
-    /**
      * Estimate where the top left cell of the dragged item will land if it is dropped.
      *
      * @param originX The X value of the top left corner of the item
@@ -1322,6 +1309,29 @@
     }
 
     /**
+     * Calculate the grid spans needed to fit given item
+     */
+    public void calculateSpans(ItemInfo info) {
+        final int minWidth;
+        final int minHeight;
+
+        if (info instanceof LauncherAppWidgetInfo) {
+            minWidth = ((LauncherAppWidgetInfo) info).minWidth;
+            minHeight = ((LauncherAppWidgetInfo) info).minHeight;
+        } else if (info instanceof PendingAddWidgetInfo) {
+            minWidth = ((PendingAddWidgetInfo) info).minWidth;
+            minHeight = ((PendingAddWidgetInfo) info).minHeight;
+        } else {
+            // It's not a widget, so it must be 1x1
+            info.spanX = info.spanY = 1;
+            return;
+        }
+        int[] spans = rectToCell(minWidth, minHeight, null);
+        info.spanX = spans[0];
+        info.spanY = spans[1];
+    }
+
+    /**
      * Find the first vacant cell, if there is one.
      *
      * @param vacant Holds the x and y coordinate of the vacant cell
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 5672921..60f1c90 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -21,7 +21,7 @@
 import org.xmlpull.v1.XmlPullParser;
 
 import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
@@ -40,7 +40,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -312,12 +311,18 @@
 
     public void setCustomizationFilter(CustomizationType filterType) {
         mCustomizationType = filterType;
-        setCurrentPage(0);
-        updateCurrentPageScroll();
-        invalidatePageData();
+        if (getChildCount() > 0) {
+            setCurrentPage(0);
+            updateCurrentPageScroll();
+            invalidatePageData();
 
-        // End the current choice mode so that we don't carry selections across tabs
-        endChoiceMode();
+            // End the current choice mode so that we don't carry selections across tabs
+            endChoiceMode();
+        }
+    }
+
+    public CustomizationType getCustomizationFilter() {
+        return mCustomizationType;
     }
 
     @Override
@@ -378,11 +383,7 @@
         posAnim.setInterpolator(mQuintEaseOutInterpolator);
         posAnim.setDuration(ANIMATION_DURATION);
 
-        posAnim.addListener(new AnimatorListener() {
-            public void onAnimationCancel(Animator animation) {}
-            public void onAnimationRepeat(Animator animation) {}
-            public void onAnimationStart(Animator animation) {}
-
+        posAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
                 dragLayer.removeView(dragCopy);
                 mLauncher.addExternalItemToScreen(info, layout);
@@ -443,7 +444,12 @@
             animateClickFeedback(v, new Runnable() {
                 @Override
                 public void run() {
-                    animateItemOntoScreen(dragView, cl, itemInfo);
+                    cl.calculateSpans(itemInfo);
+                    if (cl.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY)) {
+                        animateItemOntoScreen(dragView, cl, itemInfo);
+                    } else {
+                        mLauncher.showOutOfSpaceMessage();
+                    }
                 }
             });
             return;
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index b044ea8..16061d3 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -59,15 +59,16 @@
     public DeleteZone(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        mOuterDragPadding = getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
-        mInnerDragPadding = getResources().getDimensionPixelSize(R.dimen.delete_zone_padding);
-
         final int srcColor = context.getResources().getColor(R.color.delete_color_filter);
         mHoverPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP));
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeleteZone, defStyle, 0);
         mOrientation = a.getInt(R.styleable.DeleteZone_direction, ORIENTATION_HORIZONTAL);
         a.recycle();
+
+        int tb = getResources().getDimensionPixelSize(R.dimen.delete_zone_vertical_drag_padding);
+        int lr = getResources().getDimensionPixelSize(R.dimen.delete_zone_horizontal_drag_padding);
+        setDragPadding(tb, lr, tb, lr);
     }
 
     @Override
@@ -165,8 +166,10 @@
 
             createAnimations();
             startAnimation(mInAnimation);
-            if (mHandle != null) {
-                mHandle.startAnimation(mHandleOutAnimation);
+            if (mOverlappingViews != null) {
+                for (View view : mOverlappingViews) {
+                    view.startAnimation(mHandleOutAnimation);
+                }
             }
             setVisibility(VISIBLE);
         }
@@ -178,8 +181,10 @@
             mDragController.setDeleteRegion(null);
 
             if (mOutAnimation != null) startAnimation(mOutAnimation);
-            if (mHandleInAnimation != null && mHandle != null) {
-                mHandle.startAnimation(mHandleInAnimation);
+            if (mHandleInAnimation != null && mOverlappingViews != null) {
+                for (View view : mOverlappingViews) {
+                    view.startAnimation(mHandleInAnimation);
+                }
             }
             setVisibility(GONE);
         }
diff --git a/src/com/android/launcher2/IconDropTarget.java b/src/com/android/launcher2/IconDropTarget.java
index 5b375c3..bfc46cf 100644
--- a/src/com/android/launcher2/IconDropTarget.java
+++ b/src/com/android/launcher2/IconDropTarget.java
@@ -16,18 +16,17 @@
 
 package com.android.launcher2;
 
-import android.content.ComponentName;
+import com.android.launcher.R;
+
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.ImageView;
 
-import com.android.launcher.R;
-
 /**
  * Implements a DropTarget which allows applications to be dropped on it,
  * in order to launch the application info for that app.
@@ -36,8 +35,8 @@
     protected Launcher mLauncher;
 
     /**
-     * If true, this View responsible for managing its own visibility, and that of its handle.
-     * This is generally the case, but it will be set to false when this is part of the
+     * If true, this View responsible for managing its own visibility, and that of its overlapping
+     *  views. This is generally the case, but it will be set to false when this is part of the
      * Contextual Action Bar.
      */
     protected boolean mDragAndDropEnabled;
@@ -45,15 +44,14 @@
     /** Whether this drop target is active for the current drag */
     protected boolean mActive;
 
-    /** The view that this view should appear in the place of. */
-    protected View mHandle = null;
+    /** The views that this view should appear in the place of. */
+    protected View[] mOverlappingViews = null;
 
     /** The paint applied to the drag view on hover */
     protected final Paint mHoverPaint = new Paint();
 
-    /** Drag zone padding */
-    protected int mInnerDragPadding;
-    protected int mOuterDragPadding;
+    /** Drag zone padding [T, R, B, L] */
+    protected final int mDragPadding[] = new int[4];
 
     public IconDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -64,12 +62,23 @@
         mDragAndDropEnabled = true;
     }
 
+    protected void setDragPadding(int t, int r, int b, int l) {
+        mDragPadding[0] = t;
+        mDragPadding[1] = r;
+        mDragPadding[2] = b;
+        mDragPadding[3] = l;
+    }
+
     void setLauncher(Launcher launcher) {
         mLauncher = launcher;
     }
 
-    void setHandle(View view) {
-        mHandle = view;
+    void setOverlappingView(View view) {
+        mOverlappingViews = new View[] { view };
+    }
+    
+    void setOverlappingViews(View[] views) {
+        mOverlappingViews = views;
     }
 
     void setDragAndDropEnabled(boolean enabled) {
@@ -121,10 +130,10 @@
     public void getHitRect(Rect outRect) {
         super.getHitRect(outRect);
         if (LauncherApplication.isScreenXLarge()) {
-            outRect.top -= mOuterDragPadding;
-            outRect.left -= mInnerDragPadding;
-            outRect.bottom += mOuterDragPadding;
-            outRect.right += mOuterDragPadding;
+            outRect.top -= mDragPadding[0];
+            outRect.right += mDragPadding[1];
+            outRect.bottom += mDragPadding[2];
+            outRect.left -= mDragPadding[3];
         }
     }
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 40cd74b..3c1c336 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -19,6 +19,7 @@
 
 import com.android.common.Search;
 import com.android.launcher.R;
+import com.android.launcher2.CustomizePagedView.CustomizationType;
 import com.android.launcher2.Workspace.ShrinkState;
 
 import android.animation.Animator;
@@ -213,7 +214,7 @@
     private TabHost mHomeCustomizationDrawer;
     private boolean mAutoAdvanceRunning = false;
 
-    private PagedView mAllAppsPagedView = null;
+    private AllAppsPagedView mAllAppsPagedView = null;
     private CustomizePagedView mCustomizePagedView = null;
 
     private Bundle mSavedState;
@@ -266,6 +267,19 @@
     private static Drawable.ConstantState sVoiceSearchIcon;
     private static Drawable.ConstantState sAppMarketIcon;
 
+    private CustomizationType getCustomizeFilterForTabTag(String tag) {
+        if (tag.equals(WIDGETS_TAG)) {
+            return CustomizationType.WidgetCustomization;
+        } else if (tag.equals(APPLICATIONS_TAG)) {
+            return CustomizationType.ApplicationCustomization;
+        } else if (tag.equals(WALLPAPERS_TAG)) {
+            return CustomizePagedView.CustomizationType.WallpaperCustomization;
+        } else if (tag.equals(SHORTCUTS_TAG)) {
+            return CustomizePagedView.CustomizationType.ShortcutCustomization;
+        }
+        return CustomizationType.WidgetCustomization;
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -331,39 +345,31 @@
                     .setIndicator(tabView).setContent(contentFactory));
             mHomeCustomizationDrawer.setOnTabChangedListener(new OnTabChangeListener() {
                 public void onTabChanged(String tabId) {
-                    // animate the changing of the tab content by fading pages in and out
-                    final Resources res = getResources();
-                    final int duration = res.getInteger(R.integer.config_tabTransitionTime);
-                    final float alpha = mCustomizePagedView.getAlpha();
-                    ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mCustomizePagedView,
-                            "alpha", alpha, 0.0f);
-                    alphaAnim.setDuration(duration);
-                    alphaAnim.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            String tag = mHomeCustomizationDrawer.getCurrentTabTag();
-                            if (tag == WIDGETS_TAG) {
-                                mCustomizePagedView.setCustomizationFilter(
-                                    CustomizePagedView.CustomizationType.WidgetCustomization);
-                            } else if (tag == APPLICATIONS_TAG) {
-                                mCustomizePagedView.setCustomizationFilter(
-                                        CustomizePagedView.CustomizationType.ApplicationCustomization);
-                            } else if (tag == WALLPAPERS_TAG) {
-                                mCustomizePagedView.setCustomizationFilter(
-                                    CustomizePagedView.CustomizationType.WallpaperCustomization);
-                            } else if (tag == SHORTCUTS_TAG) {
-                                mCustomizePagedView.setCustomizationFilter(
-                                        CustomizePagedView.CustomizationType.ShortcutCustomization);
-                            }
+                    final CustomizePagedView.CustomizationType newType =
+                        getCustomizeFilterForTabTag(tabId);
+                    if (newType != mCustomizePagedView.getCustomizationFilter()) {
+                        // animate the changing of the tab content by fading pages in and out
+                        final Resources res = getResources();
+                        final int duration = res.getInteger(R.integer.config_tabTransitionTime);
+                        final float alpha = mCustomizePagedView.getAlpha();
+                        ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mCustomizePagedView,
+                                "alpha", alpha, 0.0f);
+                        alphaAnim.setDuration(duration);
+                        alphaAnim.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                String tag = mHomeCustomizationDrawer.getCurrentTabTag();
+                                mCustomizePagedView.setCustomizationFilter(newType);
 
-                            final float alpha = mCustomizePagedView.getAlpha();
-                            ValueAnimator alphaAnim = ObjectAnimator.ofFloat(
-                                    mCustomizePagedView, "alpha", alpha, 1.0f);
-                            alphaAnim.setDuration(duration);
-                            alphaAnim.start();
-                        }
-                    });
-                    alphaAnim.start();
+                                final float alpha = mCustomizePagedView.getAlpha();
+                                ValueAnimator alphaAnim = ObjectAnimator.ofFloat(
+                                        mCustomizePagedView, "alpha", alpha, 1.0f);
+                                alphaAnim.setDuration(duration);
+                                alphaAnim.start();
+                            }
+                        });
+                        alphaAnim.start();
+                    }
                 }
             });
         }
@@ -376,6 +382,9 @@
         mSavedState = savedInstanceState;
         restoreState(mSavedState);
 
+        // Update customization drawer _after_ restoring the states
+        mCustomizePagedView.update();
+
         if (PROFILE_STARTUP) {
             android.os.Debug.stopMethodTracing();
         }
@@ -879,6 +888,32 @@
             mFolderInfo = mModel.getFolderById(this, sFolders, id);
             mRestoring = true;
         }
+
+        // Restore the current AllApps drawer tab
+        if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) {
+            String curTab = savedState.getString("allapps_currentTab");
+            if (curTab != null) {
+                AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid;
+                tabhost.setCurrentTabByTag(curTab);
+            }
+            int curPage = savedState.getInt("allapps_currentPage", -1);
+            if (curPage > -1) {
+                mAllAppsPagedView.setRestorePage(curPage);
+            }
+        }
+
+        // Restore the current customization drawer tab
+        if (mHomeCustomizationDrawer != null) {
+            String curTab = savedState.getString("customize_currentTab");
+            if (curTab != null) {
+                // We set this directly so that there is no delay before the tab is set
+                mCustomizePagedView.setCustomizationFilter(getCustomizeFilterForTabTag(curTab));
+                mHomeCustomizationDrawer.setCurrentTabByTag(curTab);
+            }
+
+            // Note: currently we do not restore the page for the customization tray because unlike
+            // AllApps, the page content can change drastically
+        }
     }
 
     /**
@@ -924,7 +959,6 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.setLauncher(this);
             mCustomizePagedView.setDragController(dragController);
-            mCustomizePagedView.update();
         } else {
              ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left);
              hotseatLeft.setContentDescription(mHotseatLabels[0]);
@@ -953,12 +987,16 @@
         deleteZone.setLauncher(this);
         deleteZone.setDragController(dragController);
         int deleteZoneHandleId;
+
+        final View allAppsButton = findViewById(R.id.all_apps_button);
+        final View divider = findViewById(R.id.divider);
+        final View configureButton = findViewById(R.id.configure_button);
+
         if (LauncherApplication.isScreenXLarge()) {
-            deleteZoneHandleId = R.id.all_apps_button;
+            mDeleteZone.setOverlappingViews(new View[] { allAppsButton, divider, configureButton });
         } else {
-            deleteZoneHandleId = R.id.all_apps_button_cluster;
+            deleteZone.setOverlappingView(configureButton);
         }
-        deleteZone.setHandle(findViewById(deleteZoneHandleId));
         dragController.addDragListener(deleteZone);
 
         DeleteZone allAppsDeleteZone = (DeleteZone) findViewById(R.id.all_apps_delete_zone);
@@ -978,17 +1016,10 @@
             allAppsInfoTarget.setDragAndDropEnabled(false);
             View marketButton = findViewById(R.id.market_button);
             if (marketButton != null) {
-                allAppsInfoTarget.setHandle(marketButton);
+                allAppsInfoTarget.setOverlappingView(marketButton);
             }
         }
 
-        ApplicationInfoDropTarget infoButton = (ApplicationInfoDropTarget)findViewById(R.id.info_button);
-        if (infoButton != null) {
-            infoButton.setLauncher(this);
-            infoButton.setHandle(findViewById(R.id.configure_button));
-            dragController.addDragListener(infoButton);
-        }
-
         dragController.setDragScoller(workspace);
         dragController.setScrollView(dragLayer);
         dragController.setMoveTarget(workspace);
@@ -996,9 +1027,6 @@
         // The order here is bottom to top.
         dragController.addDropTarget(workspace);
         dragController.addDropTarget(deleteZone);
-        if (infoButton != null) {
-            dragController.addDropTarget(infoButton);
-        }
         if (allAppsInfoTarget != null) {
             dragController.addDropTarget(allAppsInfoTarget);
         }
@@ -1397,23 +1425,6 @@
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
         // Do not call super here
         mSavedInstanceState = savedInstanceState;
-
-        // Restore the current AllApps drawer tab
-        if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) {
-            String cur = savedInstanceState.getString("allapps_currentTab");
-            if (cur != null) {
-                AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid;
-                tabhost.setCurrentTabByTag(cur);
-            }
-        }
-
-        // Restore the current customization drawer tab
-        if (mHomeCustomizationDrawer != null) {
-            String cur = savedInstanceState.getString("customize_currentTab");
-            if (cur != null) {
-                mHomeCustomizationDrawer.setCurrentTabByTag(cur);
-            }
-        }
     }
 
     @Override
@@ -1452,6 +1463,7 @@
             String currentTabTag = tabhost.getCurrentTabTag();
             if (currentTabTag != null) {
                 outState.putString("allapps_currentTab", currentTabTag);
+                outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage());
             }
         }
 
@@ -2582,7 +2594,7 @@
             hideOrShowToolbarButton(true, allAppsButton, showSeq);
             hideOrShowToolbarButton(true, divider, showSeq);
             hideOrShowToolbarButton(true, configureButton, showSeq);
-            mDeleteZone.setHandle(allAppsButton);
+            mDeleteZone.setOverlappingViews(new View[] { allAppsButton, divider, configureButton });
             break;
         case ALL_APPS:
             hideOrShowToolbarButton(false, configureButton, hideSeq);
@@ -2595,7 +2607,7 @@
             hideOrShowToolbarButton(false, searchButton, hideSeq);
             hideOrShowToolbarButton(false, divider, hideSeq);
             hideOrShowToolbarButton(false, configureButton, hideSeq);
-            mDeleteZone.setHandle(allAppsButton);
+            //mDeleteZone.setOverlappingView(configureButton);
             break;
         }
     }
@@ -3261,7 +3273,7 @@
         }
     }
 
-    void setAllAppsPagedView(PagedView view) {
+    void setAllAppsPagedView(AllAppsPagedView view) {
         mAllAppsPagedView = view;
     }
 
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 8483f95..68833f9 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -73,6 +73,7 @@
 
     protected int mCurrentPage;
     protected int mNextPage = INVALID_PAGE;
+    protected int mRestorePage = -1;
     protected int mMaxScrollX;
     protected Scroller mScroller;
     private VelocityTracker mVelocityTracker;
@@ -279,9 +280,8 @@
 
         mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1));
         updateCurrentPageScroll();
-
-        invalidate();
         notifyPageSwitchListener();
+        invalidate();
     }
 
     protected void notifyPageSwitchListener() {
@@ -1219,22 +1219,6 @@
         invalidate();
     }
 
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        final SavedState state = new SavedState(super.onSaveInstanceState());
-        state.currentPage = mCurrentPage;
-        return state;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState savedState = (SavedState) state;
-        super.onRestoreInstanceState(savedState.getSuperState());
-        if (savedState.currentPage != -1) {
-            mCurrentPage = savedState.currentPage;
-        }
-    }
-
     public void scrollLeft() {
         if (mScroller.isFinished()) {
             if (mCurrentPage > 0) snapToPage(mCurrentPage - 1);
@@ -1417,6 +1401,10 @@
         }
     }
 
+    public void setRestorePage(int restorePage) {
+        mRestorePage = restorePage;
+    }
+
     /**
      * This method is called ONLY to synchronize the number of pages that the paged view has.
      * To actually fill the pages with information, implement syncPageItems() below.  It is
@@ -1443,6 +1431,12 @@
                 mDirtyPageContent.add(true);
             }
 
+            // Use the restore page if necessary
+            if (mRestorePage > -1) {
+                mCurrentPage = mRestorePage;
+                mRestorePage = -1;
+            }
+
             // Load any pages that are necessary for the current window of views
             loadAssociatedPages(mCurrentPage);
             mDirtyPageAlpha = true;
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 28b6ff9..a066a16 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -171,7 +171,7 @@
     // in all apps or customize mode)
     private boolean mIsSmall = false;
     private boolean mIsInUnshrinkAnimation = false;
-    private AnimatorListener mShrinkAnimationListener, mUnshrinkAnimationListener;
+    private AnimatorListener mUnshrinkAnimationListener;
     enum ShrinkState { TOP, SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE };
     private ShrinkState mShrinkState;
     private boolean mWasSpringLoadedOnDragExit = false;
@@ -198,9 +198,6 @@
     // Paint used to draw external drop outline
     private final Paint mExternalDragOutlinePaint = new Paint();
 
-    /** Used to trigger an animation as soon as the workspace stops scrolling. */
-    private Animator mAnimOnPageEndMoving = null;
-
     // Camera and Matrix used to determine the final position of a neighboring CellLayout
     private final Matrix mMatrix = new Matrix();
     private final Camera mCamera = new Camera();
@@ -527,11 +524,6 @@
         if (!mDragController.dragging()) {
             hideOutlines();
         }
-        // Check for an animation that's waiting to be started
-        if (mAnimOnPageEndMoving != null) {
-            mAnimOnPageEndMoving.start();
-            mAnimOnPageEndMoving = null;
-        }
         mOverScrollMaxBackgroundAlpha = 0.0f;
         mOverScrollPageIndex = -1;
         mPageMoving = false;
@@ -1557,12 +1549,7 @@
         });
 
         view.setVisibility(View.INVISIBLE);
-
-        if (!mScroller.isFinished()) {
-            mAnimOnPageEndMoving = mDropAnim;
-        } else {
-            mDropAnim.start();
-        }
+        mDropAnim.start();
     }
 
     /**
@@ -2230,13 +2217,6 @@
                 localPixelX, localPixelY, spanX, spanY, ignoreView, recycle);
     }
 
-    /**
-     * Estimate the size that a child with the given dimensions will take in the current screen.
-     */
-    void estimateChildSize(int minWidth, int minHeight, int[] result) {
-        ((CellLayout)getChildAt(mCurrentPage)).estimateChildSize(minWidth, minHeight, result);
-    }
-
     void setLauncher(Launcher launcher) {
         mLauncher = launcher;
         mSpringLoadedDragController = new SpringLoadedDragController(mLauncher);