void operator()(GNode item, Galois::UserContext<GNode>& ctx) {
    if (!graph->containsNode(item, Galois::ALL))
      return;
    
    Cavity* cavp = NULL;

    if (Version == detDisjoint) {
      bool used;
      LocalState* localState = (LocalState*) ctx.getLocalState(used);
      if (used) {
        localState->cav.update(item, ctx);
        return;
      } else {
        cavp = &localState->cav;
      }
    }

    if (Version == detDisjoint) {
      cavp->initialize(item);
      cavp->build();
      cavp->computePost();
    } else {
      Cavity cav(graph, ctx.getPerIterAlloc());
      cav.initialize(item);
      cav.build();
      cav.computePost();
      if (Version == detPrefix)
        return;
      cav.update(item, ctx);
    }
  }
  /**
   * Do reverse BFS on residual graph.
   */
  void operator()(const GNode& src, Galois::UserContext<GNode>& ctx) {
    if (version != nondet) {
      bool used = false;
      if (version == detDisjoint) {
        ctx.getLocalState(used);
      }

      if (!used) {
        for (Graph::edge_iterator
            ii = app.graph.edge_begin(src, Galois::CHECK_CONFLICT),
            ee = app.graph.edge_end(src, Galois::CHECK_CONFLICT);
            ii != ee; ++ii) {
          GNode dst = app.graph.getEdgeDst(ii);
          int rdata = app.graph.getEdgeData(findEdge(app.graph, dst, src));
          if (rdata > 0) {
            app.graph.getData(dst, Galois::CHECK_CONFLICT);
          }
        }
      }

      if (version == detDisjoint) {
        if (!used)
          return;
      } else {
        app.graph.getData(src, Galois::WRITE);
      }
    }

    for (Graph::edge_iterator
        ii = app.graph.edge_begin(src, useCAS ? Galois::NONE : Galois::CHECK_CONFLICT),
        ee = app.graph.edge_end(src, useCAS ? Galois::NONE : Galois::CHECK_CONFLICT);
        ii != ee; ++ii) {
      GNode dst = app.graph.getEdgeDst(ii);
      int rdata = app.graph.getEdgeData(findEdge(app.graph, dst, src));
      if (rdata > 0) {
        Node& node = app.graph.getData(dst, Galois::NONE);
        int newHeight = app.graph.getData(src, Galois::NONE).height + 1;
        if (useCAS) {
          int oldHeight;
          while (newHeight < (oldHeight = node.height)) {
            if (__sync_bool_compare_and_swap(&node.height, oldHeight, newHeight)) {
              ctx.push(dst);
              break;
            }
          }
        } else {
          if (newHeight < node.height) {
            node.height = newHeight;
            ctx.push(dst);
          }
        }
      }
    }
  }
  void operator()(GNode& src, Galois::UserContext<GNode>& ctx) {
    if (version != nondet) {
      bool used = false;
      if (version == detDisjoint) {
        ctx.getLocalState(used);
      }
      if (!used) {
        acquire(src);
      }
      if (version == detDisjoint) {
        if (!used)
          return;
      } else {
        app.graph.getData(src, Galois::WRITE);
      }
    }

    int increment = 1;
    if (discharge(src, ctx)) {
      increment += BETA;
    }

    counter.accum += increment;
  }