Program: 133014
Project: 133014
Buggy source:
private static boolean mergeWaits(Logger logger,Function fn,Block block){
  boolean changed=false;
  boolean fin;
  do {
    fin=true;
    MultiMap<Var,WaitStatement> waitMap=buildWaitMap(block);
    Var winner=mostSharedVar(waitMap);
    if (winner != null) {
      fin=false;
      changed=true;
      List<WaitStatement> waits=waitMap.get(winner);
      assert(waits != null && waits.size() >= 2);
      boolean explicit=false;
      boolean allRecursive=true;
      Set<Var> intersection=null;
      for (      WaitStatement wait : waits) {
        Set<Var> waitVars=new HashSet<Var>(wait.getWaitVars());
        if (intersection == null) {
          intersection=waitVars;
        }
 else {
          intersection.retainAll(waitVars);
        }
        explicit=explicit || wait.getMode() != WaitMode.DATA_ONLY;
        allRecursive=allRecursive && wait.isRecursive();
      }
      assert(intersection != null && !intersection.isEmpty());
      WaitStatement newWait=new WaitStatement(fn.getName() + "String_Node_Str",new ArrayList<Var>(intersection),PassedVar.NONE,Var.NONE,null,explicit ? WaitMode.EXPLICIT : WaitMode.DATA_ONLY,allRecursive,TaskMode.LOCAL);
      for (      WaitStatement wait : waits) {
        if (allRecursive) {
          wait.tryInline(Collections.<Var>emptySet(),intersection);
        }
 else {
          wait.tryInline(intersection,Collections.<Var>emptySet());
        }
        if (wait.getWaitVars().isEmpty() && wait.getMode() != WaitMode.TASK_DISPATCH) {
          newWait.getBlock().insertInline(wait.getBlock());
        }
 else {
          wait.setParent(newWait.getBlock());
          newWait.getBlock().addContinuation(wait);
        }
      }
      block.addContinuation(newWait);
      block.removeContinuations(waits);
    }
    changed=changed || !fin;
  }
 while (!fin);
  return changed;
}

Fixed version (ground truth):
private static boolean mergeWaits(Logger logger,Function fn,Block block){
  boolean changed=false;
  boolean fin;
  do {
    fin=true;
    MultiMap<Var,WaitStatement> waitMap=buildWaitMap(block);
    Var winner=mostSharedVar(waitMap);
    if (winner != null) {
      fin=false;
      changed=true;
      List<WaitStatement> waits=waitMap.get(winner);
      assert(waits != null && waits.size() >= 2);
      boolean explicit=false;
      boolean allRecursive=true;
      Set<Var> intersection=null;
      for (      WaitStatement wait : waits) {
        Set<Var> waitVars=new HashSet<Var>(wait.getWaitVars());
        if (intersection == null) {
          intersection=waitVars;
        }
 else {
          intersection.retainAll(waitVars);
        }
        explicit=explicit || wait.getMode() != WaitMode.DATA_ONLY;
        allRecursive=allRecursive && wait.isRecursive();
      }
      assert(intersection != null && !intersection.isEmpty());
      WaitStatement newWait=new WaitStatement(fn.getName() + "String_Node_Str",new ArrayList<Var>(intersection),PassedVar.NONE,Var.NONE,null,explicit ? WaitMode.EXPLICIT : WaitMode.DATA_ONLY,allRecursive,TaskMode.LOCAL);
      for (      WaitStatement wait : waits) {
        if (allRecursive) {
          wait.tryInline(Collections.<Var>emptySet(),intersection,false);
        }
 else {
          wait.tryInline(intersection,Collections.<Var>emptySet(),false);
        }
        if (wait.getWaitVars().isEmpty() && wait.getMode() != WaitMode.TASK_DISPATCH) {
          newWait.getBlock().insertInline(wait.getBlock());
        }
 else {
          wait.setParent(newWait.getBlock());
          newWait.getBlock().addContinuation(wait);
        }
      }
      block.addContinuation(newWait);
      block.removeContinuations(waits);
    }
    changed=changed || !fin;
  }
 while (!fin);
  return changed;
}