DirectedGraph { public boolean isConnected(T from, T to) { if (from.equals(to)) return true; return isConnected(from, to, new HashSet<T>()); } DirectedGraph();  DirectedGraph(DirectedGraph<T> graph); Set<T> getNodes(); Set<Pair<T>> getEdges(); Set<T> getInboundNodes(T node); Set<T> getOutboundNodes(T node); boolean isConnected(T from, T to); void addNode(T node); void addEdge(T from, T to); void removeEdge(T from, T to); List<T> getTopologicalSort(Comparator<T> tieBreaker);  }
@Test public void testIsConnected() { DirectedGraph<String> graph = new DirectedGraph<String>(); graph.addNode("a"); graph.addNode("b"); assertFalse(graph.isConnected("a", "b")); graph.addEdge("a", "b"); assertTrue(graph.isConnected("a", "b")); assertFalse(graph.isConnected("b", "a")); graph.addEdge("b", "c"); assertTrue(graph.isConnected("a", "b")); assertTrue(graph.isConnected("b", "c")); assertTrue(graph.isConnected("a", "c")); assertFalse(graph.isConnected("b", "a")); assertFalse(graph.isConnected("c", "b")); assertFalse(graph.isConnected("c", "a")); }