public void depthFirstSearch() {

    /*
     * Traverse the entire graph in breadth-first order. When finished, every node will have a
     * predecessor which indicates the node that came before it in the search
     * It will also have a discovery time (the value of the counter when we first saw it) and
     * finishingTime (the value of the counter after we've visited all the adjacent nodes).
     * See Cormen, Leiserson and Rivest, Section 23.3, page 477 for a full explanation of the algorithm
     */

    // Setup
    for (Enumeration e = getNodes().elements(); e.hasMoreElements(); ) {
      CommitOrderDependencyNode node = (CommitOrderDependencyNode) e.nextElement();
      node.markNotVisited();
      node.setPredecessor(null);
    }
    currentTime = 0;

    // Execution
    for (Enumeration e = getNodes().elements(); e.hasMoreElements(); ) {
      CommitOrderDependencyNode node = (CommitOrderDependencyNode) e.nextElement();
      if (node.hasNotBeenVisited()) {
        node.visit();
      }
    }
  }