merge in ics-release history after reset to master
diff --git a/res/layout-land/hotseat.xml b/res/layout-land/hotseat.xml
index f6d2347..c0c87af 100644
--- a/res/layout-land/hotseat.xml
+++ b/res/layout-land/hotseat.xml
@@ -16,6 +16,7 @@
 <com.android.launcher2.Hotseat
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+    android:background="@drawable/hotseat_bg_panel"
     launcher:cellCountX="1"
     launcher:cellCountY="5">
     <com.android.launcher2.CellLayout
diff --git a/res/layout-port/hotseat.xml b/res/layout-port/hotseat.xml
index ee59a6a..035d958 100644
--- a/res/layout-port/hotseat.xml
+++ b/res/layout-port/hotseat.xml
@@ -16,6 +16,7 @@
 <com.android.launcher2.Hotseat
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+    android:background="@drawable/hotseat_bg_panel"
     launcher:cellCountX="5"
     launcher:cellCountY="1">
     <com.android.launcher2.CellLayout
diff --git a/res/layout/wallpaper_chooser.xml b/res/layout/wallpaper_chooser.xml
index c0a5fdf..60d9719 100644
--- a/res/layout/wallpaper_chooser.xml
+++ b/res/layout/wallpaper_chooser.xml
@@ -31,7 +31,8 @@
 
         <Gallery android:id="@+id/gallery"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_height="wrap_content"
+            android:spacing="0dp" />
             
         <Button android:id="@+id/set"
             android:layout_width="wrap_content"
diff --git a/res/layout/wallpaper_item.xml b/res/layout/wallpaper_item.xml
index cfd79e2..0834ce6 100644
--- a/res/layout/wallpaper_item.xml
+++ b/res/layout/wallpaper_item.xml
@@ -16,7 +16,6 @@
 
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/wallpaper_image"
-    android:background="?android:attr/galleryItemBackground"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:scaleType="fitXY"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 65ed04b..78c4b29 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -200,7 +200,7 @@
     <skip />    
 
     <!-- The Google Apps folder name -->
-    <string name="google_apps_folder_name">Google Apps</string>
+    <string name="google_apps_folder_name">Google</string>
 
     <!-- Text to show user in place of a gadget when we can't display it properly -->
     <string name="gadget_error_text">Problem loading widget</string>
diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml
index 5bb6b4b..860e41f 100644
--- a/res/xml/default_workspace.xml
+++ b/res/xml/default_workspace.xml
@@ -37,7 +37,8 @@
     <folder
         launcher:screen="2"
         launcher:x="3"
-        launcher:y="3">
+        launcher:y="3"
+        launcher:title="@string/google_apps_folder_name">
         <favorite
             launcher:packageName="com.google.android.apps.plus"
             launcher:className="com.google.android.apps.plus.phone.HomeActivity" />
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 878cc27..a583415 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -189,6 +189,14 @@
     private final float sWidgetPreviewIconPaddingPercentage = 0.25f;
     private PagedViewCellLayout mWidgetSpacingLayout;
 
+    // Relating to the scroll and overscroll effects
+    Workspace.ZInterpolator mZInterpolator = new Workspace.ZInterpolator(0.5f);
+    private float mDensity;
+    private static float CAMERA_DISTANCE = 3500;
+    private static float TRANSITION_SCALE_FACTOR = 0.6f;
+    private static float TRANSITION_PIVOT = 0.75f;
+    private static float TRANSITION_MAX_ROTATION = 26f;
+
     // Previews & outlines
     ArrayList<AppsCustomizeAsyncTask> mRunningTasks;
     private HolographicOutlineHelper mHolographicOutlineHelper;
@@ -211,6 +219,7 @@
         mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview_holo);
         mAppIconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
         mDragViewMultiplyColor = resources.getColor(R.color.drag_view_multiply_color);
+        mDensity = resources.getDisplayMetrics().density;
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
         // TODO-APPS_CUSTOMIZE: remove these unnecessary attrs after
@@ -265,7 +274,7 @@
             int currentPage = getCurrentPage();
             switch (mContentType) {
             case Applications: {
-                PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(currentPage);
+                PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(currentPage);
                 PagedViewCellLayoutChildren childrenLayout = layout.getChildrenLayout();
                 int numItemsPerPage = mCellCountX * mCellCountY;
                 int childCount = childrenLayout.getChildCount();
@@ -274,7 +283,7 @@
                 }}
                 break;
             case Widgets: {
-                PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(currentPage);
+                PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(currentPage);
                 int numItemsPerPage = mWidgetCountX * mWidgetCountY;
                 int childCount = layout.getChildCount();
                 if (childCount > 0) {
@@ -526,8 +535,6 @@
         if (!super.beginDragging(v)) return false;
 
         // Go into spring loaded mode (must happen before we startDrag())
-        int currentPageIndex = mLauncher.getWorkspace().getCurrentPage();
-        CellLayout currentPage = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPageIndex);
         mLauncher.enterSpringLoadedDragMode();
 
         if (v instanceof PagedViewIcon) {
@@ -626,11 +633,10 @@
     }
     public void syncAppsPageItems(int page, boolean immediate) {
         // ensure that we have the right number of items on the pages
-        int numPages = getPageCount();
         int numCells = mCellCountX * mCellCountY;
         int startIndex = page * numCells;
         int endIndex = Math.min(startIndex + numCells, mApps.size());
-        PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
+        PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(page);
 
         layout.removeAllViewsOnPage();
         ArrayList<Object> items = new ArrayList<Object>();
@@ -653,8 +659,6 @@
             images.add(info.iconBitmap);
         }
 
-        // Create the hardware layers
-        layout.allowHardwareLayerCreation();
         layout.createHardwareLayers();
 
         if (mFadeInAdjacentScreens) {
@@ -959,6 +963,8 @@
         } else {
             prepareLoadWidgetPreviewsTask(page, items, cellWidth, cellHeight, mWidgetCountX);
         }
+        PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
+        layout.createHardwareLayer();
     }
     private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task,
             AsyncTaskPageData data) {
@@ -997,7 +1003,7 @@
     }
     private void onSyncWidgetPageItems(AsyncTaskPageData data) {
         int page = data.page;
-        PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(page);
+        PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
         // Only set the column count once we have items
         layout.setColumnCount(layout.getCellCountX());
 
@@ -1063,7 +1069,7 @@
         invalidate();
 
         int page = data.page;
-        ViewGroup layout = (ViewGroup) getChildAt(page);
+        ViewGroup layout = (ViewGroup) getPageAt(page);
         if (layout instanceof PagedViewCellLayout) {
             PagedViewCellLayout cl = (PagedViewCellLayout) layout;
             int count = cl.getPageChildCount();
@@ -1115,6 +1121,92 @@
         }
     }
 
+    // We want our pages to be z-ordered such that the further a page is to the left, the higher
+    // it is in the z-order. This is important to insure touch events are handled correctly.
+    View getPageAt(int index) {
+        return getChildAt(getChildCount() - index - 1);
+    }
+
+    // In apps customize, we have a scrolling effect which emulates pulling cards off of a stack.
+    @Override
+    protected void screenScrolled(int screenCenter) {
+        super.screenScrolled(screenCenter);
+        final int halfScreenSize = getMeasuredWidth() / 2;
+
+        for (int i = 0; i < getChildCount(); i++) {
+            View v = getPageAt(i);
+            if (v != null) {
+                int totalDistance = getScaledMeasuredWidth(v) + mPageSpacing;
+                int delta = screenCenter - (getChildOffset(i) -
+                        getRelativeChildOffset(i) + halfScreenSize);
+
+                float scrollProgress = delta / (totalDistance * 1.0f);
+                scrollProgress = Math.min(scrollProgress, 1.0f);
+                scrollProgress = Math.max(scrollProgress, -1.0f);
+
+                float interpolatedProgress =
+                        mZInterpolator.getInterpolation(Math.abs(Math.min(scrollProgress, 0)));
+                float scale = (1 - interpolatedProgress) +
+                        interpolatedProgress * TRANSITION_SCALE_FACTOR;
+                float translationX = Math.min(0, scrollProgress) * v.getMeasuredWidth();
+                float alpha = scrollProgress < 0 ? 1 - Math.abs(scrollProgress) : 1.0f;
+
+                v.setCameraDistance(mDensity * CAMERA_DISTANCE);
+                int pageWidth = v.getMeasuredWidth();
+                int pageHeight = v.getMeasuredHeight();
+                if (i == 0 && scrollProgress < 0) {
+                    // Overscroll to the left
+                    v.setPivotX(TRANSITION_PIVOT * pageWidth);
+                    v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress);
+                    scale = 1.0f;
+                    alpha = 1.0f;
+                    // On the first page, we don't want the page to have any lateral motion
+                    translationX = getScrollX();
+                } else if (i == getChildCount() - 1 && scrollProgress > 0) {
+                    // Overscroll to the right
+                    v.setPivotX((1 - TRANSITION_PIVOT) * pageWidth);
+                    v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress);
+                    scale = 1.0f;
+                    alpha = 1.0f;
+                    // On the last page, we don't want the page to have any lateral motion.
+                    translationX =  getScrollX() - mMaxScrollX;
+                } else {
+                    v.setPivotY(pageHeight / 2.0f);
+                    v.setPivotX(pageWidth / 2.0f);
+                    v.setRotationY(0f);
+                }
+
+                v.setTranslationX(translationX);
+                v.setScaleX(scale);
+                v.setScaleY(scale);
+                v.setAlpha(alpha);
+            }
+        }
+    }
+
+    protected void overScroll(float amount) {
+        int screenSize = getMeasuredWidth();
+
+        // We want to reach the max overscroll effect when the user has
+        // overscrolled half the size of the screen
+        float f = 2 * (amount / screenSize);
+
+        if (f == 0) return;
+
+        // Clamp this factor, f, to -1 < f < 1
+        if (Math.abs(f) >= 1) {
+            f /= Math.abs(f);
+        }
+
+        int overScrollAmount = (int) Math.round(f * screenSize);
+        if (amount < 0) {
+            mScrollX = overScrollAmount;
+        } else {
+            mScrollX = mMaxScrollX + overScrollAmount;
+        }
+        invalidate();
+    }
+
     /**
      * Used by the parent to get the content width to set the tab bar to
      * @return
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index d6ae145..124cf73 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -138,10 +138,10 @@
                 // Set the width and show the tab bar (if we have a loading graphic, we can switch
                 // it off here)
                 mTabs.getLayoutParams().width = contentWidth;
-                mTabsContainer.setAlpha(1f);
                 post(new Runnable() {
                     public void run() {
                         mTabs.requestLayout();
+                        mTabsContainer.setAlpha(1f);
                     }
                 });
             }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 6ff46f8..255bf06 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -75,9 +75,9 @@
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
+import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.View.OnLongClickListener;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.InputMethodManager;
@@ -229,9 +229,9 @@
     private final int mRestoreScreenOrientationDelay = 500;
 
     // External icons saved in case of resource changes, orientation, etc.
-    private static Drawable.ConstantState sGlobalSearchIcon;
-    private static Drawable.ConstantState sVoiceSearchIcon;
-    private static Drawable.ConstantState sAppMarketIcon;
+    private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];
+    private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
+    private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];
 
     private DragLayer mDragLayer;
 
@@ -305,18 +305,20 @@
         registerReceiver(mCloseSystemDialogsReceiver, filter);
 
         // If we have a saved version of these external icons, we load them up immediately
-        if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) {
+        int coi = getCurrentOrientationIndexForGlobalIcons();
+        if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null ||
+                sAppMarketIcon[coi] == null) {
             updateIconsAffectedByPackageManagerChanges();
             updateGlobalSearchIcon();
         }
-        if (sGlobalSearchIcon != null) {
-             updateGlobalSearchIcon(sGlobalSearchIcon);
+        if (sGlobalSearchIcon[coi] != null) {
+             updateGlobalSearchIcon(sGlobalSearchIcon[coi]);
         }
-        if (sVoiceSearchIcon != null) {
-            updateVoiceSearchIcon(sVoiceSearchIcon);
+        if (sVoiceSearchIcon[coi] != null) {
+            updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
         }
-        if (sAppMarketIcon != null) {
-            updateAppMarketIcon(sAppMarketIcon);
+        if (sAppMarketIcon[coi] != null) {
+            updateAppMarketIcon(sAppMarketIcon[coi]);
         }
     }
 
@@ -1283,14 +1285,23 @@
         }
 
         super.onCreateOptionsMenu(menu);
+
+        Intent manageApps = new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS);
+        manageApps.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
         Intent settings = new Intent(android.provider.Settings.ACTION_SETTINGS);
         settings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        Intent help = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help_url)));
+        help.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+
         menu.add(MENU_GROUP_WALLPAPER, MENU_WALLPAPER_SETTINGS, 0, R.string.menu_wallpaper)
             .setIcon(android.R.drawable.ic_menu_gallery)
             .setAlphabeticShortcut('W');
         menu.add(0, MENU_MANAGE_APPS, 0, R.string.menu_manage_apps)
             .setIcon(android.R.drawable.ic_menu_manage)
+            .setIntent(manageApps)
             .setAlphabeticShortcut('M');
         menu.add(0, MENU_SYSTEM_SETTINGS, 0, R.string.menu_settings)
             .setIcon(android.R.drawable.ic_menu_preferences)
@@ -1298,6 +1309,7 @@
             .setAlphabeticShortcut('P');
         menu.add(0, MENU_HELP, 0, R.string.menu_help)
             .setIcon(android.R.drawable.ic_menu_help)
+            .setIntent(help)
             .setAlphabeticShortcut('H');
         return true;
     }
@@ -1321,12 +1333,6 @@
         case MENU_WALLPAPER_SETTINGS:
             startWallpaper();
             return true;
-        case MENU_MANAGE_APPS:
-            manageApps();
-            return true;
-        case MENU_HELP:
-            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help_url))));
-            return true;
         }
 
         return super.onOptionsItemSelected(item);
@@ -1357,10 +1363,6 @@
         mPendingAddInfo.dropPos = null;
     }
 
-    private void manageApps() {
-        startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS));
-    }
-
     void addAppWidgetFromPick(Intent data) {
         // TODO: catch bad widget exception when sent
         int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
@@ -1678,7 +1680,7 @@
 
     private void startVoiceSearch() {
         Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
         startActivity(intent);
     }
 
@@ -1702,6 +1704,7 @@
         String packageName = componentName.getPackageName();
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                 Uri.fromParts("package", packageName, null));
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
         startActivity(intent);
     }
 
@@ -1716,6 +1719,8 @@
             String className = appInfo.componentName.getClassName();
             Intent intent = new Intent(
                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
             startActivity(intent);
         }
     }
@@ -2299,6 +2304,8 @@
     }
 
     void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, boolean extendedDelay) {
+        if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;
+
         mHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
@@ -2452,6 +2459,17 @@
         }
     }
 
+    /** Maps the current orientation to an index for referencing orientation correct global icons */
+    private int getCurrentOrientationIndexForGlobalIcons() {
+        // default - 0, landscape - 1
+        switch (getResources().getConfiguration().orientation) {
+        case Configuration.ORIENTATION_LANDSCAPE:
+            return 1;
+        default:
+            return 0;
+        }
+    }
+
     private Drawable getExternalPackageToolbarIcon(ComponentName activityName) {
         try {
             PackageManager packageManager = getPackageManager();
@@ -2538,7 +2556,8 @@
                 (SearchManager) getSystemService(Context.SEARCH_SERVICE);
         ComponentName activityName = searchManager.getGlobalSearchActivity();
         if (activityName != null) {
-            sGlobalSearchIcon = updateButtonWithIconFromExternalActivity(
+            int coi = getCurrentOrientationIndexForGlobalIcons();
+            sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
                     R.id.search_button, activityName, R.drawable.ic_search_normal_holo);
             searchButton.setVisibility(View.VISIBLE);
             if (searchDivider != null) searchDivider.setVisibility(View.VISIBLE);
@@ -2561,7 +2580,8 @@
         Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
         ComponentName activityName = intent.resolveActivity(getPackageManager());
         if (activityName != null) {
-            sVoiceSearchIcon = updateButtonWithIconFromExternalActivity(
+            int coi = getCurrentOrientationIndexForGlobalIcons();
+            sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
                     R.id.voice_button, activityName, R.drawable.ic_voice_search_holo);
             if (searchDivider != null) searchDivider.setVisibility(View.VISIBLE);
             voiceButton.setVisibility(View.VISIBLE);
@@ -2585,8 +2605,9 @@
         // (If multiple app markets are installed, it will return the ResolverActivity.)
         ComponentName activityName = intent.resolveActivity(getPackageManager());
         if (activityName != null) {
+            int coi = getCurrentOrientationIndexForGlobalIcons();
             mAppMarketIntent = intent;
-            sAppMarketIcon = updateTextButtonWithIconFromExternalActivity(
+            sAppMarketIcon[coi] = updateTextButtonWithIconFromExternalActivity(
                     R.id.market_button, activityName, R.drawable.ic_launcher_market_holo);
             marketButton.setVisibility(View.VISIBLE);
         } else {
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index c7bd670..5281f32 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -671,6 +671,7 @@
                     oldTask.stopLocked();
                 }
                 mLoaderTask = new LoaderTask(context, isLaunching);
+                sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                 sWorker.post(mLoaderTask);
             }
         }
@@ -810,6 +811,11 @@
                     if (DEBUG_LOADERS) Log.d(TAG, "step 2: special: loading workspace");
                     loadAndBindWorkspace();
                 }
+
+                // Restore the default thread priority after we are done loading items
+                synchronized (mLock) {
+                    android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+                }
             }
 
 
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 76fa937..9f9450c 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -441,7 +441,7 @@
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             // disallowing padding in paged view (just pass 0)
-            final View child = getChildAt(i);
+            final View child = getPageAt(i);
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
 
             int childWidthMode;
@@ -489,7 +489,7 @@
 
         final int pageCount = getChildCount();
         for (int i = 0; i < pageCount; i++) {
-            View page = (View) getChildAt(i);
+            View page = (View) getPageAt(i);
             page.setX(page.getX() + delta);
         }
         setCurrentPage(newCurrentPage);
@@ -506,7 +506,7 @@
         float childrenX[] = new float[childCount];
         float childrenY[] = new float[childCount];
         for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
+            final View child = getPageAt(i);
             childrenX[i] = child.getX();
             childrenY[i] = child.getY();
         }
@@ -517,7 +517,7 @@
         measure(widthSpec, heightSpec);
         layout(mLeft, mTop, mRight, mBottom);
         for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
+            final View child = getPageAt(i);
             child.setX(childrenX[i]);
             child.setY(childrenY[i]);
         }
@@ -553,7 +553,7 @@
         }
 
         for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
+            final View child = getPageAt(i);
             if (child.getVisibility() != View.GONE) {
                 final int childWidth = getScaledMeasuredWidth(child);
                 final int childHeight = child.getMeasuredHeight();
@@ -586,7 +586,7 @@
                 int screenCenter = mScrollX + halfScreenSize + mPaddingLeft;
                 final int childCount = getChildCount();
                 for (int i = 0; i < childCount; ++i) {
-                    View layout = (View) getChildAt(i);
+                    View layout = (View) getPageAt(i);
                     int childWidth = getScaledMeasuredWidth(layout);
                     int halfChildWidth = (childWidth / 2);
                     int childCenter = getChildOffset(i) + halfChildWidth;
@@ -603,13 +603,13 @@
                     int distanceFromScreenCenter = childCenter - screenCenter;
                     if (distanceFromScreenCenter > 0) {
                         if (i > 0) {
-                            d += getScaledMeasuredWidth(getChildAt(i - 1)) / 2;
+                            d += getScaledMeasuredWidth(getPageAt(i - 1)) / 2;
                         } else {
                             continue;
                         }
                     } else {
                         if (i < childCount - 1) {
-                            d += getScaledMeasuredWidth(getChildAt(i + 1)) / 2;
+                            d += getScaledMeasuredWidth(getPageAt(i + 1)) / 2;
                         } else {
                             continue;
                         }
@@ -663,21 +663,19 @@
         // page.
         final int pageCount = getChildCount();
         if (pageCount > 0) {
-            final int pageWidth = getScaledMeasuredWidth(getChildAt(0));
+            final int pageWidth = getScaledMeasuredWidth(getPageAt(0));
             final int screenWidth = getMeasuredWidth();
             int x = getScaledRelativeChildOffset(0) + pageWidth;
             int leftScreen = 0;
             int rightScreen = 0;
-            while (x <= mScrollX) {
+            while (x <= mScrollX && leftScreen < pageCount - 1) {
                 leftScreen++;
-                x += getScaledMeasuredWidth(getChildAt(leftScreen)) + mPageSpacing;
+                x += getScaledMeasuredWidth(getPageAt(leftScreen)) + mPageSpacing;
             }
             rightScreen = leftScreen;
-            while (x < mScrollX + screenWidth && rightScreen < pageCount) {
+            while (x < mScrollX + screenWidth && rightScreen < pageCount - 1) {
                 rightScreen++;
-                if (rightScreen < pageCount) {
-                    x += getScaledMeasuredWidth(getChildAt(rightScreen)) + mPageSpacing;
-                }
+                x += getScaledMeasuredWidth(getPageAt(rightScreen)) + mPageSpacing;
             }
             rightScreen = Math.min(getChildCount() - 1, rightScreen);
 
@@ -687,8 +685,8 @@
             canvas.clipRect(mScrollX, mScrollY, mScrollX + mRight - mLeft,
                     mScrollY + mBottom - mTop);
 
-            for (int i = leftScreen; i <= rightScreen; i++) {
-                drawChild(canvas, getChildAt(i), drawingTime);
+            for (int i = rightScreen; i >= leftScreen; i--) {
+                drawChild(canvas, getPageAt(i), drawingTime);
             }
             canvas.restore();
         }
@@ -787,7 +785,7 @@
         if (disallowIntercept) {
             // We need to make sure to cancel our long press if
             // a scrollable widget takes over touch events
-            final View currentPage = getChildAt(mCurrentPage);
+            final View currentPage = getPageAt(mCurrentPage);
             currentPage.cancelLongPress();
         }
         super.requestDisallowInterceptTouchEvent(disallowIntercept);
@@ -1092,7 +1090,7 @@
                 // in the opposite direction, we use a threshold to determine whether we should
                 // just return to the starting page, or if we should skip one further.
                 boolean returnToOriginalPage = false;
-                final int pageWidth = getScaledMeasuredWidth(getChildAt(mCurrentPage));
+                final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
                 if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
                         Math.signum(velocityX) != Math.signum(deltaX)) {
                     returnToOriginalPage = true;
@@ -1241,7 +1239,7 @@
         int right;
         for (int i = 0; i < childCount; ++i) {
             left = getRelativeChildOffset(i);
-            right = (left + getScaledMeasuredWidth(getChildAt(i)));
+            right = (left + getScaledMeasuredWidth(getPageAt(i)));
             if (left <= relativeOffset && relativeOffset <= right) {
                 return i;
             }
@@ -1259,7 +1257,7 @@
     protected int getChildWidth(int index) {
         // This functions are called enough times that it actually makes a difference in the
         // profiler -- so just inline the max() here
-        final int measuredWidth = getChildAt(index).getMeasuredWidth();
+        final int measuredWidth = getPageAt(index).getMeasuredWidth();
         final int minWidth = mMinimumWidth;
         return (minWidth > measuredWidth) ? minWidth : measuredWidth;
     }
@@ -1271,7 +1269,7 @@
     protected int getScaledRelativeChildOffset(int index) {
         int padding = mPaddingLeft + mPaddingRight;
         return mPaddingLeft + (getMeasuredWidth() - padding -
-                getScaledMeasuredWidth(getChildAt(index))) / 2;
+                getScaledMeasuredWidth(getPageAt(index))) / 2;
     }
 
     protected int getChildOffset(int index) {
@@ -1280,7 +1278,7 @@
 
         int offset = getRelativeChildOffset(0);
         for (int i = 0; i < index; ++i) {
-            offset += getScaledMeasuredWidth(getChildAt(i)) + mPageSpacing;
+            offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
         }
         return offset;
     }
@@ -1295,12 +1293,12 @@
     }
 
     int getPageNearestToCenterOfScreen() {
-        int minDistanceFromScreenCenter = getMeasuredWidth();
+        int minDistanceFromScreenCenter = Integer.MAX_VALUE;
         int minDistanceFromScreenCenterIndex = -1;
         int screenCenter = mScrollX + (getMeasuredWidth() / 2);
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; ++i) {
-            View layout = (View) getChildAt(i);
+            View layout = (View) getPageAt(i);
             int childWidth = getScaledMeasuredWidth(layout);
             int halfChildWidth = (childWidth / 2);
             int childCenter = getChildOffset(i) + halfChildWidth;
@@ -1395,7 +1393,7 @@
 
         View focusedChild = getFocusedChild();
         if (focusedChild != null && whichPage != mCurrentPage &&
-                focusedChild == getChildAt(mCurrentPage)) {
+                focusedChild == getPageAt(mCurrentPage)) {
             focusedChild.clearFocus();
         }
 
@@ -1441,7 +1439,7 @@
             ViewParent vp = v.getParent();
             int count = getChildCount();
             for (int i = 0; i < count; i++) {
-                if (vp == getChildAt(i)) {
+                if (vp == getPageAt(i)) {
                     return i;
                 }
             }
@@ -1509,7 +1507,7 @@
                     if ((i != page) && immediateAndOnly) {
                         continue;
                     }
-                    Page layout = (Page) getChildAt(i);
+                    Page layout = (Page) getPageAt(i);
                     final int childCount = layout.getPageChildCount();
                     if (lowerPageBound <= i && i <= upperPageBound) {
                         if (mDirtyPageContent.get(i)) {
@@ -1559,7 +1557,7 @@
         ArrayList<Checkable> checked = new ArrayList<Checkable>();
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; ++i) {
-            Page layout = (Page) getChildAt(i);
+            Page layout = (Page) getPageAt(i);
             final int grandChildCount = layout.getPageChildCount();
             for (int j = 0; j < grandChildCount; ++j) {
                 final View v = layout.getChildOnPageAt(j);
@@ -1579,7 +1577,7 @@
         if (mChoiceMode != CHOICE_MODE_MULTIPLE) {
             final int childCount = getChildCount();
             for (int i = 0; i < childCount; ++i) {
-                Page layout = (Page) getChildAt(i);
+                Page layout = (Page) getPageAt(i);
                 final int grandChildCount = layout.getPageChildCount();
                 for (int j = 0; j < grandChildCount; ++j) {
                     final View v = layout.getChildOnPageAt(j);
@@ -1778,11 +1776,13 @@
         int numPages = getChildCount();
         int pageWidth = getMeasuredWidth();
         int maxPageWidth = (numPages * getChildWidth(0)) + ((numPages - 1) * mPageSpacing);
+        int maxScrollPosition = maxPageWidth - pageWidth; // n-1 * pageWidth
         int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
         int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
                 mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
 
-        float offset = (float) getScrollX() / maxPageWidth;
+        float offset = (float) Math.max(0f, Math.min(maxScrollPosition, getScrollX()))
+                / maxPageWidth;
         int indicatorSpace = trackWidth / numPages;
         int indicatorPos = (int) (offset * trackWidth) + mScrollIndicatorPaddingLeft;
         if (hasElasticScrollIndicator()) {
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 803e700..29dc352 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -47,9 +47,6 @@
     private int mHeightGap;
     private int mMaxGap;
     protected PagedViewCellLayoutChildren mChildren;
-    private PagedViewCellLayoutChildren mHolographicChildren;
-    private boolean mAllowHardwareLayerCreation = false;
-    private boolean mCreateHardwareLayersIfAllowed = false;
 
     public PagedViewCellLayout(Context context) {
         this(context, null);
@@ -80,12 +77,6 @@
         mChildren.setGap(mWidthGap, mHeightGap);
 
         addView(mChildren);
-        mHolographicChildren = new PagedViewCellLayoutChildren(context);
-        mHolographicChildren.setAlpha(0f);
-        mHolographicChildren.setCellDimensions(mCellWidth, mCellHeight);
-        mHolographicChildren.setGap(mWidthGap, mHeightGap);
-
-        addView(mHolographicChildren);
     }
 
     public int getCellWidth() {
@@ -96,41 +87,20 @@
         return mCellHeight;
     }
 
-    public void allowHardwareLayerCreation() {
-        // This is called after the first time we launch into All Apps. Before that point,
-        // there's no need for hardware layers here since there's a hardware layer set on the
-        // parent, AllAppsTabbed, during the AllApps transition -- creating hardware layers here
-        // before the animation is done slows down the animation
-        if (!mAllowHardwareLayerCreation) {
-            mAllowHardwareLayerCreation = true;
-            if (mCreateHardwareLayersIfAllowed) {
-                createHardwareLayers();
-            }
-        }
-    }
-
     @Override
     public void setAlpha(float alpha) {
-        mChildren.setAlpha(HolographicOutlineHelper.viewAlphaInterpolator(alpha));
-        mHolographicChildren.setAlpha(HolographicOutlineHelper.highlightAlphaInterpolator(alpha));
+        mChildren.setAlpha(alpha);
     }
 
     void destroyHardwareLayers() {
         // called when a page is no longer visible (triggered by loadAssociatedPages ->
         // removeAllViewsOnPage)
-        mCreateHardwareLayersIfAllowed = false;
-        if (mAllowHardwareLayerCreation) {
-            mChildren.destroyHardwareLayer();
-            mHolographicChildren.destroyHardwareLayer();
-        }
+        mChildren.destroyHardwareLayer();
     }
+
     void createHardwareLayers() {
         // called when a page is visible (triggered by loadAssociatedPages -> syncPageItems)
-        mCreateHardwareLayersIfAllowed = true;
-        if (mAllowHardwareLayerCreation) {
-            mChildren.createHardwareLayer();
-            mHolographicChildren.createHardwareLayer();
-        }
+        mChildren.createHardwareLayer();
     }
 
     @Override
@@ -163,11 +133,7 @@
 
             if (child instanceof PagedViewIcon) {
                 PagedViewIcon pagedViewIcon = (PagedViewIcon) child;
-                if (mAllowHardwareLayerCreation) {
-                    pagedViewIcon.disableCache();
-                }
-                mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(),
-                        index, lp);
+                pagedViewIcon.disableCache();
             }
             return true;
         }
@@ -177,14 +143,12 @@
     @Override
     public void removeAllViewsOnPage() {
         mChildren.removeAllViews();
-        mHolographicChildren.removeAllViews();
         destroyHardwareLayers();
     }
 
     @Override
     public void removeViewOnPageAt(int index) {
         mChildren.removeViewAt(index);
-        mHolographicChildren.removeViewAt(index);
     }
 
     @Override
@@ -237,7 +201,6 @@
             mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
 
             mChildren.setGap(mWidthGap, mHeightGap);
-            mHolographicChildren.setGap(mWidthGap, mHeightGap);
         } else {
             mWidthGap = mOriginalWidthGap;
             mHeightGap = mOriginalHeightGap;
@@ -317,13 +280,11 @@
 
     public void enableCenteredContent(boolean enabled) {
         mChildren.enableCenteredContent(enabled);
-        mHolographicChildren.enableCenteredContent(enabled);
     }
 
     @Override
     protected void setChildrenDrawingCacheEnabled(boolean enabled) {
         mChildren.setChildrenDrawingCacheEnabled(enabled);
-        mHolographicChildren.setChildrenDrawingCacheEnabled(enabled);
     }
 
     public void setCellCount(int xCount, int yCount) {
@@ -336,7 +297,6 @@
         mWidthGap = widthGap;
         mHeightGap = heightGap;
         mChildren.setGap(widthGap, heightGap);
-        mHolographicChildren.setGap(widthGap, heightGap);
     }
 
     public int[] getCellCountForDimensions(int width, int height) {
diff --git a/src/com/android/launcher2/PagedViewCellLayoutChildren.java b/src/com/android/launcher2/PagedViewCellLayoutChildren.java
index 0907c60..eaef682 100644
--- a/src/com/android/launcher2/PagedViewCellLayoutChildren.java
+++ b/src/com/android/launcher2/PagedViewCellLayoutChildren.java
@@ -142,14 +142,10 @@
     }
 
     void destroyHardwareLayer() {
-        if (getLayerType() != LAYER_TYPE_NONE) {
-            setLayerType(LAYER_TYPE_NONE, null);
-        }
+        setLayerType(LAYER_TYPE_NONE, null);
     }
     void createHardwareLayer() {
-        if (getLayerType() != LAYER_TYPE_HARDWARE) {
-            setLayerType(LAYER_TYPE_HARDWARE, null);
-        }
+        setLayerType(LAYER_TYPE_HARDWARE, null);
     }
 
     public void enableCenteredContent(boolean enabled) {
diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java
index 4131d8b..93626f0 100644
--- a/src/com/android/launcher2/PagedViewGridLayout.java
+++ b/src/com/android/launcher2/PagedViewGridLayout.java
@@ -40,6 +40,7 @@
     int getCellCountX() {
         return mCellCountX;
     }
+
     int getCellCountY() {
         return mCellCountY;
     }
@@ -69,27 +70,18 @@
         return result;
     }
 
-    @Override
-    protected boolean onSetAlpha(int alpha) {
-        return true;
+    void destroyHardwareLayer() {
+        setLayerType(LAYER_TYPE_NONE, null);
     }
 
-    @Override
-    public void setAlpha(float alpha) {
-        setChildrenAlpha(alpha);
-        super.setAlpha(alpha);
-    }
-
-    private void setChildrenAlpha(float alpha) {
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            getChildAt(i).setAlpha(alpha);
-        }
+    void createHardwareLayer() {
+        setLayerType(LAYER_TYPE_HARDWARE, null);
     }
 
     @Override
     public void removeAllViewsOnPage() {
         removeAllViews();
+        destroyHardwareLayer();
     }
 
     @Override