// IMPLEMENTATION METHODS

    private Maze GenerateInitializedMaze(int width, int height)
    {
        var positionToMazeCell     = new Dictionary <string, MazeCell>();
        var positionToMazeCellWall = new Dictionary <string, MazeWall>();
        // keep track of the last maze cell
        MazeCell lastMazeCell = null;

        // for each position instantiate maze cells and
        // point to previous maze cell to create linked list
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                var mazeCell = new MazeCell(j, i);
                if (lastMazeCell != null)
                {
                    mazeCell.nextMazeCell = lastMazeCell;
                }
                lastMazeCell = mazeCell;
                // add to position lookup dict
                positionToMazeCell.Add(
                    GetFormattedPosition(mazeCell.position_X, mazeCell.position_Y),
                    mazeCell
                    );
            }
        }

        // for every maze cell in the linked list set all the neighbor cells
        MazeCell currentMazeCell  = lastMazeCell;
        MazeCell previousMazeCell = null;

        while (currentMazeCell != null)
        {
            foreach (string direction in MazeCell.directions)
            {
                MazeCell nCell = this.GetMazeCellNeighborCellFromLookupDict(
                    positionToMazeCell,
                    currentMazeCell,
                    direction
                    );
                MazeWall sharedWall = null;
                if (nCell != null)
                {
                    currentMazeCell.SetNeighborMazeCell(direction, nCell);
                    sharedWall = nCell.GetMazeWall(MazeCell.GetOppositeDirection(direction));
                }
                if (sharedWall != null)
                {
                    currentMazeCell.SetWall(direction, sharedWall);
                }
                else
                {
                    float xOffset = 0;
                    float yOffset = 0;
                    if (direction == MazeCell.NORTH)
                    {
                        yOffset = 0.5f;
                    }
                    else if (direction == MazeCell.SOUTH)
                    {
                        yOffset = -0.5f;
                    }
                    else if (direction == MazeCell.EAST)
                    {
                        xOffset = 0.5f;
                    }
                    else if (direction == MazeCell.WEST)
                    {
                        xOffset = -0.5f;
                    }
                    bool isOutwall = (
                        (direction == MazeCell.NORTH && currentMazeCell.position_Y == height - 1) ||
                        (direction == MazeCell.SOUTH && currentMazeCell.position_Y == 0) ||
                        (direction == MazeCell.EAST && currentMazeCell.position_X == 0) ||
                        (direction == MazeCell.WEST && currentMazeCell.position_X == width - 1)
                        );
                    bool isHorizontal = direction == MazeCell.NORTH || direction == MazeCell.SOUTH;
                    var  mazeWall     = new MazeWall(
                        currentMazeCell.position_X + xOffset,
                        currentMazeCell.position_Y + yOffset,
                        true,
                        isOutwall,
                        isHorizontal
                        );
                    currentMazeCell.SetWall(direction, mazeWall);
                    positionToMazeCellWall.Add(
                        this.GetFormattedPosition(
                            mazeWall.position_X,
                            mazeWall.position_Y
                            ),
                        mazeWall
                        );
                }
            }
            previousMazeCell = currentMazeCell;
            currentMazeCell  = currentMazeCell.nextMazeCell;
        }

        var maze = new Maze(
            width,
            height,
            positionToMazeCell,
            lastMazeCell,
            positionToMazeCellWall
            );

        // this.TestValidateMaze(maze);

        return(maze);
    }