code: package gr.uom.java.ast.decomposition.cfg.mapping;
  
  import java.util.List;
  
  import org.eclipse.jdt.core.dom.Block;
  import org.eclipse.jdt.core.dom.IfStatement;
  import org.eclipse.jdt.core.dom.Statement;
  
  import gr.uom.java.ast.decomposition.cfg.PDGBlockNode;
  import gr.uom.java.ast.decomposition.cfg.PDGControlDependence;
  import gr.uom.java.ast.decomposition.cfg.PDGNode;
  import gr.uom.java.ast.decomposition.matching.ASTNodeDifference;
  
  public class PDGNodeGap extends IdBasedGap {
  	private PDGNode nodeG1;
  	private PDGNode nodeG2;
  	private List<ASTNodeDifference> nodeDifferences;
  	private volatile int hashCode = 0;
  	
  	public PDGNodeGap(PDGNode nodeG1, PDGNode nodeG2, boolean advancedMatch, List<ASTNodeDifference> nodeDifferences) {
  		super(nodeG1 != null ? nodeG1.getId() : 0, nodeG2 != null ? nodeG2.getId() : 0,
  				advancedMatch);
  		this.nodeG1 = nodeG1;
  		this.nodeG2 = nodeG2;
  		this.nodeDifferences = nodeDifferences;
  	}
  	
  	public PDGNode getNodeG1() {
  		return nodeG1;
  	}
  
  	public PDGNode getNodeG2() {
  		return nodeG2;
  	}
  
  	public List<ASTNodeDifference> getNodeDifferences() {
  		return nodeDifferences;
  	}
  
  	public boolean isFalseControlDependent() {
  		if(nodeG1 != null) {
  			PDGControlDependence controlDependence1 = nodeG1.getIncomingControlDependence();
  			if(controlDependence1 != null)
  				return controlDependence1.isFalseControlDependence();
  			if(nodeG1 instanceof PDGBlockNode)
  				return isNestedUnderElse((PDGBlockNode)nodeG1);
  		}
  		if(nodeG2 != null) {
  			PDGControlDependence controlDependence2 = nodeG2.getIncomingControlDependence();
  			if(controlDependence2 != null)
  				return controlDependence2.isFalseControlDependence();
  			if(nodeG2 instanceof PDGBlockNode)
  				return isNestedUnderElse((PDGBlockNode)nodeG2);
  		}
  		return false;
  	}
  
  	private boolean isNestedUnderElse(PDGBlockNode blockNode) {
  		Statement statement = blockNode.getASTStatement();
  		if(statement.getParent() instanceof Block) {
  			Block block = (Block)statement.getParent();
  			if(block.getParent() instanceof IfStatement) {
  				IfStatement ifStatement = (IfStatement)block.getParent();
  				if(ifStatement.getElseStatement() != null && ifStatement.getElseStatement().equals(block))
  					return true;
  			}
  		}
  		else if(statement.getParent() instanceof IfStatement) {
  			IfStatement ifStatement = (IfStatement)statement.getParent();
  			if(ifStatement.getElseStatement() != null && ifStatement.getElseStatement().equals(statement))
  				return true;
  		}
  		return false;
  	}
  
  	public boolean equals(Object o) {
  		if(this == o)
  			return true;
  		if(o instanceof PDGNodeGap) {
  			PDGNodeGap gap = (PDGNodeGap)o;
  			if(this.nodeG1 == null && gap.nodeG1 == null)
  				return this.nodeG2.equals(gap.nodeG2);
  			if(this.nodeG2 == null && gap.nodeG2 == null)
  				return this.nodeG1.equals(gap.nodeG1);
  		}
  		return false;
  	}
  
  	public int hashCode() {
  		if(hashCode == 0) {
  			int result = 17;
  			result = 37*result + (nodeG1 == null ? 0 : nodeG1.hashCode());
  			result = 37*result + (nodeG2 == null ? 0 : nodeG2.hashCode());
  			hashCode = result;
  		}
  		return hashCode;
  	}
  
  	public String toString() {
  		StringBuilder sb = new StringBuilder();
  		if(nodeG1 != null)
  			sb.append(nodeG1);
  		else
  			sb.append("\n");
  		if(nodeG2 != null)
  			sb.append(nodeG2);
  		else
  			sb.append("\n");
  		return sb.toString();
  	}
  
  	/*public int compareTo(PDGNodeGap other) {
  		if(this.nodeG1 != null && other.nodeG1 != null)
  			return Integer.compare(this.nodeG1.getId(), other.nodeG1.getId());
  		if(this.nodeG2 != null && other.nodeG2 != null)
  			return Integer.compare(this.nodeG2.getId(), other.nodeG2.getId());
  		
  		if(this.nodeG1 != null && other.nodeG2 != null) {
  			int id1 = this.nodeG1.getId();
  			int id2 = other.nodeG2.getId();
  			if(id1 == id2)
  				return -1;
  			else
  				return Integer.compare(id1, id2);
  		}
  		if(other.nodeG1 != null && this.nodeG2 != null) {
  			int id2 = other.nodeG1.getId();
  			int id1 = this.nodeG2.getId();
  			if(id1 == id2)
  				return -1;
  			else
  				return Integer.compare(id1, id2);
  		}
  		return 0;
  	}*/
  }
  