code: package gr.uom.java.ast.decomposition.cfg.mapping;
  
  import gr.uom.java.ast.decomposition.AbstractMethodFragment;
  
  import java.util.ArrayList;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Set;
  import java.util.TreeSet;
  
  public class CompleteSubTreeMatch {
  	private TreeSet<ControlDependenceTreeNodeMatchPair> matchPairs;
  
  	public CompleteSubTreeMatch(TreeSet<ControlDependenceTreeNodeMatchPair> matchPairs) {
  		this.matchPairs = matchPairs;
  	}
  
  	public TreeSet<ControlDependenceTreeNodeMatchPair> getMatchPairs() {
  		return matchPairs;
  	}
  
  	public List<AbstractMethodFragment> getAdditionalFragments1() {
  		List<AbstractMethodFragment> additionalFragments = new ArrayList<AbstractMethodFragment>();
  		for(ControlDependenceTreeNodeMatchPair pair : matchPairs) {
  			additionalFragments.addAll(pair.getAdditionalFragments1());
  		}
  		return additionalFragments;
  	}
  
  	public List<AbstractMethodFragment> getAdditionalFragments2() {
  		List<AbstractMethodFragment> additionalFragments = new ArrayList<AbstractMethodFragment>();
  		for(ControlDependenceTreeNodeMatchPair pair : matchPairs) {
  			additionalFragments.addAll(pair.getAdditionalFragments2());
  		}
  		return additionalFragments;
  	}
  
  	public boolean isAdvancedMatch() {
  		return !getAdditionalFragments1().isEmpty() || !getAdditionalFragments2().isEmpty();
  	}
  
  	public List<ControlDependenceTreeNode> getControlDependenceTreeNodes1() {
  		List<ControlDependenceTreeNode> nodes1 = new ArrayList<ControlDependenceTreeNode>();
  		for(ControlDependenceTreeNodeMatchPair matchPair : this.matchPairs) {
  			nodes1.add(matchPair.getNode1());
  		}
  		return nodes1;
  	}
  
  	public List<ControlDependenceTreeNode> getControlDependenceTreeNodes2() {
  		List<ControlDependenceTreeNode> nodes2 = new ArrayList<ControlDependenceTreeNode>();
  		for(ControlDependenceTreeNodeMatchPair matchPair : this.matchPairs) {
  			nodes2.add(matchPair.getNode2());
  		}
  		return nodes2;
  	}
  
  	public void addStartPoint(ControlDependenceTreeNodeMatchPair pair) {
  		this.matchPairs.add(pair);
  	}
  
  	public boolean subsumes(CompleteSubTreeMatch subTree) {
  		//return this.matchPairs.containsAll(subTree.matchPairs);
  		Set<ControlDependenceTreeNode> thisNodes1 = new LinkedHashSet<ControlDependenceTreeNode>();
  		Set<ControlDependenceTreeNode> thisNodes2 = new LinkedHashSet<ControlDependenceTreeNode>();
  		for(ControlDependenceTreeNodeMatchPair matchPair : this.matchPairs) {
  			thisNodes1.add(matchPair.getNode1());
  			thisNodes2.add(matchPair.getNode2());
  		}
  		Set<ControlDependenceTreeNode> otherNodes1 = new LinkedHashSet<ControlDependenceTreeNode>();
  		Set<ControlDependenceTreeNode> otherNodes2 = new LinkedHashSet<ControlDependenceTreeNode>();
  		for(ControlDependenceTreeNodeMatchPair matchPair : subTree.matchPairs) {
  			otherNodes1.add(matchPair.getNode1());
  			otherNodes2.add(matchPair.getNode2());
  		}
  		if(thisNodes1.containsAll(otherNodes1) && thisNodes2.containsAll(otherNodes2))
  			return true;
  		return false;
  	}
  
  	public String toString() {
  		return matchPairs.toString();
  	}
  }
  