Program: 4637
Project: 4637
Buggy source:
/** 
 * Split the dag based on the input control nodes.
 * @param controlNodes set of conditions and actions based on which to split the Dag
 * @return set of splitted dags
 */
public Set<Dag> splitByControlNodes(Set<String> controlNodes){
  Set<Dag> dags=new HashSet<>();
  Set<String> childStopperNodes=Sets.union(sinks,controlNodes);
  Set<String> accessibleFromSources=accessibleFrom(sources,childStopperNodes);
  if (!controlNodes.containsAll(sources)) {
    dags.add(createSubDag(accessibleFromSources));
  }
  for (  String controlNode : controlNodes) {
    Set<String> outputs=getNodeOutputs(controlNode);
    for (    String output : outputs) {
      if (controlNodes.contains(output)) {
        dags.add(createSubDag(new HashSet<>(Arrays.asList(controlNode,output))));
        continue;
      }
      Set<String> childNodes=accessibleFrom(output,childStopperNodes);
      childNodes.add(controlNode);
      dags.add(createSubDag(childNodes));
    }
  }
  return dags;
}

Fixed version (ground truth):
/** 
 * Split the dag based on the input control nodes.
 * @param controlNodes set of conditions and actions based on which to split the Dag
 * @return set of splitted dags
 */
public Set<Dag> splitByControlNodes(Set<String> controlNodes){
  Set<Dag> dags=new HashSet<>();
  Dag copy=new Dag(this);
  Set<String> controlSources=new HashSet<>(Sets.intersection(copy.sources,controlNodes));
  while (!controlSources.isEmpty()) {
    for (    String controlSource : controlSources) {
      for (      String output : copy.getNodeOutputs(controlSource)) {
        dags.add(createSubDag(ImmutableSet.of(controlSource,output)));
      }
      copy.removeNode(controlSource);
    }
    controlSources.clear();
    controlSources.addAll(Sets.intersection(copy.sources,controlNodes));
  }
  Set<String> controlSinks=new HashSet<>(Sets.intersection(copy.sinks,controlNodes));
  while (!controlSinks.isEmpty()) {
    for (    String controlSink : controlSinks) {
      for (      String input : copy.getNodeInputs(controlSink)) {
        dags.add(createSubDag(ImmutableSet.of(input,controlSink)));
      }
      copy.removeNode(controlSink);
    }
    controlSinks.clear();
    controlSinks.addAll(Sets.intersection(copy.sources,controlNodes));
  }
  if (copy.getNodes().size() < 2) {
    return dags;
  }
  Set<String> remainingControlNodes=Sets.intersection(copy.nodes,controlNodes);
  List<Set<String>> sourceSubdags=new ArrayList<>(copy.sources.size());
  for (  String source : copy.sources) {
    sourceSubdags.add(copy.accessibleFrom(source,remainingControlNodes));
  }
  boolean done=sourceSubdags.size() <= 1;
  while (!done) {
    List<Set<String>> mergedSubdags=new ArrayList<>();
    Iterator<Set<String>> subdagIter=sourceSubdags.iterator();
    mergedSubdags.add(subdagIter.next());
    done=true;
    while (subdagIter.hasNext()) {
      Set<String> subdag=subdagIter.next();
      boolean merged=false;
      for (      Set<String> mergedSubdag : mergedSubdags) {
        if (!Sets.intersection(mergedSubdag,subdag).isEmpty()) {
          mergedSubdag.addAll(subdag);
          merged=true;
          done=false;
          break;
        }
      }
      if (!merged) {
        mergedSubdags.add(subdag);
      }
    }
    sourceSubdags=mergedSubdags;
  }
  for (  Set<String> sourceSubdag : sourceSubdags) {
    dags.add(createSubDag(sourceSubdag));
  }
  for (  String controlNode : remainingControlNodes) {
    Set<String> outputs=copy.getNodeOutputs(controlNode);
    for (    String output : outputs) {
      if (remainingControlNodes.contains(output)) {
        dags.add(createSubDag(new HashSet<>(Arrays.asList(controlNode,output))));
        continue;
      }
      Set<String> childNodes=accessibleFrom(output,remainingControlNodes);
      childNodes.add(controlNode);
      dags.add(createSubDag(childNodes));
    }
  }
  return dags;
}