/// <summary>Empties out and resizes the grid (if it requires it).</summary>
        public void Clean(float sWidth, float sHeight)
        {
            float cellSize = InputGridCell.Size;

            CellSize = cellSize;

            // Get the number of cells on x:
            int width  = (int)Math.Ceiling(sWidth / cellSize);
            int height = (int)Math.Ceiling(sHeight / cellSize);

            if (Grid == null)
            {
                Width  = width;
                Height = height;
                Grid   = new InputGridCell[width * height];

                // Create the cells:
                for (int i = 0; i < Grid.Length; i++)
                {
                    Grid[i] = new InputGridCell();
                }
            }
            else if (Width != width || Height != height)
            {
                // Pool the nodes:
                Empty();

                Width  = width;
                Height = height;
                InputGridCell[] newGrid = new InputGridCell[width * height];

                // Copy over the cells into the new array, and create any that are required.
                int max = (newGrid.Length < Grid.Length) ? newGrid.Length : Grid.Length;

                // Copy that many:
                Array.Copy(Grid, 0, newGrid, 0, max);

                // Fill the rest:
                for (int i = max; i < newGrid.Length; i++)
                {
                    newGrid[i] = new InputGridCell();
                }

                Grid = newGrid;
            }
        }
        /// <summary>Empties the grid into the pool.</summary>
        public void Empty()
        {
            if (Grid == null)
            {
                return;
            }

            // For each grid cell..
            for (int i = 0; i < Grid.Length; i++)
            {
                InputGridCell cell = Grid[i];

                if (cell.Back != null)
                {
                    // Pool:
                    cell.Back.Previous = PooledCell_;
                    PooledCell_        = cell.Front;

                    // Clear:
                    cell.Back  = null;
                    cell.Front = null;
                }
            }
        }
        /// <summary>Pushes the given renderable data into the grid now.</summary>
        public void Push(RenderableData renderData)
        {
            // Node must be an element:
            if (renderData == null || !(renderData.Node is Dom.Element))
            {
                return;
            }

            // Get the region:
            ScreenRegion region = renderData.OnScreenRegion;

            if (region == null)
            {
                return;
            }

            // Get the bounds:
            int minX = (int)(region.ScreenMinX / CellSize);
            int minY = (int)(region.ScreenMinY / CellSize);

            if (minX >= Width || minY >= Height)
            {
                // ..It's offscreen?
                return;
            }

            if (minX < 0)
            {
                minX = 0;
            }

            if (minY < 0)
            {
                minY = 0;
            }

            // Max (inclusive):
            int maxX = (int)(region.ScreenMaxX / CellSize);
            int maxY = (int)(region.ScreenMaxY / CellSize);

            if (maxX < 0 || maxY < 0)
            {
                // ..It's offscreen?
                return;
            }

            if (maxX >= Width)
            {
                maxX = Width - 1;
            }

            if (maxY >= Height)
            {
                maxY = Height - 1;
            }

            // Generating a bunch of entries now!
            int cellIndex = minY * Width;

            // Only having one box means we don't need to do multiline testing.
            // It also means we can optimise "central" boxes too (see below about that).
            bool oneBox = (renderData.FirstBox != null && renderData.FirstBox.NextInElement == null);

            for (int y = minY; y <= maxY; y++)
            {
                // Central boxes are on *both* middle X and middle Y
                // The content in the cell already is being completely overlapped
                // so we can simply empty it out (and recycle the entries too).
                bool centralBox = (oneBox && y != minY && y != maxY);

                for (int x = minX; x <= maxX; x++)
                {
                    // Get the target cell:
                    InputGridCell cell = Grid[cellIndex + x];

                    if (centralBox && x != minX && x != maxX)
                    {
                        // Overwrite! Pool the cell:
                        if (cell.Back != null)
                        {
                            // Pool:
                            cell.Back.Previous = PooledCell_;
                            PooledCell_        = cell.Front;

                            // Clear:
                            cell.Back  = null;
                            cell.Front = null;
                        }
                    }

                    // Get an entry (typically from the pool):
                    InputGridEntry ige = GetEntry();

                    // Set it up:
                    ige.RenderData = renderData;

                    if (cell.Front == null)
                    {
                        cell.Back  = ige;
                        cell.Front = ige;
                    }
                    else
                    {
                        // Stack on the front:
                        ige.Previous = cell.Front;
                        cell.Front   = ige;
                    }
                }

                cellIndex += Width;
            }
        }