public static HashSet <Vec2i> BFS_ReachableNodes_MaximumSteps(
            this PM_Maze maze,
            Vec2i root,
            bool includeRoot,
            int maximumSteps
            )
        {
            // start the bfs search...

            Dictionary <Vec2i, Vec2i> predecessors = new Dictionary <Vec2i, Vec2i>();
            Dictionary <Vec2i, int>   numSteps     = new Dictionary <Vec2i, int>();

            var allNodes = maze.CellsPositions_All_List();

            //T dummyNode = T.Dummy();
            foreach (var node in allNodes)
            {
                predecessors.Add(node, node);
                numSteps.Add(node, int.MaxValue);
            }

            HashSet <Vec2i> visited_Nodes = new HashSet <Vec2i>()
            {
                root
            };

            Queue <Vec2i> searchQueue = new Queue <Vec2i>();

            searchQueue.Enqueue(root);
            numSteps[root] = 0;

            while (searchQueue.Count > 0)
            {
                var current = searchQueue.Dequeue();
                if (numSteps[current] < maximumSteps)
                {
                    HashSet <Vec2i> unvisitedNeighbors = maze.Cells_Connected_To_Cell__Set(current);
                    unvisitedNeighbors.ExceptWith(visited_Nodes);

                    foreach (var neighbor in unvisitedNeighbors)
                    {
                        predecessors[neighbor] = current;
                        numSteps[neighbor]     = numSteps[current] + 1;
                        searchQueue.Enqueue(neighbor);
                        visited_Nodes.Add(neighbor);
                    }
                }
            }

            HashSet <Vec2i> reachable_within_steps = new HashSet <Vec2i>();

            foreach (var node in visited_Nodes)
            {
                if (numSteps[node] <= maximumSteps)
                {
                    reachable_within_steps.Add(node);
                }
            }

            if (includeRoot)
            {
                return(reachable_within_steps);
            }
            else
            {
                reachable_within_steps.Remove(root);
                return(reachable_within_steps);
            }
        }