diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index bc3e341..8df5412 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -21,7 +21,6 @@
 
 import com.android.launcher3.accessibility.DragViewStateAnnouncer;
 import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.util.FocusLogic;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
@@ -476,7 +475,7 @@
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         // Clear the frame and give focus to the widget host view when a directional key is pressed.
-        if (FocusLogic.shouldConsume(keyCode)) {
+        if (shouldConsume(keyCode)) {
             close(false);
             mWidgetView.requestFocus();
             return true;
@@ -599,4 +598,14 @@
             return moveEnd ? out.size() - size() : size() - out.size();
         }
     }
+
+    /**
+     * Returns true only if this utility class handles the key code.
+     */
+    public static boolean shouldConsume(int keyCode) {
+        return (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);
+    }
 }
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
deleted file mode 100644
index e5aecf7..0000000
--- a/src/com/android/launcher3/FocusHelper.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * 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;
-
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderPagedView;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.FocusLogic;
-import com.android.launcher3.util.Thunk;
-
-/**
- * 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);
-    }
-}
-
-/**
- * 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) {
-        return FocusHelper.handleHotseatButtonKeyEvent(v, keyCode, event);
-    }
-}
-
-/**
- * A keyboard listener we set on full screen pages (e.g. custom content).
- */
-class FullscreenKeyEventListener implements View.OnKeyListener {
-    @Override
-    public boolean onKey(View v, int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
-                || keyCode == KeyEvent.KEYCODE_PAGE_DOWN || keyCode == KeyEvent.KEYCODE_PAGE_UP) {
-            // Handle the key event just like a workspace icon would in these cases. In this case,
-            // it will basically act as if there is a single icon in the top left (so you could
-            // think of the fullscreen page as a focusable fullscreen widget).
-            return FocusHelper.handleIconKeyEvent(v, keyCode, event);
-        }
-        return false;
-    }
-}
-
-/**
- * TODO: Reevaluate if this is still required
- */
-public class FocusHelper {
-
-    private static final String TAG = "FocusHelper";
-    private static final boolean DEBUG = false;
-
-    /**
-     * Handles key events in paged folder.
-     */
-    public static class PagedFolderKeyEventListener implements View.OnKeyListener {
-
-        private final Folder mFolder;
-
-        public PagedFolderKeyEventListener(Folder folder) {
-            mFolder = folder;
-        }
-
-        @Override
-        public boolean onKey(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 Folders keyevent=[%s].",
-                        KeyEvent.keyCodeToString(keyCode)));
-            }
-
-            if (!(v.getParent() instanceof ShortcutAndWidgetContainer)) {
-                if (FeatureFlags.IS_STUDIO_BUILD) {
-                    throw new IllegalStateException("Parent of the focused item is not supported.");
-                } else {
-                    return false;
-                }
-            }
-
-            // Initialize variables.
-            final ShortcutAndWidgetContainer itemContainer = (ShortcutAndWidgetContainer) v.getParent();
-            final CellLayout cellLayout = (CellLayout) itemContainer.getParent();
-
-            final int iconIndex = itemContainer.indexOfChild(v);
-            final FolderPagedView pagedView = (FolderPagedView) cellLayout.getParent();
-
-            final int pageIndex = pagedView.indexOfChild(cellLayout);
-            final int pageCount = pagedView.getPageCount();
-            final boolean isLayoutRtl = Utilities.isRtl(v.getResources());
-
-            int[][] matrix = FocusLogic.createSparseMatrix(cellLayout);
-            // Process focus.
-            int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
-                    pageCount, isLayoutRtl);
-            if (newIconIndex == FocusLogic.NOOP) {
-                handleNoopKey(keyCode, v);
-                return consume;
-            }
-            ShortcutAndWidgetContainer newParent = null;
-            View child = null;
-
-            switch (newIconIndex) {
-                case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN:
-                case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
-                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1);
-                    if (newParent != null) {
-                        int row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY;
-                        pagedView.snapToPage(pageIndex - 1);
-                        child = newParent.getChildAt(
-                                ((newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN)
-                                    ^ newParent.invertLayoutHorizontally()) ? 0 : matrix.length - 1,
-                                row);
-                    }
-                    break;
-                case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
-                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1);
-                    if (newParent != null) {
-                        pagedView.snapToPage(pageIndex - 1);
-                        child = newParent.getChildAt(0, 0);
-                    }
-                    break;
-                case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
-                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex - 1);
-                    if (newParent != null) {
-                        pagedView.snapToPage(pageIndex - 1);
-                        child = newParent.getChildAt(matrix.length - 1, matrix[0].length - 1);
-                    }
-                    break;
-                case FocusLogic.NEXT_PAGE_FIRST_ITEM:
-                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex + 1);
-                    if (newParent != null) {
-                        pagedView.snapToPage(pageIndex + 1);
-                        child = newParent.getChildAt(0, 0);
-                    }
-                    break;
-                case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
-                case FocusLogic.NEXT_PAGE_RIGHT_COLUMN:
-                    newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex + 1);
-                    if (newParent != null) {
-                        pagedView.snapToPage(pageIndex + 1);
-                        child = FocusLogic.getAdjacentChildInNextFolderPage(
-                                newParent, v, newIconIndex);
-                    }
-                    break;
-                case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
-                    child = cellLayout.getChildAt(0, 0);
-                    break;
-                case FocusLogic.CURRENT_PAGE_LAST_ITEM:
-                    child = pagedView.getLastItem();
-                    break;
-                default: // Go to some item on the current page.
-                    child = itemContainer.getChildAt(newIconIndex);
-                    break;
-            }
-            if (child != null) {
-                child.requestFocus();
-                playSoundEffect(keyCode, v);
-            } else {
-                handleNoopKey(keyCode, v);
-            }
-            return consume;
-        }
-
-        public void handleNoopKey(int keyCode, View v) {
-            if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
-                mFolder.mFolderName.requestFocus();
-                playSoundEffect(keyCode, v);
-            }
-        }
-    }
-
-    /**
-     * Handles key events in the workspace hotseat (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;
-        }
-
-        final Launcher launcher = Launcher.getLauncher(v.getContext());
-        final DeviceProfile profile = launcher.getDeviceProfile();
-
-        if (DEBUG) {
-            Log.v(TAG, String.format(
-                    "Handle HOTSEAT BUTTONS keyevent=[%s] on hotseat buttons, isVertical=%s",
-                    KeyEvent.keyCodeToString(keyCode), profile.isVerticalBarLayout()));
-        }
-
-        // Initialize the variables.
-        final Workspace workspace = (Workspace) v.getRootView().findViewById(R.id.workspace);
-        final ShortcutAndWidgetContainer hotseatParent = (ShortcutAndWidgetContainer) v.getParent();
-        final CellLayout hotseatLayout = (CellLayout) hotseatParent.getParent();
-
-        final ItemInfo itemInfo = (ItemInfo) v.getTag();
-        int pageIndex = workspace.getNextPage();
-        int pageCount = workspace.getChildCount();
-        int iconIndex = hotseatParent.indexOfChild(v);
-        int iconRank = ((CellLayout.LayoutParams) hotseatLayout.getShortcutsAndWidgets()
-                .getChildAt(iconIndex).getLayoutParams()).cellX;
-
-        final CellLayout iconLayout = (CellLayout) workspace.getChildAt(pageIndex);
-        if (iconLayout == null) {
-            // This check is to guard against cases where key strokes rushes in when workspace
-            // child creation/deletion is still in flux. (e.g., during drop or fling
-            // animation.)
-            return consume;
-        }
-        final ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
-
-        ViewGroup parent = null;
-        int[][] matrix = null;
-
-        if (keyCode == KeyEvent.KEYCODE_DPAD_UP &&
-                !profile.isVerticalBarLayout()) {
-            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
-            iconIndex += iconParent.getChildCount();
-            parent = iconParent;
-        } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT &&
-                profile.isVerticalBarLayout()) {
-            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
-            iconIndex += iconParent.getChildCount();
-            parent = iconParent;
-        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
-                profile.isVerticalBarLayout()) {
-            keyCode = KeyEvent.KEYCODE_PAGE_DOWN;
-        } 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;
-        }
-
-        // Process the focus.
-        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
-                pageCount, Utilities.isRtl(v.getResources()));
-
-        View newIcon = null;
-        switch (newIconIndex) {
-            case FocusLogic.NEXT_PAGE_FIRST_ITEM:
-                parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
-                newIcon = parent.getChildAt(0);
-                // TODO(hyunyoungs): handle cases where the child is not an icon but
-                // a folder or a widget.
-                workspace.snapToPage(pageIndex + 1);
-                break;
-            case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
-                parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
-                newIcon = parent.getChildAt(0);
-                // TODO(hyunyoungs): handle cases where the child is not an icon but
-                // a folder or a widget.
-                workspace.snapToPage(pageIndex - 1);
-                break;
-            case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
-                parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
-                newIcon = parent.getChildAt(parent.getChildCount() - 1);
-                // TODO(hyunyoungs): handle cases where the child is not an icon but
-                // a folder or a widget.
-                workspace.snapToPage(pageIndex - 1);
-                break;
-            case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
-            case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN:
-                // Go to the previous page but keep the focus on the same hotseat icon.
-                workspace.snapToPage(pageIndex - 1);
-                break;
-            case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
-            case FocusLogic.NEXT_PAGE_RIGHT_COLUMN:
-                // Go to the next page but keep the focus on the same hotseat icon.
-                workspace.snapToPage(pageIndex + 1);
-                break;
-        }
-        if (parent == iconParent && newIconIndex >= iconParent.getChildCount()) {
-            newIconIndex -= iconParent.getChildCount();
-        }
-        if (parent != null) {
-            if (newIcon == null && newIconIndex >= 0) {
-                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;
-        }
-
-        Launcher launcher = Launcher.getLauncher(v.getContext());
-        DeviceProfile profile = launcher.getDeviceProfile();
-
-        if (DEBUG) {
-            Log.v(TAG, String.format("Handle WORKSPACE ICONS keyevent=[%s] isVerticalBar=%s",
-                    KeyEvent.keyCodeToString(keyCode), profile.isVerticalBarLayout()));
-        }
-
-        // Initialize the variables.
-        ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
-        CellLayout iconLayout = (CellLayout) parent.getParent();
-        final Workspace workspace = (Workspace) iconLayout.getParent();
-        final ViewGroup dragLayer = (ViewGroup) workspace.getParent();
-        final ViewGroup tabs = (ViewGroup) dragLayer.findViewById(R.id.drop_target_bar);
-        final Hotseat hotseat = (Hotseat) dragLayer.findViewById(R.id.hotseat);
-
-        final ItemInfo itemInfo = (ItemInfo) v.getTag();
-        final int iconIndex = parent.indexOfChild(v);
-        final int pageIndex = workspace.indexOfChild(iconLayout);
-        final int pageCount = workspace.getChildCount();
-
-        CellLayout hotseatLayout = (CellLayout) hotseat.getChildAt(0);
-        ShortcutAndWidgetContainer hotseatParent = hotseatLayout.getShortcutsAndWidgets();
-        int[][] matrix;
-
-        // KEYCODE_DPAD_DOWN in portrait (KEYCODE_DPAD_RIGHT 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 && !profile.isVerticalBarLayout()) {
-            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
-        } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT &&
-                profile.isVerticalBarLayout()) {
-            matrix = FocusLogic.createSparseMatrixWithHotseat(iconLayout, hotseatLayout, profile);
-        } else {
-            matrix = FocusLogic.createSparseMatrix(iconLayout);
-        }
-
-        // Process the focus.
-        int newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, iconIndex, pageIndex,
-                pageCount, Utilities.isRtl(v.getResources()));
-        boolean isRtl = Utilities.isRtl(v.getResources());
-        View newIcon = null;
-        CellLayout workspaceLayout = (CellLayout) workspace.getChildAt(pageIndex);
-        switch (newIconIndex) {
-            case FocusLogic.NOOP:
-                if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
-                    newIcon = tabs;
-                }
-                break;
-            case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN:
-            case FocusLogic.NEXT_PAGE_RIGHT_COLUMN:
-                int newPageIndex = pageIndex - 1;
-                if (newIconIndex == FocusLogic.NEXT_PAGE_RIGHT_COLUMN) {
-                    newPageIndex = pageIndex + 1;
-                }
-                int row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY;
-                parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
-                if (parent != null) {
-                    iconLayout = (CellLayout) parent.getParent();
-                    matrix = FocusLogic.createSparseMatrixWithPivotColumn(iconLayout,
-                            iconLayout.getCountX(), row);
-                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, FocusLogic.PIVOT,
-                            newPageIndex, pageCount, Utilities.isRtl(v.getResources()));
-                    if (newIconIndex == FocusLogic.NEXT_PAGE_FIRST_ITEM) {
-                        newIcon = handleNextPageFirstItem(workspace, hotseatLayout, pageIndex,
-                                isRtl);
-                    } else if (newIconIndex == FocusLogic.PREVIOUS_PAGE_LAST_ITEM) {
-                        newIcon = handlePreviousPageLastItem(workspace, hotseatLayout, pageIndex,
-                                isRtl);
-                    } else {
-                        newIcon = parent.getChildAt(newIconIndex);
-                    }
-                }
-                break;
-            case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
-                workspaceLayout = (CellLayout) workspace.getChildAt(pageIndex - 1);
-                newIcon = getFirstFocusableIconInReadingOrder(workspaceLayout, isRtl);
-                if (newIcon == null) {
-                    // Check the hotseat if no focusable item was found on the workspace.
-                    newIcon = getFirstFocusableIconInReadingOrder(hotseatLayout, isRtl);
-                    workspace.snapToPage(pageIndex - 1);
-                }
-                break;
-            case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
-                newIcon = handlePreviousPageLastItem(workspace, hotseatLayout, pageIndex, isRtl);
-                break;
-            case FocusLogic.NEXT_PAGE_FIRST_ITEM:
-                newIcon = handleNextPageFirstItem(workspace, hotseatLayout, pageIndex, isRtl);
-                break;
-            case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
-            case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
-                newPageIndex = pageIndex + 1;
-                if (newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN) {
-                    newPageIndex = pageIndex - 1;
-                }
-                row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY;
-                parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
-                if (parent != null) {
-                    iconLayout = (CellLayout) parent.getParent();
-                    matrix = FocusLogic.createSparseMatrixWithPivotColumn(iconLayout, -1, row);
-                    newIconIndex = FocusLogic.handleKeyEvent(keyCode, matrix, FocusLogic.PIVOT,
-                            newPageIndex, pageCount, Utilities.isRtl(v.getResources()));
-                    if (newIconIndex == FocusLogic.NEXT_PAGE_FIRST_ITEM) {
-                        newIcon = handleNextPageFirstItem(workspace, hotseatLayout, pageIndex,
-                                isRtl);
-                    } else if (newIconIndex == FocusLogic.PREVIOUS_PAGE_LAST_ITEM) {
-                        newIcon = handlePreviousPageLastItem(workspace, hotseatLayout, pageIndex,
-                                isRtl);
-                    } else {
-                        newIcon = parent.getChildAt(newIconIndex);
-                    }
-                }
-                break;
-            case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
-                newIcon = getFirstFocusableIconInReadingOrder(workspaceLayout, isRtl);
-                if (newIcon == null) {
-                    // Check the hotseat if no focusable item was found on the workspace.
-                    newIcon = getFirstFocusableIconInReadingOrder(hotseatLayout, isRtl);
-                }
-                break;
-            case FocusLogic.CURRENT_PAGE_LAST_ITEM:
-                newIcon = getFirstFocusableIconInReverseReadingOrder(workspaceLayout, isRtl);
-                if (newIcon == null) {
-                    // Check the hotseat if no focusable item was found on the workspace.
-                    newIcon = getFirstFocusableIconInReverseReadingOrder(hotseatLayout, isRtl);
-                }
-                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;
-    }
-
-    //
-    // Helper methods.
-    //
-
-    /**
-     * Private helper method to get the CellLayoutChildren given a CellLayout index.
-     */
-    @Thunk static ShortcutAndWidgetContainer getCellLayoutChildrenForIndex(
-            ViewGroup container, int i) {
-        CellLayout parent = (CellLayout) container.getChildAt(i);
-        return parent.getShortcutsAndWidgets();
-    }
-
-    /**
-     * Helper method to be used for playing sound effects.
-     */
-    @Thunk static void playSoundEffect(int keyCode, View v) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                v.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                v.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-            case KeyEvent.KEYCODE_PAGE_DOWN:
-            case KeyEvent.KEYCODE_MOVE_END:
-                v.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN);
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_PAGE_UP:
-            case KeyEvent.KEYCODE_MOVE_HOME:
-                v.playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
-                break;
-            default:
-                break;
-        }
-    }
-
-    private static View handlePreviousPageLastItem(Workspace workspace, CellLayout hotseatLayout,
-            int pageIndex, boolean isRtl) {
-        if (pageIndex - 1 < 0) {
-            return null;
-        }
-        CellLayout workspaceLayout = (CellLayout) workspace.getChildAt(pageIndex - 1);
-        View newIcon = getFirstFocusableIconInReverseReadingOrder(workspaceLayout, isRtl);
-        if (newIcon == null) {
-            // Check the hotseat if no focusable item was found on the workspace.
-            newIcon = getFirstFocusableIconInReverseReadingOrder(hotseatLayout,isRtl);
-            workspace.snapToPage(pageIndex - 1);
-        }
-        return newIcon;
-    }
-
-    private static View handleNextPageFirstItem(Workspace workspace, CellLayout hotseatLayout,
-            int pageIndex, boolean isRtl) {
-        if (pageIndex + 1 >= workspace.getPageCount()) {
-            return null;
-        }
-        CellLayout workspaceLayout = (CellLayout) workspace.getChildAt(pageIndex + 1);
-        View newIcon = getFirstFocusableIconInReadingOrder(workspaceLayout, isRtl);
-        if (newIcon == null) {
-            // Check the hotseat if no focusable item was found on the workspace.
-            newIcon = getFirstFocusableIconInReadingOrder(hotseatLayout, isRtl);
-            workspace.snapToPage(pageIndex + 1);
-        }
-        return newIcon;
-    }
-
-    private static View getFirstFocusableIconInReadingOrder(CellLayout cellLayout, boolean isRtl) {
-        View icon;
-        int countX = cellLayout.getCountX();
-        for (int y = 0; y < cellLayout.getCountY(); y++) {
-            int increment = isRtl ? -1 : 1;
-            for (int x = isRtl ? countX - 1 : 0; 0 <= x && x < countX; x += increment) {
-                if ((icon = cellLayout.getChildAt(x, y)) != null && icon.isFocusable()) {
-                    return icon;
-                }
-            }
-        }
-        return null;
-    }
-
-    private static View getFirstFocusableIconInReverseReadingOrder(CellLayout cellLayout,
-            boolean isRtl) {
-        View icon;
-        int countX = cellLayout.getCountX();
-        for (int y = cellLayout.getCountY() - 1; y >= 0; y--) {
-            int increment = isRtl ? 1 : -1;
-            for (int x = isRtl ? 0 : countX - 1; 0 <= x && x < countX; x += increment) {
-                if ((icon = cellLayout.getChildAt(x, y)) != null && icon.isFocusable()) {
-                    return icon;
-                }
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
deleted file mode 100644
index 4f4cccd..0000000
--- a/src/com/android/launcher3/util/FocusLogic.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * 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.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.launcher3.CellLayout;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.ShortcutAndWidgetContainer;
-import com.android.launcher3.config.FeatureFlags;
-
-import java.util.Arrays;
-
-/**
- * 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 = "FocusLogic";
-    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_RIGHT_COLUMN  = -2;
-    public static final int PREVIOUS_PAGE_FIRST_ITEM    = -3;
-    public static final int PREVIOUS_PAGE_LAST_ITEM     = -4;
-    public static final int PREVIOUS_PAGE_LEFT_COLUMN   = -5;
-
-    public static final int CURRENT_PAGE_FIRST_ITEM     = -6;
-    public static final int CURRENT_PAGE_LAST_ITEM      = -7;
-
-    public static final int NEXT_PAGE_FIRST_ITEM        = -8;
-    public static final int NEXT_PAGE_LEFT_COLUMN       = -9;
-    public static final int NEXT_PAGE_RIGHT_COLUMN      = -10;
-
-    public static final int ALL_APPS_COLUMN = -11;
-
-    // Matrix related constant.
-    public static final int EMPTY = -1;
-    public static final int PIVOT = 100;
-
-    /**
-     * Returns true only if this utility class handles the key code.
-     */
-    public static boolean shouldConsume(int keyCode) {
-        return (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);
-    }
-
-    public static int handleKeyEvent(int keyCode, int [][] map, int iconIdx, int pageIndex,
-            int pageCount, boolean isRtl) {
-
-        int cntX = map == null ? -1 : map.length;
-        int cntY = map == null ? -1 : map[0].length;
-
-        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*/, isRtl);
-                if (!isRtl && newIndex == NOOP && pageIndex > 0) {
-                    newIndex = PREVIOUS_PAGE_RIGHT_COLUMN;
-                } else if (isRtl && newIndex == NOOP && pageIndex < pageCount - 1) {
-                    newIndex = NEXT_PAGE_RIGHT_COLUMN;
-                }
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                newIndex = handleDpadHorizontal(iconIdx, cntX, cntY, map, 1 /*increment*/, isRtl);
-                if (!isRtl && newIndex == NOOP && pageIndex < pageCount - 1) {
-                    newIndex = NEXT_PAGE_LEFT_COLUMN;
-                } else if (isRtl && newIndex == NOOP && pageIndex > 0) {
-                    newIndex = PREVIOUS_PAGE_LEFT_COLUMN;
-                }
-                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 {@link #EMPTY}.
-     *
-     * @param m                 number of columns in the matrix
-     * @param n                 number of rows in the matrix
-     */
-    // TODO: get rid of dynamic matrix creation.
-    private static int[][] createFullMatrix(int m, int n) {
-        int[][] matrix = new int [m][n];
-
-        for (int i=0; i < m;i++) {
-            Arrays.fill(matrix[i], 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) {
-        ShortcutAndWidgetContainer parent = layout.getShortcutsAndWidgets();
-        final int m = layout.getCountX();
-        final int n = layout.getCountY();
-        final boolean invert = parent.invertLayoutHorizontally();
-
-        int[][] matrix = createFullMatrix(m, n);
-
-        // Iterate thru the children.
-        for (int i = 0; i < parent.getChildCount(); i++ ) {
-            View cell = parent.getChildAt(i);
-            if (!cell.isFocusable()) {
-                continue;
-            }
-            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
-            int x = invert ? (m - cx - 1) : cx;
-            if (x < m && cy < n) { // check if view fits into matrix, else skip
-                matrix[x][cy] = i;
-            }
-        }
-        if (DEBUG) {
-            printMatrix(matrix);
-        }
-        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[][] createSparseMatrixWithHotseat(
-            CellLayout iconLayout, CellLayout hotseatLayout, DeviceProfile dp) {
-
-        ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
-        ViewGroup hotseatParent = hotseatLayout.getShortcutsAndWidgets();
-
-        boolean isHotseatHorizontal = !dp.isVerticalBarLayout();
-
-        int m, n;
-        if (isHotseatHorizontal) {
-            m = hotseatLayout.getCountX();
-            n = iconLayout.getCountY() + hotseatLayout.getCountY();
-        } else {
-            m = iconLayout.getCountX() + hotseatLayout.getCountX();
-            n = hotseatLayout.getCountY();
-        }
-        int[][] matrix = createFullMatrix(m, n);
-        // Iterate through the children of the workspace.
-        for (int i = 0; i < iconParent.getChildCount(); i++) {
-            View cell = iconParent.getChildAt(i);
-            if (!cell.isFocusable()) {
-                continue;
-            }
-            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
-            matrix[cx][cy] = i;
-        }
-
-        // Iterate thru the children of the hotseat.
-        for (int i = hotseatParent.getChildCount() - 1; i >= 0; i--) {
-            if (isHotseatHorizontal) {
-                int cx = ((CellLayout.LayoutParams)
-                        hotseatParent.getChildAt(i).getLayoutParams()).cellX;
-                matrix[cx][iconLayout.getCountY()] = iconParent.getChildCount() + i;
-            } else {
-                int cy = ((CellLayout.LayoutParams)
-                        hotseatParent.getChildAt(i).getLayoutParams()).cellY;
-                matrix[iconLayout.getCountX()][cy] = iconParent.getChildCount() + i;
-            }
-        }
-        if (DEBUG) {
-            printMatrix(matrix);
-        }
-        return matrix;
-    }
-
-    /**
-     * Creates a sparse matrix that merges the icon of previous/next page and last column of
-     * current page. When left key is triggered on the leftmost column, sparse matrix is created
-     * that combines previous page matrix and an extra column on the right. Likewise, when right
-     * key is triggered on the rightmost column, sparse matrix is created that combines this column
-     * on the 0th column and the next page matrix.
-     *
-     * @param pivotX    x coordinate of the focused item in the current page
-     * @param pivotY    y coordinate of the focused item in the current page
-     */
-    // TODO: get rid of the dynamic matrix creation
-    public static int[][] createSparseMatrixWithPivotColumn(CellLayout iconLayout,
-            int pivotX, int pivotY) {
-
-        ViewGroup iconParent = iconLayout.getShortcutsAndWidgets();
-
-        int[][] matrix = createFullMatrix(iconLayout.getCountX() + 1, iconLayout.getCountY());
-
-        // Iterate thru the children of the top parent.
-        for (int i = 0; i < iconParent.getChildCount(); i++) {
-            View cell = iconParent.getChildAt(i);
-            if (!cell.isFocusable()) {
-                continue;
-            }
-            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
-            if (pivotX < 0) {
-                matrix[cx - pivotX][cy] = i;
-            } else {
-                matrix[cx][cy] = i;
-            }
-        }
-
-        if (pivotX < 0) {
-            matrix[0][pivotY] = PIVOT;
-        } else {
-            matrix[pivotX][pivotY] = PIVOT;
-        }
-        if (DEBUG) {
-            printMatrix(matrix);
-        }
-        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, boolean isRtl) {
-        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 x = xPos + increment; 0 <= x && x < cntX; x += increment) {
-            if ((newIconIndex = inspectMatrix(x, yPos, cntX, cntY, matrix)) != NOOP
-                    && newIconIndex != ALL_APPS_COLUMN) {
-                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;
-        boolean haveCrossedAllAppsColumn1 = false;
-        boolean haveCrossedAllAppsColumn2 = false;
-        int x = -1;
-        for (int coeff = 1; coeff < cntY; coeff++) {
-            nextYPos1 = yPos + coeff * increment;
-            nextYPos2 = yPos - coeff * increment;
-            x = xPos + increment * coeff;
-            if (inspectMatrix(x, nextYPos1, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
-                haveCrossedAllAppsColumn1 = true;
-            }
-            if (inspectMatrix(x, nextYPos2, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
-                haveCrossedAllAppsColumn2 = true;
-            }
-            for (; 0 <= x && x < cntX; x += increment) {
-                int offset1 = haveCrossedAllAppsColumn1 && x < cntX - 1 ? increment : 0;
-                newIconIndex = inspectMatrix(x, nextYPos1 + offset1, cntX, cntY, matrix);
-                if (newIconIndex != NOOP) {
-                    return newIconIndex;
-                }
-                int offset2 = haveCrossedAllAppsColumn2 && x < cntX - 1 ? -increment : 0;
-                newIconIndex = inspectMatrix(x, nextYPos2 + offset2, cntX, cntY, matrix);
-                if (newIconIndex != NOOP) {
-                    return newIconIndex;
-                }
-            }
-        }
-
-        // Rule3: if switching between pages, do a brute-force search to find an item that was
-        //        missed by rules 1 and 2 (such as when going from a bottom right icon to top left)
-        if (iconIdx == PIVOT) {
-            if (isRtl) {
-                return increment < 0 ? NEXT_PAGE_FIRST_ITEM : PREVIOUS_PAGE_LAST_ITEM;
-            }
-            return increment < 0 ? PREVIOUS_PAGE_LAST_ITEM : NEXT_PAGE_FIRST_ITEM;
-        }
-        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 y = yPos + increment; 0 <= y && y <cntY && 0 <= y; y += increment) {
-            if ((newIconIndex = inspectMatrix(xPos, y, cntX, cntY, matrix)) != NOOP
-                    && newIconIndex != ALL_APPS_COLUMN) {
-                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;
-        boolean haveCrossedAllAppsColumn1 = false;
-        boolean haveCrossedAllAppsColumn2 = false;
-        int y = -1;
-        for (int coeff = 1; coeff < cntX; coeff++) {
-            nextXPos1 = xPos + coeff * increment;
-            nextXPos2 = xPos - coeff * increment;
-            y = yPos + increment * coeff;
-            if (inspectMatrix(nextXPos1, y, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
-                haveCrossedAllAppsColumn1 = true;
-            }
-            if (inspectMatrix(nextXPos2, y, cntX, cntY, matrix) == ALL_APPS_COLUMN) {
-                haveCrossedAllAppsColumn2 = true;
-            }
-            for (; 0 <= y && y < cntY; y = y + increment) {
-                int offset1 = haveCrossedAllAppsColumn1 && y < cntY - 1 ? increment : 0;
-                newIconIndex = inspectMatrix(nextXPos1 + offset1, y, cntX, cntY, matrix);
-                if (newIconIndex != NOOP) {
-                    return newIconIndex;
-                }
-                int offset2 = haveCrossedAllAppsColumn2 && y < cntY - 1 ? -increment : 0;
-                newIconIndex = inspectMatrix(nextXPos2 + offset2, y, cntX, cntY, matrix);
-                if (newIconIndex != 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;
-    }
-
-    /**
-     * Only used for debugging.
-     */
-    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 PREVIOUS_PAGE_RIGHT_COLUMN:return "PREVIOUS_PAGE_RIGHT_COLUMN";
-            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";
-            case NEXT_PAGE_LEFT_COLUMN:     return "NEXT_PAGE_LEFT_COLUMN";
-            case ALL_APPS_COLUMN:           return "ALL_APPS_COLUMN";
-            default:
-                return Integer.toString(index);
-        }
-    }
-
-    /**
-     * Only used for debugging.
-     */
-    private static void printMatrix(int[][] matrix) {
-        Log.v(TAG, "\tprintMap:");
-        int m = matrix.length;
-        int n = matrix[0].length;
-
-        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);
-        }
-    }
-
-    /**
-     * @param edgeColumn the column of the new icon. either {@link #NEXT_PAGE_LEFT_COLUMN} or
-     * {@link #NEXT_PAGE_RIGHT_COLUMN}
-     * @return the view adjacent to {@param oldView} in the {@param nextPage} of the folder.
-     */
-    public static View getAdjacentChildInNextFolderPage(
-            ShortcutAndWidgetContainer nextPage, View oldView, int edgeColumn) {
-        final int newRow = ((CellLayout.LayoutParams) oldView.getLayoutParams()).cellY;
-
-        int column = (edgeColumn == NEXT_PAGE_LEFT_COLUMN) ^ nextPage.invertLayoutHorizontally()
-                ? 0 : (((CellLayout) nextPage.getParent()).getCountX() - 1);
-
-        for (; column >= 0; column--) {
-            for (int row = newRow; row >= 0; row--) {
-                View newView = nextPage.getChildAt(column, row);
-                if (newView != null) {
-                    return newView;
-                }
-            }
-        }
-        return null;
-    }
-}
