Program: 12095
Project: 12095
Buggy source:
private void matchBasedOnControlDependenceTreeStructure(ControlDependenceTreeNode controlDependenceTreePDG1,ControlDependenceTreeNode controlDependenceTreePDG2){
  int maxLevel1=controlDependenceTreePDG1.getMaxLevel();
  int level1=maxLevel1;
  int maxLevel2=controlDependenceTreePDG2.getMaxLevel();
  int level2=maxLevel2;
  if (monitor != null)   monitor.beginTask("String_Node_Str",Math.min(maxLevel1,maxLevel2));
  CloneStructureNode root=null;
  MappingState finalState=null;
  List<CloneStructureNode> parents=new ArrayList<CloneStructureNode>();
  while (level1 >= 0 && level2 >= 0) {
    Set<PDGNode> controlPredicateNodesG1=controlDependenceTreePDG1.getControlPredicateNodesInLevel(level1);
    Set<PDGNode> controlPredicateNodesG2=controlDependenceTreePDG2.getControlPredicateNodesInLevel(level2);
    Set<PDGNode> controlPredicateNodesInNextLevelG1=new LinkedHashSet<PDGNode>();
    Set<PDGNode> controlPredicateNodesInNextLevelG2=new LinkedHashSet<PDGNode>();
    if (level1 < maxLevel1) {
      Set<PDGNode> nodesInNextLevel=controlDependenceTreePDG1.getControlPredicateNodesInLevel(level1 + 1);
      controlPredicateNodesInNextLevelG1.addAll(nodesInNextLevel);
      for (      PDGNode node : nodesInNextLevel) {
        if (node instanceof PDGTryNode) {
          controlPredicateNodesInNextLevelG1.addAll(pdg1.getNestedNodesWithinTryNode((PDGTryNode)node));
        }
      }
    }
    if (level2 < maxLevel2) {
      Set<PDGNode> nodesInNextLevel=controlDependenceTreePDG2.getControlPredicateNodesInLevel(level2 + 1);
      controlPredicateNodesInNextLevelG2.addAll(nodesInNextLevel);
      for (      PDGNode node : nodesInNextLevel) {
        if (node instanceof PDGTryNode) {
          controlPredicateNodesInNextLevelG2.addAll(pdg2.getNestedNodesWithinTryNode((PDGTryNode)node));
        }
      }
    }
    for (    PDGNode predicate1 : controlPredicateNodesG1) {
      Set<PDGNode> nodesG1=getNodesInRegion(pdg1,predicate1,controlPredicateNodesG1,controlPredicateNodesInNextLevelG1,controlDependenceTreePDG1);
      if (level1 == 0 && !fullTreeMatch) {
        int maxId=allNodesInSubTreePDG1.last().getId();
        Set<PDGNode> nodesG1ToBeRemoved=new LinkedHashSet<PDGNode>();
        for (        PDGNode nodeG1 : nodesG1) {
          if (nodeG1.getId() > maxId) {
            nodesG1ToBeRemoved.add(nodeG1);
          }
          if (controlDependenceTreePDG1.isElseNode()) {
            double elseNodeId=controlDependenceTreePDG1.getId();
            if (nodeG1.getId() < elseNodeId) {
              nodesG1ToBeRemoved.add(nodeG1);
            }
          }
        }
        nodesG1.removeAll(nodesG1ToBeRemoved);
      }
      this.allNodesInSubTreePDG1.addAll(nodesG1);
      List<MappingState> currentStates=new ArrayList<MappingState>();
      for (      PDGNode predicate2 : controlPredicateNodesG2) {
        Set<PDGNode> nodesG2=getNodesInRegion(pdg2,predicate2,controlPredicateNodesG2,controlPredicateNodesInNextLevelG2,controlDependenceTreePDG2);
        if (level2 == 0 && !fullTreeMatch) {
          int maxId=allNodesInSubTreePDG2.last().getId();
          Set<PDGNode> nodesG2ToBeRemoved=new LinkedHashSet<PDGNode>();
          for (          PDGNode nodeG2 : nodesG2) {
            if (nodeG2.getId() > maxId) {
              nodesG2ToBeRemoved.add(nodeG2);
            }
            if (controlDependenceTreePDG2.isElseNode()) {
              double elseNodeId=controlDependenceTreePDG2.getId();
              if (nodeG2.getId() < elseNodeId) {
                nodesG2ToBeRemoved.add(nodeG2);
              }
            }
          }
          nodesG2.removeAll(nodesG2ToBeRemoved);
        }
        this.allNodesInSubTreePDG2.addAll(nodesG2);
        List<MappingState> maxStates=null;
        if (level1 == 0 || level2 == 0) {
          maxStates=matchBasedOnCodeFragments(finalState,nodesG1,nodesG2);
        }
 else {
          ControlDependenceTreeNode cdtNode1=controlDependenceTreePDG1.getNode(predicate1);
          ControlDependenceTreeNode cdtNode2=controlDependenceTreePDG2.getNode(predicate2);
          ControlDependenceTreeNode cdtNode1Parent=null;
          if (cdtNode1 != null)           cdtNode1Parent=cdtNode1.getParent();
          ControlDependenceTreeNode cdtNode2Parent=null;
          if (cdtNode2 != null)           cdtNode2Parent=cdtNode2.getParent();
          if (cdtNode1Parent != null && cdtNode2Parent != null) {
            if ((cdtNode1Parent.getNode() != null && cdtNode1Parent.getNode().getCFGNode() instanceof CFGBranchIfNode && cdtNode2Parent.isElseNode()) || (cdtNode2Parent.getNode() != null && cdtNode2Parent.getNode().getCFGNode() instanceof CFGBranchIfNode && cdtNode1Parent.isElseNode()))             continue;
          }
          maxStates=processPDGNodes(finalState,nodesG1,nodesG2);
        }
        for (        MappingState temp : maxStates) {
          if (!currentStates.contains(temp)) {
            currentStates.add(temp);
          }
        }
      }
      if (!currentStates.isEmpty()) {
        MappingState best=findMaximumStateWithMinimumDifferences(currentStates);
        List<PDGNodeMapping> nodeMappings=new ArrayList<PDGNodeMapping>(best.getNodeMappings());
        int index=0;
        for (        PDGNodeMapping mapping : nodeMappings) {
          if (mapping.getNodeG1().equals(predicate1)) {
            controlPredicateNodesG2.remove(mapping.getNodeG2());
            break;
          }
          index++;
        }
        finalState=best;
        CloneStructureNode parent=null;
        CloneStructureNode newElseParent=null;
        for (int i=index; i < nodeMappings.size(); i++) {
          PDGNodeMapping mapping=nodeMappings.get(i);
          if (parent == null) {
            parent=new CloneStructureNode(mapping);
          }
 else {
            PDGTryNode nestedUnderTry1=pdg1.isDirectlyNestedWithinTryNode(mapping.getNodeG1());
            PDGTryNode nestedUnderTry2=pdg2.isDirectlyNestedWithinTryNode(mapping.getNodeG2());
            boolean nestedUnderTry=nestedUnderTry1 != null && nestedUnderTry2 != null;
            if (mapping.isFalseControlDependent() && !nestedUnderTry) {
              if (newElseParent == null) {
                ControlDependenceTreeNode elseNodeG1=controlDependenceTreePDG1.getElseNode(parent.getMapping().getNodeG1());
                ControlDependenceTreeNode elseNodeG2=controlDependenceTreePDG2.getElseNode(parent.getMapping().getNodeG2());
                if (elseNodeG1 != null && elseNodeG2 != null) {
                  PDGElseMapping elseMapping=new PDGElseMapping(elseNodeG1.getId(),elseNodeG2.getId());
                  newElseParent=new CloneStructureNode(elseMapping);
                  parent.addChild(newElseParent);
                  CloneStructureNode child=new CloneStructureNode(mapping);
                  newElseParent.addChild(child);
                }
              }
 else {
                CloneStructureNode child=new CloneStructureNode(mapping);
                newElseParent.addChild(child);
              }
            }
 else {
              CloneStructureNode child=new CloneStructureNode(mapping);
              parent.addChild(child);
            }
          }
        }
        if (parent != null) {
          PDGNodeMapping parentNodeMapping=(PDGNodeMapping)parent.getMapping();
          double parentId1=parentNodeMapping.getId1();
          double parentId2=parentNodeMapping.getId2();
          for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
            CloneStructureNode previousParent=parentIterator.next();
            PDGNodeMapping previousParentNodeMapping=(PDGNodeMapping)previousParent.getMapping();
            double previousParentId1=previousParentNodeMapping.getId1();
            double previousParentId2=previousParentNodeMapping.getId2();
            if (controlDependenceTreePDG1.parentChildRelationship(parentId1,previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(parentId2,previousParentId2)) {
              parent.addChild(previousParent);
              parentIterator.remove();
            }
 else             if (previousParentNodeMapping.isFalseControlDependent()) {
              if (newElseParent == null) {
                ControlDependenceTreeNode elseNodeG1=controlDependenceTreePDG1.getElseNode(parentNodeMapping.getNodeG1());
                ControlDependenceTreeNode elseNodeG2=controlDependenceTreePDG2.getElseNode(parentNodeMapping.getNodeG2());
                if (elseNodeG1 != null && elseNodeG2 != null) {
                  if (controlDependenceTreePDG1.parentChildRelationship(elseNodeG1.getId(),previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(elseNodeG2.getId(),previousParentId2)) {
                    PDGElseMapping elseMapping=new PDGElseMapping(elseNodeG1.getId(),elseNodeG2.getId());
                    newElseParent=new CloneStructureNode(elseMapping);
                    parent.addChild(newElseParent);
                    newElseParent.addChild(previousParent);
                    parentIterator.remove();
                  }
                }
              }
 else {
                PDGElseMapping elseMapping=(PDGElseMapping)newElseParent.getMapping();
                if (controlDependenceTreePDG1.parentChildRelationship(elseMapping.getId1(),previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(elseMapping.getId2(),previousParentId2)) {
                  newElseParent.addChild(previousParent);
                  parentIterator.remove();
                }
              }
            }
          }
          boolean isTryBlock=(parentNodeMapping.getNodeG1() instanceof PDGTryNode) && (parentNodeMapping.getNodeG2() instanceof PDGTryNode);
          if (!parent.getChildren().isEmpty() || isTryBlock) {
            parents.add(parent);
          }
 else {
            finalState.getNodeMappings().remove(parent.getMapping());
          }
        }
 else {
          root=new CloneStructureNode(null);
          for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
            CloneStructureNode previousParent=parentIterator.next();
            root.addChild(previousParent);
            parentIterator.remove();
          }
          for (          PDGNodeMapping nodeMapping : best.getNodeMappings()) {
            if (nodesG1.contains(nodeMapping.getNodeG1())) {
              CloneStructureNode childNode=new CloneStructureNode(nodeMapping);
              root.addChild(childNode);
            }
          }
        }
      }
    }
    level1--;
    level2--;
    if (monitor != null)     monitor.worked(1);
  }
  if (monitor != null)   monitor.done();
  if (root == null) {
    root=new CloneStructureNode(null);
    for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
      CloneStructureNode previousParent=parentIterator.next();
      root.addChild(previousParent);
      parentIterator.remove();
    }
  }
  this.maximumStateWithMinimumDifferences=finalState;
  this.cloneStructureRoot=root;
}

Fixed version (ground truth):
private void matchBasedOnControlDependenceTreeStructure(ControlDependenceTreeNode controlDependenceTreePDG1,ControlDependenceTreeNode controlDependenceTreePDG2){
  int maxLevel1=controlDependenceTreePDG1.getMaxLevel();
  int level1=maxLevel1;
  int maxLevel2=controlDependenceTreePDG2.getMaxLevel();
  int level2=maxLevel2;
  if (monitor != null)   monitor.beginTask("String_Node_Str",Math.min(maxLevel1,maxLevel2));
  CloneStructureNode root=null;
  MappingState finalState=null;
  List<CloneStructureNode> parents=new ArrayList<CloneStructureNode>();
  while (level1 >= 0 && level2 >= 0) {
    Set<PDGNode> controlPredicateNodesG1=controlDependenceTreePDG1.getControlPredicateNodesInLevel(level1);
    Set<PDGNode> controlPredicateNodesG2=controlDependenceTreePDG2.getControlPredicateNodesInLevel(level2);
    Set<PDGNode> controlPredicateNodesInNextLevelG1=new LinkedHashSet<PDGNode>();
    Set<PDGNode> controlPredicateNodesInNextLevelG2=new LinkedHashSet<PDGNode>();
    if (level1 < maxLevel1) {
      Set<PDGNode> nodesInNextLevel=controlDependenceTreePDG1.getControlPredicateNodesInLevel(level1 + 1);
      controlPredicateNodesInNextLevelG1.addAll(nodesInNextLevel);
      for (      PDGNode node : nodesInNextLevel) {
        if (node instanceof PDGTryNode) {
          controlPredicateNodesInNextLevelG1.addAll(pdg1.getNestedNodesWithinTryNode((PDGTryNode)node));
        }
      }
    }
    if (level2 < maxLevel2) {
      Set<PDGNode> nodesInNextLevel=controlDependenceTreePDG2.getControlPredicateNodesInLevel(level2 + 1);
      controlPredicateNodesInNextLevelG2.addAll(nodesInNextLevel);
      for (      PDGNode node : nodesInNextLevel) {
        if (node instanceof PDGTryNode) {
          controlPredicateNodesInNextLevelG2.addAll(pdg2.getNestedNodesWithinTryNode((PDGTryNode)node));
        }
      }
    }
    for (    PDGNode predicate1 : controlPredicateNodesG1) {
      Set<PDGNode> nodesG1=getNodesInRegion(pdg1,predicate1,controlPredicateNodesG1,controlPredicateNodesInNextLevelG1,controlDependenceTreePDG1);
      if (level1 == 0 && !fullTreeMatch) {
        int maxId=allNodesInSubTreePDG1.last().getId();
        Set<PDGNode> nodesG1ToBeRemoved=new LinkedHashSet<PDGNode>();
        for (        PDGNode nodeG1 : nodesG1) {
          if (nodeG1.getId() > maxId) {
            nodesG1ToBeRemoved.add(nodeG1);
          }
          if (controlDependenceTreePDG1.isElseNode()) {
            double elseNodeId=controlDependenceTreePDG1.getId();
            if (nodeG1.getId() < elseNodeId) {
              nodesG1ToBeRemoved.add(nodeG1);
            }
          }
        }
        nodesG1.removeAll(nodesG1ToBeRemoved);
      }
      this.allNodesInSubTreePDG1.addAll(nodesG1);
      List<MappingState> currentStates=new ArrayList<MappingState>();
      for (      PDGNode predicate2 : controlPredicateNodesG2) {
        Set<PDGNode> nodesG2=getNodesInRegion(pdg2,predicate2,controlPredicateNodesG2,controlPredicateNodesInNextLevelG2,controlDependenceTreePDG2);
        if (level2 == 0 && !fullTreeMatch) {
          int maxId=allNodesInSubTreePDG2.last().getId();
          Set<PDGNode> nodesG2ToBeRemoved=new LinkedHashSet<PDGNode>();
          for (          PDGNode nodeG2 : nodesG2) {
            if (nodeG2.getId() > maxId) {
              nodesG2ToBeRemoved.add(nodeG2);
            }
            if (controlDependenceTreePDG2.isElseNode()) {
              double elseNodeId=controlDependenceTreePDG2.getId();
              if (nodeG2.getId() < elseNodeId) {
                nodesG2ToBeRemoved.add(nodeG2);
              }
            }
          }
          nodesG2.removeAll(nodesG2ToBeRemoved);
        }
        this.allNodesInSubTreePDG2.addAll(nodesG2);
        List<MappingState> maxStates=null;
        if (level1 == 0 || level2 == 0) {
          maxStates=matchBasedOnCodeFragments(finalState,nodesG1,nodesG2);
        }
 else {
          ControlDependenceTreeNode cdtNode1=controlDependenceTreePDG1.getNode(predicate1);
          ControlDependenceTreeNode cdtNode2=controlDependenceTreePDG2.getNode(predicate2);
          ControlDependenceTreeNode cdtNode1Parent=null;
          if (cdtNode1 != null)           cdtNode1Parent=cdtNode1.getParent();
          ControlDependenceTreeNode cdtNode2Parent=null;
          if (cdtNode2 != null)           cdtNode2Parent=cdtNode2.getParent();
          if (cdtNode1Parent != null && cdtNode2Parent != null && !cdtNode1Parent.equals(controlDependenceTreePDG1) && !cdtNode2Parent.equals(controlDependenceTreePDG2)) {
            if ((cdtNode1Parent.getNode() != null && cdtNode1Parent.getNode().getCFGNode() instanceof CFGBranchIfNode && cdtNode2Parent.isElseNode()) || (cdtNode2Parent.getNode() != null && cdtNode2Parent.getNode().getCFGNode() instanceof CFGBranchIfNode && cdtNode1Parent.isElseNode()))             continue;
          }
          if (predicate1.getASTStatement() instanceof SwitchStatement && predicate2.getASTStatement() instanceof SwitchStatement) {
            ASTNodeMatcher astNodeMatcher=new ASTNodeMatcher(iCompilationUnit1,iCompilationUnit2);
            boolean match=astNodeMatcher.match(predicate1,predicate2);
            if (match && astNodeMatcher.isParameterizable()) {
              PDGNodeMapping mapping=new PDGNodeMapping(predicate1,predicate2,astNodeMatcher);
              MappingState state=new MappingState(finalState,mapping);
              if (finalState != null)               finalState.addChild(state);
              Set<PDGNode> switchBodyNodes1=new LinkedHashSet<PDGNode>(nodesG1);
              switchBodyNodes1.remove(predicate1);
              Set<PDGNode> switchBodyNodes2=new LinkedHashSet<PDGNode>(nodesG2);
              switchBodyNodes1.remove(predicate2);
              maxStates=matchBasedOnSwitchCases(state,switchBodyNodes1,switchBodyNodes2);
            }
          }
 else {
            maxStates=processPDGNodes(finalState,nodesG1,nodesG2);
          }
        }
        for (        MappingState temp : maxStates) {
          if (!currentStates.contains(temp)) {
            currentStates.add(temp);
          }
        }
      }
      if (!currentStates.isEmpty()) {
        MappingState best=findMaximumStateWithMinimumDifferences(currentStates);
        List<PDGNodeMapping> nodeMappings=new ArrayList<PDGNodeMapping>(best.getNodeMappings());
        int index=0;
        for (        PDGNodeMapping mapping : nodeMappings) {
          if (mapping.getNodeG1().equals(predicate1)) {
            controlPredicateNodesG2.remove(mapping.getNodeG2());
            break;
          }
          index++;
        }
        finalState=best;
        CloneStructureNode parent=null;
        CloneStructureNode newElseParent=null;
        for (int i=index; i < nodeMappings.size(); i++) {
          PDGNodeMapping mapping=nodeMappings.get(i);
          if (parent == null) {
            parent=new CloneStructureNode(mapping);
          }
 else {
            PDGTryNode nestedUnderTry1=pdg1.isDirectlyNestedWithinTryNode(mapping.getNodeG1());
            PDGTryNode nestedUnderTry2=pdg2.isDirectlyNestedWithinTryNode(mapping.getNodeG2());
            boolean nestedUnderTry=nestedUnderTry1 != null && nestedUnderTry2 != null;
            if (mapping.isFalseControlDependent() && !nestedUnderTry) {
              if (newElseParent == null) {
                ControlDependenceTreeNode elseNodeG1=controlDependenceTreePDG1.getElseNode(parent.getMapping().getNodeG1());
                ControlDependenceTreeNode elseNodeG2=controlDependenceTreePDG2.getElseNode(parent.getMapping().getNodeG2());
                if (elseNodeG1 != null && elseNodeG2 != null) {
                  PDGElseMapping elseMapping=new PDGElseMapping(elseNodeG1.getId(),elseNodeG2.getId());
                  newElseParent=new CloneStructureNode(elseMapping);
                  parent.addChild(newElseParent);
                  CloneStructureNode child=new CloneStructureNode(mapping);
                  newElseParent.addChild(child);
                }
              }
 else {
                CloneStructureNode child=new CloneStructureNode(mapping);
                newElseParent.addChild(child);
              }
            }
 else {
              CloneStructureNode child=new CloneStructureNode(mapping);
              parent.addChild(child);
            }
          }
        }
        if (parent != null) {
          PDGNodeMapping parentNodeMapping=(PDGNodeMapping)parent.getMapping();
          double parentId1=parentNodeMapping.getId1();
          double parentId2=parentNodeMapping.getId2();
          for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
            CloneStructureNode previousParent=parentIterator.next();
            PDGNodeMapping previousParentNodeMapping=(PDGNodeMapping)previousParent.getMapping();
            double previousParentId1=previousParentNodeMapping.getId1();
            double previousParentId2=previousParentNodeMapping.getId2();
            if (controlDependenceTreePDG1.parentChildRelationship(parentId1,previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(parentId2,previousParentId2)) {
              parent.addChild(previousParent);
              parentIterator.remove();
            }
 else             if (previousParentNodeMapping.isFalseControlDependent()) {
              if (newElseParent == null) {
                ControlDependenceTreeNode elseNodeG1=controlDependenceTreePDG1.getElseNode(parentNodeMapping.getNodeG1());
                ControlDependenceTreeNode elseNodeG2=controlDependenceTreePDG2.getElseNode(parentNodeMapping.getNodeG2());
                if (elseNodeG1 != null && elseNodeG2 != null) {
                  if (controlDependenceTreePDG1.parentChildRelationship(elseNodeG1.getId(),previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(elseNodeG2.getId(),previousParentId2)) {
                    PDGElseMapping elseMapping=new PDGElseMapping(elseNodeG1.getId(),elseNodeG2.getId());
                    newElseParent=new CloneStructureNode(elseMapping);
                    parent.addChild(newElseParent);
                    newElseParent.addChild(previousParent);
                    parentIterator.remove();
                  }
                }
              }
 else {
                PDGElseMapping elseMapping=(PDGElseMapping)newElseParent.getMapping();
                if (controlDependenceTreePDG1.parentChildRelationship(elseMapping.getId1(),previousParentId1) && controlDependenceTreePDG2.parentChildRelationship(elseMapping.getId2(),previousParentId2)) {
                  newElseParent.addChild(previousParent);
                  parentIterator.remove();
                }
              }
            }
          }
          boolean isTryBlock=(parentNodeMapping.getNodeG1() instanceof PDGTryNode) && (parentNodeMapping.getNodeG2() instanceof PDGTryNode);
          if (!parent.getChildren().isEmpty() || isTryBlock) {
            parents.add(parent);
          }
 else {
            finalState.getNodeMappings().remove(parent.getMapping());
          }
        }
 else {
          root=new CloneStructureNode(null);
          for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
            CloneStructureNode previousParent=parentIterator.next();
            root.addChild(previousParent);
            parentIterator.remove();
          }
          for (          PDGNodeMapping nodeMapping : best.getNodeMappings()) {
            if (nodesG1.contains(nodeMapping.getNodeG1())) {
              CloneStructureNode childNode=new CloneStructureNode(nodeMapping);
              root.addChild(childNode);
            }
          }
        }
      }
    }
    level1--;
    level2--;
    if (monitor != null)     monitor.worked(1);
  }
  if (monitor != null)   monitor.done();
  if (root == null) {
    root=new CloneStructureNode(null);
    for (ListIterator<CloneStructureNode> parentIterator=parents.listIterator(); parentIterator.hasNext(); ) {
      CloneStructureNode previousParent=parentIterator.next();
      root.addChild(previousParent);
      parentIterator.remove();
    }
  }
  this.maximumStateWithMinimumDifferences=finalState;
  this.cloneStructureRoot=root;
}