code: package gr.uom.java.distance;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.LinkedHashSet;
  import java.util.Set;
  import java.util.TreeSet;
  
  public class ExtractClassCandidateGroup implements Comparable<ExtractClassCandidateGroup> {
  
  	private String source;
  	private ArrayList<ExtractClassCandidateRefactoring> candidates;
  	private ArrayList<ExtractedConcept> extractedConcepts;
  
  	public ExtractClassCandidateGroup(String source) {
  		this.source = source;
  		this.candidates = new ArrayList<ExtractClassCandidateRefactoring>();
  		this.extractedConcepts = new ArrayList<ExtractedConcept>();
  	}
  
  	public ArrayList<ExtractedConcept> getExtractedConcepts() {
  		return extractedConcepts;
  	}
  
  	public String getSource() {
  		return source;
  	}
  
  	public void addCandidate(ExtractClassCandidateRefactoring candidate) {
  		this.candidates.add(candidate);
  	}
  
  	public ArrayList<ExtractClassCandidateRefactoring> getCandidates() {
  		Collections.sort(candidates);
  		return candidates;
  	}
  
  	public void groupConcepts() {
  		ArrayList<ExtractClassCandidateRefactoring> tempCandidates = new ArrayList<ExtractClassCandidateRefactoring>(candidates);
  		Collections.sort(tempCandidates, new ClusterSizeComparator());
  		while (!tempCandidates.isEmpty()) {
  			Set<Entity> conceptEntities = new HashSet<Entity>(tempCandidates.get(0).getExtractedEntities());
  			Set<Integer> indexSet = new LinkedHashSet<Integer>();
  			indexSet.add(0);
  			int previousSize = 0;
  			do {
  				previousSize = conceptEntities.size();
  				for (int i = 1; i < tempCandidates.size(); i++) {
  					HashSet<Entity> copiedConceptEntities = new HashSet<Entity>(conceptEntities);
  					copiedConceptEntities.retainAll(tempCandidates.get(i).getExtractedEntities());
  					if (!copiedConceptEntities.isEmpty()) {
  						conceptEntities.addAll(tempCandidates.get(i).getExtractedEntities());
  						indexSet.add(i);
  					}
  				}
  			} while (previousSize < conceptEntities.size());
  			Set<ExtractClassCandidateRefactoring> candidatesToBeRemoved = new HashSet<ExtractClassCandidateRefactoring>();
  			ExtractedConcept newConcept = new ExtractedConcept(conceptEntities, source);
  			for (Integer j : indexSet) {
  				newConcept.addConceptCluster(tempCandidates.get(j));
  				candidatesToBeRemoved.add(tempCandidates.get(j));
  			}
  			tempCandidates.removeAll(candidatesToBeRemoved);
  			extractedConcepts.add(newConcept);
  		}
  		findConceptTerms();
  	}
  
  	private void findConceptTerms() {
  		for (ExtractedConcept concept : extractedConcepts) {
  			concept.findTopics();
  			for (ExtractClassCandidateRefactoring conceptCluster : concept.getConceptClusters()) {
  				conceptCluster.findTopics();
  			}
  		}
  	}
  
  	public int compareTo(ExtractClassCandidateGroup other) {
  		TreeSet<ExtractClassCandidateRefactoring> thisSet = new TreeSet<ExtractClassCandidateRefactoring>(this.candidates);
  		TreeSet<ExtractClassCandidateRefactoring> otherSet = new TreeSet<ExtractClassCandidateRefactoring>(other.candidates);
  		ExtractClassCandidateRefactoring thisFirst = thisSet.first();
  		ExtractClassCandidateRefactoring otherFirst = otherSet.first();
  		int comparison = thisFirst.compareTo(otherFirst);
  		if(comparison != 0) {
  			return comparison;
  		}
  		else {
  			return this.source.compareTo(other.source);
  		}
  	}
  }
  