private void InternalDfs(Dictionary <T, UndirectedGraphNode <T> > nodes, UndirectedGraphNode <T> node, Func <UndirectedGraphNode <T>, bool> inspectFunc)
 {
     if (inspectFunc(node))
     {
         return;
     }
     foreach (var neighbor in node.GetNeighbors())
     {
         if (!neighbor.Value.IsVisited)
         {
             InternalDfs(nodes, neighbor.Value, inspectFunc);
         }
     }
 }
        /// <summary>
        /// Generic BFS function. Can be used to solve any problem that requires BFS, just plug in the inspectionFunc.
        /// </summary>
        /// <param name="inspectFunc">Must return true if the search is completed and no more nodes need to be checked</param>
        /// <param name="startId">Starting node, by default it is 0.</param>
        public void Bfs(Func <UndirectedGraphNode <T>, bool> inspectFunc, bool countComponents)
        {
            if (Nodes.Count == 0)
            {
                return;
            }

            Queue <UndirectedGraphNode <T> > nodeQueue = new Queue <UndirectedGraphNode <T> >();

            foreach (var undirectedGraphNode in Nodes)
            {
                if (!undirectedGraphNode.Value.IsVisited)
                {
                    if (countComponents)
                    {
                        NumberOfComponents++;
                    }
                    nodeQueue.Enqueue(undirectedGraphNode.Value);
                    undirectedGraphNode.Value.IsVisited = true;
                    while (nodeQueue.Count != 0)
                    {
                        UndirectedGraphNode <T> currentNode = nodeQueue.Dequeue();

                        if (inspectFunc != null && inspectFunc(currentNode))
                        {
                            return;
                        }

                        foreach (var neighbor in currentNode.GetNeighbors())
                        {
                            if (!neighbor.Value.IsVisited)
                            {
                                neighbor.Value.IsVisited = true;
                                nodeQueue.Enqueue(neighbor.Value);
                            }
                        }
                    }
                }
            }
        }