Adding support for drag and drop of folders and shortcuts. 

also:
- Long press on empty space on workspace now brings up customization tray
- Fixed: while dragging, items appeared to be dropping on folders two cells to the right
- Fixed: Disabling drops on folders when the workspace is shrunken
- Fixed: account for scaling of dragged items when checking if they overlap
          with shrunken workspace screens
- Making folder icons dimmable to match shortcuts and widgets
- When deciding with shrunken workspace screen we're dragging to, we now use the closest screen rather than the one that has been overlapped the most
- Refactored drag/add mechanism, removing array of occupied cells from CellInfo
- Removed dead code/variables
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 4d1c299..19b5852 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -40,8 +40,6 @@
 public class CellLayout extends ViewGroup {
     static final String TAG = "CellLayout";
 
-    private boolean mPortrait;
-
     private int mCellWidth;
     private int mCellHeight;
 
@@ -90,9 +88,6 @@
     // When a drag operation is in progress, holds the nearest cell to the touch point
     private final int[] mDragCell = new int[2];
 
-    private boolean mDirtyTag;
-    private boolean mLastDownOnOccupiedCell = false;
-
     private final WallpaperManager mWallpaperManager;
 
     public CellLayout(Context context) {
@@ -135,6 +130,7 @@
 
         mCountX = LauncherModel.getCellCountX();
         mCountY = LauncherModel.getCellCountY();
+        mOccupied = new boolean[mCountX][mCountY];
 
         a.recycle();
 
@@ -214,15 +210,60 @@
             // We might be in the middle or end of shrinking/fading to a dimmed view
             // Make sure this view's alpha is set the same as all the rest of the views
             child.setAlpha(getAlpha());
-
             addView(child, index, lp);
 
+            markCellsAsOccupiedForView(child);
+
             return true;
         }
         return false;
     }
 
     @Override
+    public void removeAllViews() {
+        clearOccupiedCells();
+    }
+
+    @Override
+    public void removeAllViewsInLayout() {
+        clearOccupiedCells();
+    }
+
+    @Override
+    public void removeView(View view) {
+        markCellsAsUnoccupiedForView(view);
+        super.removeView(view);
+    }
+
+    @Override
+    public void removeViewAt(int index) {
+        markCellsAsUnoccupiedForView(getChildAt(index));
+        super.removeViewAt(index);
+    }
+
+    @Override
+    public void removeViewInLayout(View view) {
+        markCellsAsUnoccupiedForView(view);
+        super.removeViewInLayout(view);
+    }
+
+    @Override
+    public void removeViews(int start, int count) {
+        for (int i = start; i < start + count; i++) {
+            markCellsAsUnoccupiedForView(getChildAt(i));
+        }
+        super.removeViews(start, count);
+    }
+
+    @Override
+    public void removeViewsInLayout(int start, int count) {
+        for (int i = start; i < start + count; i++) {
+            markCellsAsUnoccupiedForView(getChildAt(i));
+        }
+        super.removeViewsInLayout(start, count);
+    }
+
+    @Override
     public void requestChildFocus(View child, View focused) {
         super.requestChildFocus(child, focused);
         if (child != null) {
@@ -258,45 +299,24 @@
                     cellInfo.cellY = lp.cellY;
                     cellInfo.spanX = lp.cellHSpan;
                     cellInfo.spanY = lp.cellVSpan;
-                    cellInfo.intersectX = lp.cellX;
-                    cellInfo.intersectY = lp.cellY;
                     cellInfo.valid = true;
                     found = true;
-                    mDirtyTag = false;
                     break;
                 }
             }
         }
 
-        mLastDownOnOccupiedCell = found;
-
         if (!found) {
             final int cellXY[] = mTmpCellXY;
             pointToCellExact(x, y, cellXY);
 
-            final boolean portrait = mPortrait;
-            final int xCount = mCountX;
-            final int yCount = mCountY;
-
-            final boolean[][] occupied = mOccupied;
-            findOccupiedCells(xCount, yCount, occupied, null, true);
-
             cellInfo.cell = null;
             cellInfo.cellX = cellXY[0];
             cellInfo.cellY = cellXY[1];
             cellInfo.spanX = 1;
             cellInfo.spanY = 1;
-            cellInfo.intersectX = cellXY[0];
-            cellInfo.intersectY = cellXY[1];
-            cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
-                    cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
-
-            // Instead of finding the interesting vacant cells here, wait until a
-            // caller invokes getTag() to retrieve the result. Finding the vacant
-            // cells is a bit expensive and can generate many new objects, it's
-            // therefore better to defer it until we know we actually need it.
-
-            mDirtyTag = true;
+            cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < mCountX &&
+                    cellXY[1] < mCountY && !mOccupied[cellXY[0]][cellXY[1]];
         }
         setTag(cellInfo);
     }
@@ -319,7 +339,6 @@
             cellInfo.spanX = 0;
             cellInfo.spanY = 0;
             cellInfo.valid = false;
-            mDirtyTag = false;
             setTag(cellInfo);
         }
 
@@ -328,31 +347,7 @@
 
     @Override
     public CellInfo getTag() {
-        final CellInfo info = (CellInfo) super.getTag();
-        if (mDirtyTag && info.valid) {
-            final int xCount = mCountX;
-            final int yCount = mCountY;
-
-            final boolean[][] occupied = mOccupied;
-            findOccupiedCells(xCount, yCount, occupied, null, true);
-
-            info.updateOccupiedCells(occupied, mCountX, mCountY);
-
-            mDirtyTag = false;
-        }
-        return info;
-    }
-
-    /**
-     * Check if the column 'x' is empty from rows 'top' to 'bottom', inclusive.
-     */
-    private static boolean isColumnEmpty(int x, int top, int bottom, boolean[][] occupied) {
-        for (int y = top; y <= bottom; y++) {
-            if (occupied[x][y]) {
-                return false;
-            }
-        }
-        return true;
+        return (CellInfo) super.getTag();
     }
 
     /**
@@ -367,42 +362,6 @@
         return true;
     }
 
-    CellInfo updateOccupiedCells(boolean[] occupiedCells, View ignoreView) {
-        final int xCount = mCountX;
-        final int yCount = mCountY;
-
-        boolean[][] occupied = mOccupied;
-
-        if (occupiedCells != null) {
-            for (int y = 0; y < yCount; y++) {
-                for (int x = 0; x < xCount; x++) {
-                    occupied[x][y] = occupiedCells[y * xCount + x];
-                }
-            }
-        } else {
-            findOccupiedCells(xCount, yCount, occupied, ignoreView, true);
-        }
-
-        CellInfo cellInfo = new CellInfo();
-
-        cellInfo.cellX = -1;
-        cellInfo.cellY = -1;
-        cellInfo.intersectX = -1;
-        cellInfo.intersectY = -1;
-        cellInfo.spanY = 0;
-        cellInfo.spanX = 0;
-        cellInfo.screen = mCellInfo.screen;
-
-        cellInfo.updateOccupiedCells(occupied, mCountX, mCountY);
-
-        cellInfo.valid = cellInfo.existsEmptyCell();
-
-        // Assume the caller will perform their own cell searching, otherwise we
-        // risk causing an unnecessary rebuild after findCellForSpan()
-
-        return cellInfo;
-    }
-
     /**
      * Given a point, return the cell that strictly encloses that point
      * @param x X coordinate of the point
@@ -492,19 +451,13 @@
         final int cellWidth = mCellWidth;
         final int cellHeight = mCellHeight;
 
-        if (mOccupied == null) {
-            mOccupied = new boolean[mCountX][mCountY];
-        }
-
         int numWidthGaps = mCountX - 1;
         int numHeightGaps = mCountY - 1;
 
-        int vSpaceLeft = heightSpecSize - mTopPadding
-                - mBottomPadding - (cellHeight * mCountY);
+        int vSpaceLeft = heightSpecSize - mTopPadding - mBottomPadding - (cellHeight * mCountY);
         mHeightGap = vSpaceLeft / numHeightGaps;
 
-        int hSpaceLeft = widthSpecSize - mLeftPadding
-                - mRightPadding - (cellWidth * mCountX);
+        int hSpaceLeft = widthSpecSize - mLeftPadding - mRightPadding - (cellWidth * mCountX);
         mWidthGap = hSpaceLeft / numWidthGaps;
 
         // center it around the min gaps
@@ -519,8 +472,7 @@
             lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
                     mLeftPadding, mTopPadding);
 
-            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
-                    MeasureSpec.EXACTLY);
+            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
             int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
                     MeasureSpec.EXACTLY);
 
@@ -538,7 +490,7 @@
     }
 
     @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+    public void onLayout(boolean changed, int l, int t, int r, int b) {
         int count = getChildCount();
 
         for (int i = 0; i < count; i++) {
@@ -621,15 +573,29 @@
         }
     }
 
-    private boolean isVacant(int originX, int originY, int spanX, int spanY) {
+    private boolean isVacantIgnoring(
+            int originX, int originY, int spanX, int spanY, View ignoreView) {
+        if (ignoreView != null) {
+            markCellsAsUnoccupiedForView(ignoreView);
+        }
         for (int i = 0; i < spanY; i++) {
             if (!isRowEmpty(originY + i, originX, originX + spanX - 1, mOccupied)) {
+                if (ignoreView != null) {
+                    markCellsAsOccupiedForView(ignoreView);
+                }
                 return false;
             }
         }
+        if (ignoreView != null) {
+            markCellsAsOccupiedForView(ignoreView);
+        }
         return true;
     }
 
+    private boolean isVacant(int originX, int originY, int spanX, int spanY) {
+        return isVacantIgnoring(originX, originY, spanX, spanY, null);
+    }
+
     public View getChildAt(int x, int y) {
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
@@ -687,7 +653,8 @@
         result[1] = Math.max(0, result[1]); // Snap to top
     }
 
-    void visualizeDropLocation(View view, int originX, int originY, int spanX, int spanY) {
+    void visualizeDropLocation(
+            View view, int originX, int originY, int spanX, int spanY, View draggedItem) {
         final int[] originCell = mDragCell;
         final int[] cellXY = mTmpCellXY;
         estimateDropCell(originX, originY, spanX, spanY, cellXY);
@@ -709,12 +676,8 @@
             bottomRight[0] += mCellWidth;
             bottomRight[1] += mCellHeight;
 
-            final int countX = mCountX;
-            final int countY = mCountY;
-            // TODO: It's not necessary to do this every time, but it's not especially expensive
-            findOccupiedCells(countX, countY, mOccupied, view, false);
-
-            boolean vacant = isVacant(originCell[0], originCell[1], spanX, spanY);
+            boolean vacant =
+                isVacantIgnoring(originCell[0], originCell[1], spanX, spanY, draggedItem);
             mDragRectDrawable = vacant ? mVacantDrawable : mOccupiedDrawable;
 
             // mDragRect will be rendered in onDraw()
@@ -736,8 +699,7 @@
      * @return The X, Y cell of a vacant area that can contain this object,
      *         nearest the requested location.
      */
-    int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY,
-            CellInfo vacantCells, int[] recycle) {
+    int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY, int[] recycle) {
 
         // Keep track of best-scoring drop area
         final int[] bestXY = recycle != null ? recycle : new int[2];
@@ -777,10 +739,130 @@
         }
     }
 
+    boolean existsEmptyCell() {
+        return findCellForSpan(null, 1, 1);
+    }
+
     /**
-     * Called when a drag and drop operation has finished (successfully or not).
+     * Finds the upper-left coordinate of the first rectangle in the grid that can
+     * hold a cell of the specified dimensions. If intersectX and intersectY are not -1,
+     * then this method will only return coordinates for rectangles that contain the cell
+     * (intersectX, intersectY)
+     *
+     * @param cellXY The array that will contain the position of a vacant cell if such a cell
+     *               can be found.
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     *
+     * @return True if a vacant cell of the specified dimension was found, false otherwise.
      */
-    void onDragComplete() {
+    boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
+        return findCellForSpanThatIntersectsIgnoring(cellXY, spanX, spanY, -1, -1, null);
+    }
+
+    /**
+     * Like above, but ignores any cells occupied by the item "ignoreView"
+     *
+     * @param cellXY The array that will contain the position of a vacant cell if such a cell
+     *               can be found.
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     * @param ignoreView The home screen item we should treat as not occupying any space
+     * @return
+     */
+    boolean findCellForSpanIgnoring(int[] cellXY, int spanX, int spanY, View ignoreView) {
+        return findCellForSpanThatIntersectsIgnoring(cellXY, spanX, spanY, -1, -1, ignoreView);
+    }
+
+    /**
+     * Like above, but if intersectX and intersectY are not -1, then this method will try to
+     * return coordinates for rectangles that contain the cell [intersectX, intersectY]
+     *
+     * @param spanX The horizontal span of the cell we want to find.
+     * @param spanY The vertical span of the cell we want to find.
+     * @param ignoreView The home screen item we should treat as not occupying any space
+     * @param intersectX The X coordinate of the cell that we should try to overlap
+     * @param intersectX The Y coordinate of the cell that we should try to overlap
+     *
+     * @return True if a vacant cell of the specified dimension was found, false otherwise.
+     */
+    boolean findCellForSpanThatIntersects(int[] cellXY, int spanX, int spanY,
+            int intersectX, int intersectY) {
+        return findCellForSpanThatIntersectsIgnoring(
+                cellXY, spanX, spanY, intersectX, intersectY, null);
+    }
+
+    /**
+     * The superset of the above two methods
+     */
+    boolean findCellForSpanThatIntersectsIgnoring(int[] cellXY, int spanX, int spanY,
+            int intersectX, int intersectY, View ignoreView) {
+        if (ignoreView != null) {
+            markCellsAsUnoccupiedForView(ignoreView);
+        }
+
+        while (true) {
+            int startX = 0;
+            if (intersectX >= 0) {
+                startX = Math.max(startX, intersectX - (spanX - 1));
+            }
+            int endX = mCountX - (spanX - 1);
+            if (intersectX >= 0) {
+                endX = Math.min(endX, intersectX + (spanX - 1) + (spanX == 1 ? 1 : 0));
+            }
+            int startY = 0;
+            if (intersectY >= 0) {
+                startY = Math.max(startY, intersectY - (spanY - 1));
+            }
+            int endY = mCountY - (spanY - 1);
+            if (intersectY >= 0) {
+                endY = Math.min(endY, intersectY + (spanY - 1) + (spanY == 1 ? 1 : 0));
+            }
+
+            for (int x = startX; x < endX; x++) {
+                inner:
+                for (int y = startY; y < endY; y++) {
+                    for (int i = 0; i < spanX; i++) {
+                        for (int j = 0; j < spanY; j++) {
+                            if (mOccupied[x + i][y + j]) {
+                                // small optimization: we can skip to below the row we just found
+                                // an occupied cell
+                                y += j;
+                                continue inner;
+                            }
+                        }
+                    }
+                    if (cellXY != null) {
+                        cellXY[0] = x;
+                        cellXY[1] = y;
+                    }
+                    if (ignoreView != null) {
+                        markCellsAsOccupiedForView(ignoreView);
+                    }
+                    return true;
+                }
+            }
+            if (intersectX == -1 && intersectY == -1) {
+                break;
+            } else {
+                // if we failed to find anything, try again but without any requirements of
+                // intersecting
+                intersectX = -1;
+                intersectY = -1;
+                continue;
+            }
+        }
+
+        if (ignoreView != null) {
+            markCellsAsOccupiedForView(ignoreView);
+        }
+        return false;
+    }
+
+    /**
+     * Called when drag has left this CellLayout or has been completed (successfully or not)
+     */
+    void onDragExit() {
         // Invalidate the drag data
         mDragCell[0] = -1;
         mDragCell[1] = -1;
@@ -803,14 +885,14 @@
             mDragRect.setEmpty();
             child.requestLayout();
         }
-        onDragComplete();
+        onDragExit();
     }
 
     void onDropAborted(View child) {
         if (child != null) {
             ((LayoutParams) child.getLayoutParams()).isDragging = false;
         }
-        onDragComplete();
+        onDragExit();
     }
 
     /**
@@ -889,13 +971,8 @@
      * @return True if a vacant cell was found
      */
     public boolean getVacantCell(int[] vacant, int spanX, int spanY) {
-        final int xCount = mCountX;
-        final int yCount = mCountY;
-        final boolean[][] occupied = mOccupied;
 
-        findOccupiedCells(xCount, yCount, occupied, null, true);
-
-        return findVacantCell(vacant, spanX, spanY, xCount, yCount, occupied);
+        return findVacantCell(vacant, spanX, spanY, mCountX, mCountY, mOccupied);
     }
 
     static boolean findVacantCell(int[] vacant, int spanX, int spanY,
@@ -930,8 +1007,6 @@
         final int yCount = mCountY;
         final boolean[][] occupied = mOccupied;
 
-        findOccupiedCells(xCount, yCount, occupied, null, true);
-
         final boolean[] flat = new boolean[xCount * yCount];
         for (int y = 0; y < yCount; y++) {
             for (int x = 0; x < xCount; x++) {
@@ -942,32 +1017,34 @@
         return flat;
     }
 
-    /**
-     * Update the array of occupied cells.
-     * @param ignoreView If non-null, the space occupied by this View is treated as vacant
-     * @param ignoreFolders If true, a cell occupied by a Folder is treated as vacant
-     */
-    private void findOccupiedCells(
-            int xCount, int yCount, boolean[][] occupied, View ignoreView, boolean ignoreFolders) {
-
-        for (int x = 0; x < xCount; x++) {
-            for (int y = 0; y < yCount; y++) {
-                occupied[x][y] = false;
+    private void clearOccupiedCells() {
+        for (int x = 0; x < mCountX; x++) {
+            for (int y = 0; y < mCountY; y++) {
+                mOccupied[x][y] = false;
             }
         }
+    }
 
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            View child = getChildAt(i);
-            if ((ignoreFolders && child instanceof Folder) || child.equals(ignoreView)) {
-                continue;
-            }
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+    public void onMove(View view, int newCellX, int newCellY) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsAsUnoccupiedForView(view);
+        markCellsForView(newCellX, newCellY, lp.cellHSpan, lp.cellVSpan, true);
+    }
 
-            for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan && x < xCount; x++) {
-                for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan && y < yCount; y++) {
-                    occupied[x][y] = true;
-                }
+    private void markCellsAsOccupiedForView(View view) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true);
+    }
+
+    private void markCellsAsUnoccupiedForView(View view) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false);
+    }
+
+    private void markCellsForView(int cellX, int cellY, int spanX, int spanY, boolean value) {
+        for (int x = cellX; x < cellX + spanX && x < mCountX; x++) {
+            for (int y = cellY; y < cellY + spanY && y < mCountY; y++) {
+                mOccupied[x][y] = value;
             }
         }
     }
@@ -1087,117 +1164,25 @@
         }
     }
 
+    // This class stores info for two purposes:
+    // 1. When dragging items (mDragInfo in Workspace), we store the View, its cellX & cellY,
+    //    its spanX, spanY, and the screen it is on
+    // 2. When long clicking on an empty cell in a CellLayout, we save information about the
+    //    cellX and cellY coordinates and which page was clicked. We then set this as a tag on
+    //    the CellLayout that was long clicked
     static final class CellInfo implements ContextMenu.ContextMenuInfo {
-        private boolean[][] mOccupied;
-        private int mCountX;
-        private int mCountY;
         View cell;
         int cellX = -1;
         int cellY = -1;
-        // intersectX and intersectY constrain the results of findCellForSpan; any empty space
-        // it results must include this point (unless intersectX and intersectY are -1)
-        int intersectX = -1;
-        int intersectY = -1;
         int spanX;
         int spanY;
         int screen;
         boolean valid;
 
-        void updateOccupiedCells(boolean[][] occupied, int xCount, int yCount) {
-            mOccupied = occupied.clone();
-            mCountX = xCount;
-            mCountY = yCount;
-        }
-
-        void updateOccupiedCells(boolean[] occupied, int xCount, int yCount) {
-            if (mOccupied == null || mCountX != xCount || mCountY != yCount) {
-                mOccupied = new boolean[xCount][yCount];
-            }
-            mCountX = xCount;
-            mCountY = yCount;
-            for (int y = 0; y < yCount; y++) {
-                for (int x = 0; x < xCount; x++) {
-                    mOccupied[x][y] = occupied[y * xCount + x];
-                }
-            }
-        }
-
-        boolean existsEmptyCell() {
-            return findCellForSpan(null, 1, 1);
-        }
-        /**
-         * Finds the upper-left coordinate of the first rectangle in the grid that can
-         * hold a cell of the specified dimensions. If intersectX and intersectY are not -1,
-         * then this method will only return coordinates for rectangles that contain the cell
-         * (intersectX, intersectY)
-         *
-         * @param cellXY The array that will contain the position of a vacant cell if such a cell
-         *               can be found.
-         * @param spanX The horizontal span of the cell we want to find.
-         * @param spanY The vertical span of the cell we want to find.
-         *
-         * @return True if a vacant cell of the specified dimension was found, false otherwise.
-         */
-        boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
-            // return the span represented by the CellInfo only there is no view there
-            //   (this.cell == null) and there is enough space
-
-            if (this.cell == null && this.spanX >= spanX && this.spanY >= spanY) {
-                if (cellXY != null) {
-                    cellXY[0] = cellX;
-                    cellXY[1] = cellY;
-                }
-                return true;
-            }
-
-            int startX = 0;
-            if (intersectX >= 0) {
-                startX = Math.max(startX, intersectX - (spanX - 1));
-            }
-            int endX = mCountX - (spanX - 1);
-            if (intersectX >= 0) {
-                endX = Math.min(endX, intersectX + (spanX - 1));
-            }
-            int startY = 0;
-            if (intersectY >= 0) {
-                startY = Math.max(startY, intersectY - (spanY - 1));
-            }
-            int endY = mCountY - (spanY - 1);
-            if (intersectY >= 0) {
-                endY = Math.min(endY, intersectY + (spanY - 1));
-            }
-
-            for (int x = startX; x < endX; x++) {
-                inner:
-                for (int y = startY; y < endY; y++) {
-                    for (int i = 0; i < spanX; i++) {
-                        for (int j = 0; j < spanY; j++) {
-                            if (mOccupied[x + i][y + j]) {
-                                // small optimization: we can skip to below the row we just found
-                                // an occupied cell
-                                y += j;
-                                continue inner;
-                            }
-                        }
-                    }
-                    if (cellXY != null) {
-                        cellXY[0] = x;
-                        cellXY[1] = y;
-                    }
-                    return true;
-                }
-            }
-            return false;
-        }
-
         @Override
         public String toString() {
             return "Cell[view=" + (cell == null ? "null" : cell.getClass())
                     + ", x=" + cellX + ", y=" + cellY + "]";
         }
     }
-
-    public boolean lastDownOnOccupiedCell() {
-        return mLastDownOnOccupiedCell;
-    }
 }