Program: 2513
Project: 2513
Buggy source:
/** 
 * This method projects the supplied model object based on the specified role.
 * @param model The model object
 * @param role The role
 * @param l The model listener
 * @return The projected model object
 */
public ModelObject project(ProjectorContext context,ModelObject model,Role role,Journal l){
  Choice ret=new Choice();
  Choice source=(Choice)model;
  boolean f_merge=false;
  boolean f_rolesSet=false;
  Role fromRole=null;
  Role toRole=null;
  ret.derivedFrom(source);
  if (source.getFromRole() != null && source.getFromRole().getName().equals(role.getName()) == false) {
    ret.setFromRole(new Role(source.getFromRole()));
  }
  if (source.getToRole() != null && source.getToRole().getName().equals(role.getName()) == false) {
    ret.setToRole(new Role(source.getToRole()));
  }
  if ((ret.getFromRole() != null && ret.getToRole() != null) || (ret.getFromRole() == null && ret.getToRole() == null)) {
    f_merge=true;
  }
  for (int i=0; i < source.getWhens().size(); i++) {
    When block=(When)context.project(source.getWhens().get(i),role,l);
    if (block != null) {
      ret.getWhens().add(block);
      if (f_merge) {
        java.util.List<ModelObject> list=org.scribble.protocol.util.InteractionUtil.getInitialInteractions(block);
        ret.getWhens().remove(block);
        for (        ModelObject act : list) {
          MessageSignature ms=InteractionUtil.getMessageSignature(act);
          boolean f_add=true;
          for (          When wb : ret.getWhens()) {
            MessageSignature wbms=InteractionUtil.getMessageSignature(wb);
            if (ms.equals(wbms)) {
              l.error("String_Node_Str",null);
              f_add=false;
            }
          }
          if (f_add) {
            if (f_rolesSet == false) {
              fromRole=InteractionUtil.getFromRole(act);
              toRole=InteractionUtil.getToRole(act);
              f_rolesSet=true;
            }
 else {
            }
            if (act instanceof When) {
              ret.getWhens().add((When)act);
            }
 else             if (act instanceof Interaction) {
              When newwb=new When();
              newwb.derivedFrom(act);
              newwb.setMessageSignature(new MessageSignature(ms));
              Block b=(Block)act.getParent();
              for (              Activity a : b.getContents()) {
                if (a != act) {
                  newwb.getBlock().add(a);
                }
              }
              ret.getWhens().add(newwb);
            }
          }
        }
      }
    }
  }
  if (f_merge) {
    ret.setFromRole(fromRole);
    ret.setToRole(toRole);
  }
  if (ret.getWhens().size() == 1) {
    Block b=new Block();
    Interaction interaction=new Interaction();
    interaction.derivedFrom(ret.getWhens().get(0));
    interaction.setMessageSignature(ret.getWhens().get(0).getMessageSignature());
    interaction.setFromRole(ret.getFromRole());
    if (ret.getToRole() != null) {
      interaction.getToRoles().add(ret.getToRole());
    }
    b.add(interaction);
    for (    Activity act : ret.getWhens().get(0).getBlock().getContents()) {
      b.add(act);
    }
    return (b);
  }
 else   if (ret.getWhens().size() == 0) {
    ret=null;
  }
  return (ret);
}

Fixed version (ground truth):
/** 
 * This method projects the supplied model object based on the specified role.
 * @param model The model object
 * @param role The role
 * @param l The model listener
 * @return The projected model object
 */
public ModelObject project(ProjectorContext context,ModelObject model,Role role,Journal l){
  Choice ret=new Choice();
  Choice source=(Choice)model;
  boolean f_merge=false;
  boolean f_rolesSet=false;
  Role fromRole=null;
  Role toRole=null;
  ret.derivedFrom(source);
  if (source.getFromRole() != null && source.getFromRole().getName().equals(role.getName()) == false) {
    ret.setFromRole(new Role(source.getFromRole()));
  }
  if (source.getToRole() != null && source.getToRole().getName().equals(role.getName()) == false) {
    ret.setToRole(new Role(source.getToRole()));
  }
  if ((ret.getFromRole() != null && ret.getToRole() != null) || (ret.getFromRole() == null && ret.getToRole() == null)) {
    f_merge=true;
  }
  for (int i=0; i < source.getWhens().size(); i++) {
    When block=(When)context.project(source.getWhens().get(i),role,l);
    if (block != null) {
      ret.getWhens().add(block);
    }
  }
  if (f_merge) {
    Role destination=null;
    for (    When block : ret.getWhens()) {
      java.util.List<ModelObject> list=org.scribble.protocol.util.InteractionUtil.getInitialInteractions(block);
      for (      ModelObject act : list) {
        Role r=InteractionUtil.getToRole(act);
        if (destination == null) {
          destination=r;
        }
 else         if (destination.equals(r) == false) {
          f_merge=false;
          break;
        }
      }
      if (f_merge == false) {
        break;
      }
    }
  }
  if (f_merge) {
    java.util.List<When> tmp=new java.util.Vector<When>(ret.getWhens());
    for (    When block : tmp) {
      java.util.List<ModelObject> list=org.scribble.protocol.util.InteractionUtil.getInitialInteractions(block);
      ret.getWhens().remove(block);
      for (      ModelObject act : list) {
        MessageSignature ms=InteractionUtil.getMessageSignature(act);
        boolean f_add=true;
        for (        When wb : ret.getWhens()) {
          MessageSignature wbms=InteractionUtil.getMessageSignature(wb);
          if (ms.equals(wbms)) {
            l.error("String_Node_Str",null);
            f_add=false;
          }
        }
        if (f_add) {
          if (f_rolesSet == false) {
            fromRole=InteractionUtil.getFromRole(act);
            toRole=InteractionUtil.getToRole(act);
            f_rolesSet=true;
          }
 else {
          }
          if (act instanceof When) {
            ret.getWhens().add((When)act);
          }
 else           if (act instanceof Interaction) {
            When newwb=new When();
            newwb.derivedFrom(act);
            newwb.setMessageSignature(new MessageSignature(ms));
            Block b=(Block)act.getParent();
            for (            Activity a : b.getContents()) {
              if (a != act) {
                newwb.getBlock().add(a);
              }
            }
            ret.getWhens().add(newwb);
          }
        }
      }
    }
  }
  if (f_merge) {
    ret.setFromRole(fromRole);
    ret.setToRole(toRole);
  }
  if (ret.getWhens().size() == 1) {
    Block b=new Block();
    Interaction interaction=new Interaction();
    interaction.derivedFrom(ret.getWhens().get(0));
    interaction.setMessageSignature(ret.getWhens().get(0).getMessageSignature());
    interaction.setFromRole(ret.getFromRole());
    if (ret.getToRole() != null) {
      interaction.getToRoles().add(ret.getToRole());
    }
    b.add(interaction);
    for (    Activity act : ret.getWhens().get(0).getBlock().getContents()) {
      b.add(act);
    }
    return (b);
  }
 else   if (ret.getWhens().size() == 0) {
    ret=null;
  }
  return (ret);
}