public NodePartition<N> apply(Graph<N> g) { ImmutableSet<ImmutableList<N>> nodePairs = getEquivalentPairs(g); Set<Set<N>> rv = new HashSet<Set<N>>(); Map<N, Set<N>> intermediate = new HashMap<N, Set<N>>(); for (ImmutableList<N> pair : nodePairs) { Set<N> res = intermediate.get(pair.get(0)); if (res == null) { res = intermediate.get(pair.get(1)); } if (res == null) { // we haven't seen this one before res = new HashSet<N>(); } res.add(pair.get(0)); res.add(pair.get(1)); intermediate.put(pair.get(0), res); intermediate.put(pair.get(1), res); } rv.addAll(intermediate.values()); // pick up the nodes which don't appear in intermediate; they are // singletons (equivalence classes of size 1) Collection<N> singletons = new ArrayList<N>(g.nodes()); singletons.removeAll(intermediate.keySet()); for (N v : singletons) { Set<N> vSet = Collections.singleton(v); intermediate.put(v, vSet); rv.add(vSet); } return new NodePartition<N>(g, intermediate, rv); }