Program: 120210
Project: 120210
Buggy source:
private void changeForMultipleMergeComponents(INode graphicalNode){
  String hashMergeOutput="String_Node_Str";
  String hashMergeInput="String_Node_Str";
  INode mergeDataNode=buildCheckMap.get(graphicalNode);
  IComponent hashMergeOutputComponent=ComponentsFactoryProvider.getInstance().get(hashMergeOutput,ComponentCategory.CATEGORY_4_DI.getName());
  IComponent hashMergeInputComponent=ComponentsFactoryProvider.getInstance().get(hashMergeInput,ComponentCategory.CATEGORY_4_DI.getName());
  if (hashMergeOutputComponent == null || hashMergeInputComponent == null) {
    return;
  }
  String hashOutputUniqueName=hashMergeOutput + "String_Node_Str" + mergeDataNode.getUniqueName();
  List mergeOutputConnections=NodeUtil.getOutgoingConnections(mergeDataNode,IConnectionCategory.MAIN);
  if (mergeOutputConnections.size() == 0) {
    return;
  }
  IConnection mergeOutputConnection=((List<IConnection>)mergeOutputConnections).get(0);
  DataNode hashNode=new DataNode(hashMergeOutputComponent,hashOutputUniqueName);
  hashNode.setActivate(mergeDataNode.isActivate());
  hashNode.setStart(false);
  hashNode.setDesignSubjobStartNode(null);
  hashNode.getMetadataList().remove(0);
  IMetadataTable newMetadata=mergeDataNode.getMetadataList().get(0).clone();
  newMetadata.setTableName(hashOutputUniqueName);
  hashNode.getMetadataList().add(newMetadata);
  hashNode.setSubProcessStart(false);
  hashNode.setProcess(graphicalNode.getProcess());
  List<IConnection> outgoingConnections=new ArrayList<IConnection>();
  List<IConnection> incomingConnections=new ArrayList<IConnection>();
  hashNode.setIncomingConnections(incomingConnections);
  hashNode.setOutgoingConnections(outgoingConnections);
  hashNode.setVirtualGenerateNode(false);
  addDataNode(hashNode);
  incomingConnections.add(mergeOutputConnection);
  INode oldNodeTarget=((DataConnection)mergeOutputConnection).getTarget();
  ((DataConnection)mergeOutputConnection).setTarget(hashNode);
  oldNodeTarget.getIncomingConnections().remove(mergeOutputConnection);
  String hashInputUniqueName=hashMergeInput + "String_Node_Str" + mergeDataNode.getUniqueName();
  hashNode=new DataNode(hashMergeInputComponent,hashInputUniqueName);
  hashNode.setActivate(mergeDataNode.isActivate());
  hashNode.setStart(false);
  hashNode.setDesignSubjobStartNode(null);
  newMetadata=mergeDataNode.getMetadataList().get(0).clone();
  newMetadata.setTableName(hashInputUniqueName);
  hashNode.getMetadataList().remove(0);
  hashNode.getMetadataList().add(newMetadata);
  hashNode.setSubProcessStart(true);
  hashNode.setProcess(graphicalNode.getProcess());
  outgoingConnections=new ArrayList<IConnection>();
  incomingConnections=new ArrayList<IConnection>();
  hashNode.setIncomingConnections(incomingConnections);
  hashNode.setOutgoingConnections(outgoingConnections);
  hashNode.setVirtualGenerateNode(false);
  hashNode.getElementParameter("String_Node_Str").setValue(Boolean.TRUE);
  hashNode.getElementParameter("String_Node_Str").setValue(hashOutputUniqueName);
  DataConnection dataConnec=new DataConnection();
  dataConnec.setActivate(mergeOutputConnection.isActivate());
  dataConnec.setLineStyle(mergeOutputConnection.getLineStyle());
  dataConnec.setConnectorName(mergeOutputConnection.getConnectorName());
  dataConnec.setMetadataTable(newMetadata);
  dataConnec.setTraceConnection(mergeOutputConnection.isTraceConnection());
  dataConnec.setMonitorConnection(mergeOutputConnection.isMonitorConnection());
  dataConnec.setTracesCondition(mergeOutputConnection.getTracesCondition());
  dataConnec.setEnabledTraceColumns(mergeOutputConnection.getEnabledTraceColumns());
  dataConnec.setName(mergeOutputConnection.getName());
  dataConnec.setSource(hashNode);
  dataConnec.setLinkNodeForHash(((DataConnection)mergeOutputConnection).getLinkNodeForHash());
  dataConnec.setElementParameters(mergeOutputConnection.getElementParameters());
  dataConnec.setUniqueName(mergeOutputConnection.getUniqueName());
  mergeOutputConnection.setElementParameters(new ArrayList<IElementParameter>());
  dataConnec.setTarget(oldNodeTarget);
  ((DataConnection)mergeOutputConnection).setName(hashNode.getUniqueName() + "String_Node_Str" + mergeOutputConnection.getName());
  ((DataConnection)mergeOutputConnection).setUniqueName(hashNode.getUniqueName() + "String_Node_Str" + mergeOutputConnection.getName());
  int inputId=mergeOutputConnection.getInputId();
  if (inputId == 0) {
    List refOutputConnections=NodeUtil.getOutgoingConnections(mergeDataNode,EConnectionType.FLOW_REF);
    if (refOutputConnections.size() != 0) {
      IConnection refConnection=((List<IConnection>)refOutputConnections).get(0);
      inputId=refConnection.getInputId();
      mergeDataNode.getOutgoingConnections().remove(refConnection);
      ((DataConnection)refConnection).setSource(hashNode);
      ((List<IConnection>)hashNode.getOutgoingConnections()).add(refConnection);
    }
  }
  dataConnec.setInputId(inputId);
  outgoingConnections.add(dataConnec);
  if (inputId == 1) {
    ((List<IConnection>)oldNodeTarget.getIncomingConnections()).add(0,dataConnec);
  }
 else {
    ((List<IConnection>)oldNodeTarget.getIncomingConnections()).add(dataConnec);
  }
  ((DataConnection)mergeOutputConnection).setLineStyle(EConnectionType.FLOW_MAIN);
  ((DataConnection)mergeOutputConnection).setConnectorName(EConnectionType.FLOW_MAIN.getName());
  addDataNode(hashNode);
  INode afterMergeStart=hashNode.getSubProcessStartNode(false);
  INode mergeSubNodeStart=mergeDataNode.getSubProcessStartNode(false);
  boolean changeStartNode=false;
  if (mergeDataNode.getLinkedMergeInfo() == null || mergeDataNode.getLinkedMergeInfo().isEmpty()) {
    changeStartNode=true;
  }
 else {
    Map<INode,Integer> nextMergeNodes=mergeDataNode.getLinkedMergeInfo();
    if (nextMergeNodes.size() == 1) {
      INode followMergeNode=nextMergeNodes.keySet().iterator().next();
      List nextMergeOutputConnections=NodeUtil.getOutgoingConnections(followMergeNode,IConnectionCategory.DATA);
      if (nextMergeNodes.get(followMergeNode) == 1) {
        if (nextMergeOutputConnections == null || nextMergeOutputConnections.isEmpty()) {
          changeStartNode=true;
        }
      }
    }
  }
  if (changeStartNode) {
    INode oldStartNode=null;
    if (mergeDataNode.isThereLinkWithHash()) {
      oldStartNode=mergeDataNode.getSubProcessStartNode(false);
    }
 else {
      oldStartNode=mergeDataNode.getDesignSubjobStartNode();
    }
    ((AbstractNode)afterMergeStart).setStart(oldStartNode.isStart());
    ((AbstractNode)oldStartNode).setStart(false);
    for (    INode curNode : dataNodeList) {
      if (curNode instanceof AbstractNode) {
        if (curNode.getDesignSubjobStartNode().equals(oldStartNode)) {
          ((AbstractNode)curNode).setDesignSubjobStartNode(afterMergeStart);
        }
      }
    }
    List<IConnection> depConnections=(List<IConnection>)NodeUtil.getOutgoingConnections(oldStartNode,IConnectionCategory.EXECUTION_ORDER);
    oldStartNode.getOutgoingConnections().removeAll(depConnections);
    ((List<IConnection>)afterMergeStart.getOutgoingConnections()).addAll(depConnections);
    for (    IConnection curDepConnection : depConnections) {
      ((AbstractConnection)curDepConnection).setSource(afterMergeStart);
    }
    depConnections=(List<IConnection>)NodeUtil.getIncomingConnections(oldStartNode,IConnectionCategory.DEPENDENCY);
    for (    IConnection connection : connectionsToIgnoreInMerge) {
      if (depConnections.contains(connection)) {
        depConnections.remove(connection);
      }
    }
    oldStartNode.getIncomingConnections().removeAll(depConnections);
    ((List<IConnection>)afterMergeStart.getIncomingConnections()).addAll(depConnections);
    for (    IConnection curDepConnection : depConnections) {
      ((AbstractConnection)curDepConnection).setTarget(afterMergeStart);
    }
  }
  dataConnec=new DataConnection();
  dataConnec.setActivate(mergeOutputConnection.isActivate());
  dataConnec.setLineStyle(EConnectionType.RUN_AFTER);
  dataConnec.setConnectorName(EConnectionType.RUN_AFTER.getName());
  dataConnec.setTraceConnection(false);
  dataConnec.setName(hashNode.getUniqueName() + "String_Node_Str" + EConnectionType.RUN_AFTER.getDefaultLinkName());
  dataConnec.setSource(afterMergeStart);
  dataConnec.setTarget(mergeSubNodeStart);
  connectionsToIgnoreInMerge.add(dataConnec);
  ((List<IConnection>)mergeSubNodeStart.getIncomingConnections()).add(dataConnec);
  ((List<IConnection>)afterMergeStart.getOutgoingConnections()).add(dataConnec);
}

Fixed version (ground truth):
private void changeForMultipleMergeComponents(INode graphicalNode){
  String hashMergeOutput="String_Node_Str";
  String hashMergeInput="String_Node_Str";
  INode mergeDataNode=buildCheckMap.get(graphicalNode);
  IComponent hashMergeOutputComponent=ComponentsFactoryProvider.getInstance().get(hashMergeOutput,ComponentCategory.CATEGORY_4_DI.getName());
  IComponent hashMergeInputComponent=ComponentsFactoryProvider.getInstance().get(hashMergeInput,ComponentCategory.CATEGORY_4_DI.getName());
  if (hashMergeOutputComponent == null || hashMergeInputComponent == null) {
    return;
  }
  String hashOutputUniqueName=hashMergeOutput + "String_Node_Str" + mergeDataNode.getUniqueName();
  List mergeOutputConnections=NodeUtil.getOutgoingConnections(mergeDataNode,IConnectionCategory.MAIN);
  if (mergeOutputConnections.size() == 0) {
    return;
  }
  IConnection mergeOutputConnection=((List<IConnection>)mergeOutputConnections).get(0);
  DataNode hashNode=new DataNode(hashMergeOutputComponent,hashOutputUniqueName);
  hashNode.setActivate(mergeDataNode.isActivate());
  hashNode.setStart(false);
  hashNode.setDesignSubjobStartNode(null);
  hashNode.getMetadataList().remove(0);
  IMetadataTable newMetadata=mergeDataNode.getMetadataList().get(0).clone();
  newMetadata.setTableName(hashOutputUniqueName);
  hashNode.getMetadataList().add(newMetadata);
  hashNode.setSubProcessStart(false);
  hashNode.setProcess(graphicalNode.getProcess());
  List<IConnection> outgoingConnections=new ArrayList<IConnection>();
  List<IConnection> incomingConnections=new ArrayList<IConnection>();
  hashNode.setIncomingConnections(incomingConnections);
  hashNode.setOutgoingConnections(outgoingConnections);
  hashNode.setVirtualGenerateNode(false);
  addDataNode(hashNode);
  incomingConnections.add(mergeOutputConnection);
  INode oldNodeTarget=((DataConnection)mergeOutputConnection).getTarget();
  ((DataConnection)mergeOutputConnection).setTarget(hashNode);
  oldNodeTarget.getIncomingConnections().remove(mergeOutputConnection);
  String hashInputUniqueName=hashMergeInput + "String_Node_Str" + mergeDataNode.getUniqueName();
  hashNode=new DataNode(hashMergeInputComponent,hashInputUniqueName);
  hashNode.setActivate(mergeDataNode.isActivate());
  hashNode.setStart(false);
  hashNode.setDesignSubjobStartNode(null);
  newMetadata=mergeDataNode.getMetadataList().get(0).clone();
  newMetadata.setTableName(hashInputUniqueName);
  hashNode.getMetadataList().remove(0);
  hashNode.getMetadataList().add(newMetadata);
  hashNode.setSubProcessStart(true);
  hashNode.setProcess(graphicalNode.getProcess());
  outgoingConnections=new ArrayList<IConnection>();
  incomingConnections=new ArrayList<IConnection>();
  hashNode.setIncomingConnections(incomingConnections);
  hashNode.setOutgoingConnections(outgoingConnections);
  hashNode.setVirtualGenerateNode(false);
  hashNode.getElementParameter("String_Node_Str").setValue(Boolean.TRUE);
  hashNode.getElementParameter("String_Node_Str").setValue(hashOutputUniqueName);
  hashNode.getElementParameter("String_Node_Str").setValue(Boolean.TRUE);
  DataConnection dataConnec=new DataConnection();
  dataConnec.setActivate(mergeOutputConnection.isActivate());
  dataConnec.setLineStyle(mergeOutputConnection.getLineStyle());
  dataConnec.setConnectorName(mergeOutputConnection.getConnectorName());
  dataConnec.setMetadataTable(newMetadata);
  dataConnec.setTraceConnection(mergeOutputConnection.isTraceConnection());
  dataConnec.setMonitorConnection(mergeOutputConnection.isMonitorConnection());
  dataConnec.setTracesCondition(mergeOutputConnection.getTracesCondition());
  dataConnec.setEnabledTraceColumns(mergeOutputConnection.getEnabledTraceColumns());
  dataConnec.setName(mergeOutputConnection.getName());
  dataConnec.setSource(hashNode);
  dataConnec.setLinkNodeForHash(((DataConnection)mergeOutputConnection).getLinkNodeForHash());
  dataConnec.setElementParameters(mergeOutputConnection.getElementParameters());
  dataConnec.setUniqueName(mergeOutputConnection.getUniqueName());
  mergeOutputConnection.setElementParameters(new ArrayList<IElementParameter>());
  dataConnec.setTarget(oldNodeTarget);
  ((DataConnection)mergeOutputConnection).setName(hashNode.getUniqueName() + "String_Node_Str" + mergeOutputConnection.getName());
  ((DataConnection)mergeOutputConnection).setUniqueName(hashNode.getUniqueName() + "String_Node_Str" + mergeOutputConnection.getName());
  int inputId=mergeOutputConnection.getInputId();
  if (inputId == 0) {
    List refOutputConnections=NodeUtil.getOutgoingConnections(mergeDataNode,EConnectionType.FLOW_REF);
    if (refOutputConnections.size() != 0) {
      IConnection refConnection=((List<IConnection>)refOutputConnections).get(0);
      inputId=refConnection.getInputId();
      mergeDataNode.getOutgoingConnections().remove(refConnection);
      ((DataConnection)refConnection).setSource(hashNode);
      ((List<IConnection>)hashNode.getOutgoingConnections()).add(refConnection);
    }
  }
  dataConnec.setInputId(inputId);
  outgoingConnections.add(dataConnec);
  if (inputId == 1) {
    ((List<IConnection>)oldNodeTarget.getIncomingConnections()).add(0,dataConnec);
  }
 else {
    ((List<IConnection>)oldNodeTarget.getIncomingConnections()).add(dataConnec);
  }
  ((DataConnection)mergeOutputConnection).setLineStyle(EConnectionType.FLOW_MAIN);
  ((DataConnection)mergeOutputConnection).setConnectorName(EConnectionType.FLOW_MAIN.getName());
  addDataNode(hashNode);
  INode afterMergeStart=hashNode.getSubProcessStartNode(false);
  INode mergeSubNodeStart=mergeDataNode.getSubProcessStartNode(false);
  boolean changeStartNode=false;
  if (mergeDataNode.getLinkedMergeInfo() == null || mergeDataNode.getLinkedMergeInfo().isEmpty()) {
    changeStartNode=true;
  }
 else {
    Map<INode,Integer> nextMergeNodes=mergeDataNode.getLinkedMergeInfo();
    if (nextMergeNodes.size() == 1) {
      INode followMergeNode=nextMergeNodes.keySet().iterator().next();
      List nextMergeOutputConnections=NodeUtil.getOutgoingConnections(followMergeNode,IConnectionCategory.DATA);
      if (nextMergeNodes.get(followMergeNode) == 1) {
        if (nextMergeOutputConnections == null || nextMergeOutputConnections.isEmpty()) {
          changeStartNode=true;
        }
      }
    }
  }
  if (changeStartNode) {
    INode oldStartNode=null;
    if (mergeDataNode.isThereLinkWithHash()) {
      oldStartNode=mergeDataNode.getSubProcessStartNode(false);
    }
 else {
      oldStartNode=mergeDataNode.getDesignSubjobStartNode();
    }
    ((AbstractNode)afterMergeStart).setStart(oldStartNode.isStart());
    ((AbstractNode)oldStartNode).setStart(false);
    for (    INode curNode : dataNodeList) {
      if (curNode instanceof AbstractNode) {
        if (curNode.getDesignSubjobStartNode().equals(oldStartNode)) {
          ((AbstractNode)curNode).setDesignSubjobStartNode(afterMergeStart);
        }
      }
    }
    List<IConnection> depConnections=(List<IConnection>)NodeUtil.getOutgoingConnections(oldStartNode,IConnectionCategory.EXECUTION_ORDER);
    oldStartNode.getOutgoingConnections().removeAll(depConnections);
    ((List<IConnection>)afterMergeStart.getOutgoingConnections()).addAll(depConnections);
    for (    IConnection curDepConnection : depConnections) {
      ((AbstractConnection)curDepConnection).setSource(afterMergeStart);
    }
    depConnections=(List<IConnection>)NodeUtil.getIncomingConnections(oldStartNode,IConnectionCategory.DEPENDENCY);
    for (    IConnection connection : connectionsToIgnoreInMerge) {
      if (depConnections.contains(connection)) {
        depConnections.remove(connection);
      }
    }
    oldStartNode.getIncomingConnections().removeAll(depConnections);
    ((List<IConnection>)afterMergeStart.getIncomingConnections()).addAll(depConnections);
    for (    IConnection curDepConnection : depConnections) {
      ((AbstractConnection)curDepConnection).setTarget(afterMergeStart);
    }
  }
  dataConnec=new DataConnection();
  dataConnec.setActivate(mergeOutputConnection.isActivate());
  dataConnec.setLineStyle(EConnectionType.RUN_AFTER);
  dataConnec.setConnectorName(EConnectionType.RUN_AFTER.getName());
  dataConnec.setTraceConnection(false);
  dataConnec.setName(hashNode.getUniqueName() + "String_Node_Str" + EConnectionType.RUN_AFTER.getDefaultLinkName());
  dataConnec.setSource(afterMergeStart);
  dataConnec.setTarget(mergeSubNodeStart);
  connectionsToIgnoreInMerge.add(dataConnec);
  ((List<IConnection>)mergeSubNodeStart.getIncomingConnections()).add(dataConnec);
  ((List<IConnection>)afterMergeStart.getOutgoingConnections()).add(dataConnec);
}