/// <summary>
        /// Sets the bits in the region starting at location and having
        /// given width and height
        /// </summary>
        /// <param name="location">Top Left of the the Region</param>
        /// <param name="width">Width of the Region</param>
        /// <param name="height">Height of the Region</param>
        internal void SetRegion(MatrixCell location, int width, int height)
        {
            long targetRow    = location.Row;
            long targetCol    = location.Col;
            int  targetWidth  = width;
            int  targetHeight = height;

            // Interchange Row & Column and width & height if the BitOrientation is Vertical
            if (BitOrientation == Orientation.Vertical)
            {
                targetRow    = location.Col;
                targetCol    = location.Row;
                targetWidth  = height;
                targetHeight = width;
            }

            // Optimization: If the region is only 1 bit wide and high
            if ((targetWidth == 1) && (targetHeight == 1))
            {
                this[targetRow, targetCol] = true;
                return;
            }

            for (var row = 0; row < targetHeight; row++)
            {
                for (var col = 0; col < targetWidth; col++)
                {
                    this[targetRow + row, targetCol + col] = true;
                }
            }
        }
        /// <summary>
        /// Tries to find an empty region of given width and height starting
        /// from the startIndex row.
        /// </summary>
        /// <param name="startIndex">The row to start the search from</param>
        /// <param name="width">Width of the Region</param>
        /// <param name="height">Height of the Region</param>
        /// <param name="cell">The cell location</param>
        /// <returns>true if successful otherwise false</returns>
        internal bool TryFindRegion(long startIndex, int width, int height, out MatrixCell cell)
        {
            cell = MatrixCell.InvalidCell;

            // Swap width and height if the BitOrientation is Vertical
            if ((BitOrientation == Orientation.Vertical) && (width != height))
            {
                var temp = width;
                width  = height;
                height = temp;
            }

            if ((startIndex < 0 || startIndex >= _rowsInternal) ||
                (startIndex + (height - 1) >= _rowsInternal) ||
                ((width < 1) || (width > MaxBitsPerItem)) ||
                (width > _columnsInternal))
            {
                return(false);
            }

            // Optimization: If both width and height are 1 then use a faster
            // loop to find the next empty cell
            if ((width == 1) && (height == 1))
            {
                for (var row = startIndex; row < _rowsInternal; row++)
                {
                    for (var col = 0; col < _columnsInternal; col++)
                    {
                        // Is the cell unset?
                        if (this[row, col])
                        {
                            continue;
                        }

                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, col) : new MatrixCell(col, row);
                        return(true);
                    }
                }

                // If the code has reached here it means that it did not find any unset
                // bit in the entire matrix. Return false from here.
                return(false);
            }

            var mask = (((UInt64)1) << width) - 1;

            for (var row = startIndex; row < (_rowsInternal - height + 1); row++)
            {
                // Quickcheck: If the row is empty then no need to check individual bits in the row
                if (!RowHasData(row))
                {
                    // Current column has no bits set. Check the bits in the next (height - 1)
                    // rows starting at the same column position (0) to check if they are unset
                    if (!AnyBitsSetInRegion(row, 0, width, height))
                    {
                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, 0) : new MatrixCell(0, row);
                        return(true);
                    }
                }

                // Row is not empty and has some set bits.  Check if there are
                // 'width' continuous unset bits in the column.
                // 1. Check the first 'width' bits
                var rowData = 0UL;
                var col     = 0;
                for (; col < width; col++)
                {
                    rowData <<= 1;
                    rowData  |= this[row, col] ? 1UL : 0UL;
                }
                if ((rowData & mask) == 0)
                {
                    // Current column has 'width' unset bits starting from 0 position.
                    // Check the bits in the next (height - 1) rows starting at the same
                    // column position (0) to check if they are unset
                    if (!AnyBitsSetInRegion(row, 0, width, height))
                    {
                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, 0) : new MatrixCell(0, row);
                        return(true);
                    }
                }

                // Shift the rowData by 1 bit and clear the (width + 1)th most significant bit.
                // This way a set of 'width' continuous bits is matched against the mask
                // to check if all the bits are zero.
                var colBegin = 0;
                while (col < _columnsInternal)
                {
                    rowData <<= 1;
                    rowData  &= mask;
                    rowData  |= this[row, col++] ? 1UL : 0UL;
                    colBegin++;

                    if ((rowData & mask) != 0)
                    {
                        continue;
                    }

                    // Current column has 'width' unset bits starting from colBegin position.
                    // Check the bits in the next (height - 1) rows starting at the same
                    // column position (colBegin) to check if they are unset
                    if (AnyBitsSetInRegion(row, colBegin, width, height))
                    {
                        continue;
                    }

                    // Swap the row and col values if the BitOrientation is Vertical
                    cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, colBegin) : new MatrixCell(colBegin, row);
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Checks if the given UIElement can fit in the given cell location
        /// </summary>
        /// <param name="element">UIElement</param>
        /// <param name="cell">Cell location</param>
        /// <returns>True if the UIElement fits otherwise False.</returns>
        private bool IsValidCellPosition(UIElement element, MatrixCell cell)
        {
            if (!cell.IsValid())
                return false;

            var info = _fluidBits[element];

            return (cell.Row + info.Height <= _maxCellRows) &&
                   (cell.Col + info.Width <= _maxCellCols);
        }
        /// <summary>
        /// Gets the list of cell locations which are vacated when the given element is
        /// moved to the given cell location.
        /// </summary>
        /// <param name="element">UIElement</param>
        /// <param name="cell">Cell location</param>
        /// <returns>List of cell locations</returns>
        private List<MatrixCell> GetVacatedCells(UIElement element, MatrixCell cell)
        {
            var result = new List<MatrixCell>();

            var info = _fluidBits[element];
            var baseRow = info.Row;
            var baseCol = info.Col;
            var width = info.Width;
            var height = info.Height;

            var minRow = cell.Row;
            var maxRow = minRow + height;
            var minCol = cell.Col;
            var maxCol = minCol + width;

            for (var i = 0; i < height; i++)
            {
                for (var j = 0; j < width; j++)
                {
                    var row = baseRow + i;
                    var col = baseCol + j;

                    var isInside = (row >= minRow) && (row < maxRow) &&
                                   (col >= minCol) && (col < maxCol);

                    if (!isInside)
                        result.Add(new MatrixCell(row, col));
                }
            }

            return result;
        }
        /// <summary>
        /// Gets the list of children overlapped by the given element when it is
        /// moved to the given cell location.
        /// </summary>
        /// <param name="element">UIElement</param>
        /// <param name="cell">Cell location</param>
        /// <returns>List of overlapped UIElements</returns>
        private List<UIElement> GetOverlappedChildren(UIElement element, MatrixCell cell)
        {
            var result = new List<UIElement>();
            var info = _fluidBits[element];

            for (var row = 0; row < info.Height; row++)
            {
                for (var col = 0; col < info.Width; col++)
                {
                    var item = _fluidBits.Where(t => t.Value.Contains(cell.Row + row, cell.Col + col)).Select(t => t.Key).FirstOrDefault();
                    if ((item != null) && !ReferenceEquals(item, element) && (!result.Contains(item)))
                    {
                        result.Add(item);
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Tries to find an empty region of given width and height starting
        /// from the startIndex row.
        /// </summary>
        /// <param name="startIndex">The row to start the search from</param>
        /// <param name="width">Width of the Region</param>
        /// <param name="height">Height of the Region</param>
        /// <param name="cell">The cell location</param>
        /// <returns>true if successful otherwise false</returns>
        internal bool TryFindRegion(long startIndex, int width, int height, out MatrixCell cell)
        {
            cell = MatrixCell.InvalidCell;

            // Swap width and height if the BitOrientation is Vertical
            if ((BitOrientation == Orientation.Vertical) && (width != height))
            {
                var temp = width;
                width = height;
                height = temp;
            }

            if ((startIndex < 0 || startIndex >= _rowsInternal) ||
                (startIndex + (height - 1) >= _rowsInternal) ||
                ((width < 1) || (width > MaxBitsPerItem)) ||
                (width > _columnsInternal))
                return false;

            // Optimization: If both width and height are 1 then use a faster
            // loop to find the next empty cell
            if ((width == 1) && (height == 1))
            {
                for (var row = startIndex; row < _rowsInternal; row++)
                {
                    for (var col = 0; col < _columnsInternal; col++)
                    {
                        // Is the cell unset?
                        if (this[row, col])
                            continue;

                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, col) : new MatrixCell(col, row);
                        return true;
                    }
                }

                // If the code has reached here it means that it did not find any unset
                // bit in the entire matrix. Return false from here.
                return false;
            }

            var mask = (((UInt64)1) << width) - 1;
            for (var row = startIndex; row < (_rowsInternal - height + 1); row++)
            {
                // Quickcheck: If the row is empty then no need to check individual bits in the row
                if (!RowHasData(row))
                {
                    // Current column has no bits set. Check the bits in the next (height - 1)
                    // rows starting at the same column position (0) to check if they are unset
                    if (!AnyBitsSetInRegion(row, 0, width, height))
                    {
                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, 0) : new MatrixCell(0, row);
                        return true;
                    }
                }

                // Row is not empty and has some set bits.  Check if there are
                // 'width' continuous unset bits in the column.
                // 1. Check the first 'width' bits
                var rowData = 0UL;
                var col = 0;
                for (; col < width; col++)
                {
                    rowData <<= 1;
                    rowData |= this[row, col] ? 1UL : 0UL;
                }
                if ((rowData & mask) == 0)
                {
                    // Current column has 'width' unset bits starting from 0 position.
                    // Check the bits in the next (height - 1) rows starting at the same
                    // column position (0) to check if they are unset
                    if (!AnyBitsSetInRegion(row, 0, width, height))
                    {
                        // Swap the row and col values if the BitOrientation is Vertical
                        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, 0) : new MatrixCell(0, row);
                        return true;
                    }
                }

                // Shift the rowData by 1 bit and clear the (width + 1)th most significant bit.
                // This way a set of 'width' continuous bits is matched against the mask
                // to check if all the bits are zero.
                var colBegin = 0;
                while (col < _columnsInternal)
                {
                    rowData <<= 1;
                    rowData &= mask;
                    rowData |= this[row, col++] ? 1UL : 0UL;
                    colBegin++;

                    if ((rowData & mask) != 0)
                        continue;

                    // Current column has 'width' unset bits starting from colBegin position.
                    // Check the bits in the next (height - 1) rows starting at the same
                    // column position (colBegin) to check if they are unset
                    if (AnyBitsSetInRegion(row, colBegin, width, height))
                        continue;

                    // Swap the row and col values if the BitOrientation is Vertical
                    cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, colBegin) : new MatrixCell(colBegin, row);
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Sets the bits in the region starting at location and having 
        /// given width and height
        /// </summary>
        /// <param name="location">Top Left of the the Region</param>
        /// <param name="width">Width of the Region</param>
        /// <param name="height">Height of the Region</param>
        internal void SetRegion(MatrixCell location, int width, int height)
        {
            long targetRow = location.Row;
            long targetCol = location.Col;
            int targetWidth = width;
            int targetHeight = height;

            // Interchange Row & Column and width & height if the BitOrientation is Vertical
            if (BitOrientation == Orientation.Vertical)
            {
                targetRow = location.Col;
                targetCol = location.Row;
                targetWidth = height;
                targetHeight = width;
            }

            // Optimization: If the region is only 1 bit wide and high
            if ((targetWidth == 1) && (targetHeight == 1))
            {
                this[targetRow, targetCol] = true;
                return;
            }

            for (var row = 0; row < targetHeight; row++)
            {
                for (var col = 0; col < targetWidth; col++)
                {
                    this[targetRow + row, targetCol + col] = true;
                }
            }
        }