/// <summary>
        /// Considers a single dimension for the given dimension set.
        /// </summary>
        private void ProcessDimension()
        {
            //A of length, l, has a reach of l-1 to eith side of the Pre-defined Cell whilst still containg the pre-defined Cell.
            int reach = PossibleBlock.DimensionSet[DimensionIndex] - 1;
            //The position of the layer of Cells in the dimension currently being processed.
            int position = CurrentDimensionOfCells.Peek().Coordinates[DimensionIndex];
            //The position of the outer most Cells in the Grid  in the current dimension.
            //Note the lower bound of the Grid is 0 by definition.
            int upperBound = _puzzleData.SideLengths[DimensionIndex] - 1;
            //The limits are the distance between the PDC and Cell, of highest position, that need processing.
            //It is the reach of Block unless this extends beyond the bound of the Grid. In which case the upper limit is the distance between the PDC and the edge of the Grid.
            int upperLimit = reach - Math.Max(0, position + reach - upperBound);
            int lowerLimit = -reach - Math.Min(0, position - reach);

            //CurrentDimensionOfCells represents a layer of Cells. Each Cell in this layer is used to process a line of Cells purpendicular to the layer.
            foreach (ICell centralCell in CurrentDimensionOfCells)
            {
                for (int offset = lowerLimit; offset <= upperLimit; offset++)
                {
                    //Retrieves the Cell to be processed.
                    ICell outerCell = _solutionTracker.Grid.GetCellFromOffset(centralCell, DimensionIndex, offset);
                    NextDimensionOfCells.Push(outerCell);
                    if (outerCell.GetPossibleOwners.ContainsKey(PossibleBlock.MainBlock) == false)
                    {
                        outerCell.GetPossibleMainBlocks.AddLast(PossibleBlock.MainBlock);
                        outerCell.GetPossibleOwners.Add(PossibleBlock.MainBlock, GetCellPossilbeOwners(centralCell, offset));
                    }
                    else
                    {
                        foreach (int possibleOwner in GetCellPossilbeOwners(centralCell, offset))
                        {
                            outerCell.GetPossibleOwners[PossibleBlock.MainBlock].AddLast(possibleOwner);
                        }
                    }
                }
            }
            // Some PossibleBlocks are not possible as they extend beyond the bounds of the Grid.
            // These PossibleBlocks are removed.
            if (upperLimit != reach)
            {
                foreach (int possibleBlockIndex in GetCellPossilbeOwners(PossibleBlock.MainBlock.PreDefinedCell, upperLimit + 1))
                {
                    PossibleBlock.MainBlock.PossibleBlocks.Remove(possibleBlockIndex);
                }
            }

            if (lowerLimit != -reach)
            {
                foreach (int possibleBlockIndex in GetCellPossilbeOwners(PossibleBlock.MainBlock.PreDefinedCell, lowerLimit - 1))
                {
                    PossibleBlock.MainBlock.PossibleBlocks.Remove(possibleBlockIndex);
                }
            }
        }
        /// <summary>
        /// For a given MainBlock, all possible sets of dimensions are considered 1 at a time.
        /// </summary>
        private void ProcessDimensionSet()
        {
            //For the dimension set, 1 dimension is considered at a time starting with that of the highest index.
            int dimensionIndex = PossibleBlock.DimensionSet.Count - 1;

            //The algorith uses the Pre-defined Cell as the starting point.
            CurrentDimensionOfCells.Push(PossibleBlock.MainBlock.PreDefinedCell);

            while (DimensionIndex >= 0)
            {
                NextDimensionOfCells = new Stack <ICell>();
                NodeSepartion        = PossibleBlock.MultipleMatrix[dimensionIndex + 1];
                ProcessDimension();
                CurrentDimensionOfCells = NextDimensionOfCells;
                dimensionIndex--;
            }
        }