code: package gr.uom.java.jdeodorant.refactoring.manipulators;
  
  import java.util.LinkedHashSet;
  import java.util.Set;
  
  import org.eclipse.jdt.core.dom.MethodDeclaration;
  import org.eclipse.jdt.core.dom.TypeDeclaration;
  import org.eclipse.jdt.core.dom.VariableDeclaration;
  
  public class ASTSliceGroup implements Comparable<ASTSliceGroup> {
  	private Set<ASTSlice> candidates;
  	private double averageNumberOfExtractedStatementsInGroup = 0.0;
  	private double averageNumberOfDuplicatedStatementsInGroup = 0.0;
  	private double averageDuplicationRatioInGroup = 0.0;
  	private int maximumNumberOfExtractedStatementsInGroup = 0;
  
  	public ASTSliceGroup() {
  		this.candidates = new LinkedHashSet<ASTSlice>();
  	}
  
  	public void addCandidate(ASTSlice slice) {
  		Set<ASTSlice> slicesToBeRemoved = new LinkedHashSet<ASTSlice>();
  		for(ASTSlice previousSlice : candidates) {
  			if(previousSlice.getNumberOfSliceStatements() == slice.getNumberOfSliceStatements() &&
  					previousSlice.getNumberOfDuplicatedStatements() == slice.getNumberOfDuplicatedStatements()) {
  				slicesToBeRemoved.add(previousSlice);
  			}
  		}
  		this.candidates.removeAll(slicesToBeRemoved);
  		this.candidates.add(slice);
  	}
  
  	public Set<ASTSlice> getCandidates() {
  		return candidates;
  	}
  
  	public TypeDeclaration getSourceTypeDeclaration() {
  		return ((ASTSlice)candidates.toArray()[0]).getSourceTypeDeclaration();
  	}
  
  	public MethodDeclaration getSourceMethodDeclaration() {
  		return ((ASTSlice)candidates.toArray()[0]).getSourceMethodDeclaration();
  	}
  
  	public VariableDeclaration getLocalVariableCriterion() {
  		return ((ASTSlice)candidates.toArray()[0]).getLocalVariableCriterion();
  	}
  
  	public void setAverageNumberOfExtractedStatementsInGroup(double averageNumberOfExtractedStatementsInGroup) {
  		this.averageNumberOfExtractedStatementsInGroup = averageNumberOfExtractedStatementsInGroup;
  	}
  
  	public void setAverageNumberOfDuplicatedStatementsInGroup(double averageNumberOfDuplicatedStatementsInGroup) {
  		this.averageNumberOfDuplicatedStatementsInGroup = averageNumberOfDuplicatedStatementsInGroup;
  	}
  
  	public void setAverageDuplicationRatioInGroup(double averageDuplicationRatioInGroup) {
  		this.averageDuplicationRatioInGroup = averageDuplicationRatioInGroup;
  	}
  
  	public void setMaximumNumberOfExtractedStatementsInGroup(int maximumNumberOfExtractedStatementsInGroup) {
  		this.maximumNumberOfExtractedStatementsInGroup = maximumNumberOfExtractedStatementsInGroup;
  	}
  
  	public int compareTo(ASTSliceGroup other) {
  		double duplicationRatio1 = this.averageDuplicationRatioInGroup;
  		double duplicationRatio2 = other.averageDuplicationRatioInGroup;
  		
  		if(duplicationRatio1 < duplicationRatio2)
  			return -1;
  		else if(duplicationRatio1 > duplicationRatio2)
  			return 1;
  		//same duplication ratio
  		double averageNumberOfDuplicatedStatements1 = this.averageNumberOfDuplicatedStatementsInGroup;
  		double averageNumberOfDuplicatedStatements2 = other.averageNumberOfDuplicatedStatementsInGroup;
  		
  		if(averageNumberOfDuplicatedStatements1 != 0 && averageNumberOfDuplicatedStatements2 != 0) {
  			if(averageNumberOfDuplicatedStatements1 < averageNumberOfDuplicatedStatements2)
  				return -1;
  			else if(averageNumberOfDuplicatedStatements1 > averageNumberOfDuplicatedStatements2)
  				return 1;
  		}
  		
  		int maximumNumberOfExtractedStatements1 = this.maximumNumberOfExtractedStatementsInGroup;
  		int maximumNumberOfExtractedStatements2 = other.maximumNumberOfExtractedStatementsInGroup;
  		
  		if(averageNumberOfDuplicatedStatements1 == 0 && averageNumberOfDuplicatedStatements2 == 0) {
  			if(maximumNumberOfExtractedStatements1 < maximumNumberOfExtractedStatements2)
  				return 1;
  			else if(maximumNumberOfExtractedStatements1 > maximumNumberOfExtractedStatements2)
  				return -1;
  		}
  		
  		double averageNumberOfExtractedStatements1 = this.averageNumberOfExtractedStatementsInGroup;
  		double averageNumberOfExtractedStatements2 = other.averageNumberOfExtractedStatementsInGroup;
  		
  		if(averageNumberOfExtractedStatements1 < averageNumberOfExtractedStatements2)
  			return 1;
  		else if(averageNumberOfExtractedStatements1 > averageNumberOfExtractedStatements2)
  			return -1;
  		
  		String group1 = this.getSourceTypeDeclaration().resolveBinding().getQualifiedName() + "::" +
  						this.getSourceMethodDeclaration().resolveBinding().toString() + "::" +
  						this.getLocalVariableCriterion().getName().getIdentifier();
  		
  		String group2 = other.getSourceTypeDeclaration().resolveBinding().getQualifiedName() + "::" +
  						other.getSourceMethodDeclaration().resolveBinding().toString() + "::" +
  						other.getLocalVariableCriterion().getName().getIdentifier();
  		return group1.compareTo(group2);
  	}
  }
  