docs: public void findStronglyConnectedComponents(GraphType g, GraphToolkit<GraphType, EdgeType, VertexType> toolkit) {
  
          // Perform the initial depth first search
          DepthFirstSearch<GraphType, EdgeType, VertexType> initialDFS = new DepthFirstSearch<>(g);
          if (m_vertexChooser != null) {
              initialDFS.setVertexChooser(m_vertexChooser);
          }
          initialDFS.search();
  
          // Create a transposed graph
          Transpose<GraphType, EdgeType, VertexType> t = new Transpose<>();
          GraphType transpose = t.transpose(g, toolkit);
  
          // Create a set of vertices in the transposed graph,
          // in descending order of finish time in the initial
          // depth first search.
          VisitationTimeComparator<VertexType> comparator = new VisitationTimeComparator<>(
                  initialDFS.getFinishTimeList(), VisitationTimeComparator.DESCENDING);
          Set<VertexType> descendingByFinishTimeSet = new TreeSet<>(comparator);
          Iterator<VertexType> i = transpose.vertexIterator();
          while (i.hasNext()) {
              descendingByFinishTimeSet.add(i.next());
          }
  
          // Create a SearchTreeBuilder for transposed DFS
          SearchTreeBuilder<VertexType> searchTreeBuilder = new SearchTreeBuilder<>();
  
          // Now perform a DFS on the transpose, choosing the vertices
          // to visit in the main loop by descending finish time
          final Iterator<VertexType> vertexIter = descendingByFinishTimeSet.iterator();
          DepthFirstSearch<GraphType, EdgeType, VertexType> transposeDFS = new DepthFirstSearch<GraphType, EdgeType, VertexType>(
                  transpose) {
              @Override
              protected VertexType getNextSearchTreeRoot() {
                  while (vertexIter.hasNext()) {
                      VertexType vertex = vertexIter.next();
                      if (visitMe(vertex)) {
                          return vertex;
                      }
                  }
                  return null;
              }
          };
          if (m_vertexChooser != null) {
              transposeDFS.setVertexChooser(m_vertexChooser);
          }
          transposeDFS.setSearchTreeCallback(searchTreeBuilder);
          transposeDFS.search();
  
          // The search tree roots of the second DFS represent the
          // strongly connected components. Note that we call copySearchTree()
          // to make the returned search trees relative to the original
          // graph, not the transposed graph (which would be very confusing).
          Iterator<SearchTree<VertexType>> j = searchTreeBuilder.searchTreeIterator();
          while (j.hasNext()) {
              m_stronglyConnectedSearchTreeList.add(copySearchTree(j.next(), t));
          }
      }