public List<List<Integer>> getSCCs () {
        finishTimesPerVertex = new int [graph.numVertices()];
        int [] vertexPerFinishTimes = new int [graph.numVertices()];
        leaders = new int [graph.numVertices()];
        visited = new boolean [graph.numVertices()];
        time = 0;
        source = -1;
        for (int i = graph.numVertices() - 1; i >= 0; i--) {
            if (!visited[i]) {
                source = i;
                dfs2 (i, true);
            }
        }
        for (int i = 0; i < visited.length; i++) {
            visited[i] = false;
        }
        for (int i = 0; i < finishTimesPerVertex.length; i++) {
            vertexPerFinishTimes[finishTimesPerVertex[i]] = i;
        }
        time = 0;
        source = -1;
        for (int i = vertexPerFinishTimes.length - 1; i >= 0; i--) {
            int u = vertexPerFinishTimes[i];
            if (!visited[u]) {
                source = u;
                dfs2 (u, false);
            }
        }
        Map<Integer, List<Integer>> sccs = new HashMap<Integer, List<Integer>> ();
        for (int i = 0; i < leaders.length; i++) {
            System.out.println(i + " " + leaders[i]);
            if (!sccs.containsKey(leaders[i])) {
                sccs.put(Integer.valueOf(leaders[i]), new LinkedList<Integer>());
            }
            sccs.get(Integer.valueOf(leaders[i])).add(i);
        }
        List<List<Integer>> sccList = new LinkedList<List<Integer>> ();
        for (Map.Entry<Integer,List<Integer>> entry : sccs.entrySet()) {
            sccList.add(entry.getValue());
        }
        return sccList;
    }