public int compareTo(ExamDifficultyWeight other) {
   return new CompareToBuilder()
       .append(studentSizeTotal, other.studentSizeTotal)
       .append(maximumDuration, other.maximumDuration)
       .append(exam instanceof LeadingExam, other.exam instanceof LeadingExam)
       .append(exam.getId(), other.exam.getId())
       .toComparison();
 }
 public Comparable createSorterWeight(Examination examination, Exam exam) {
   int studentSizeTotal = exam.getTopicStudentSize();
   int maximumDuration = exam.getTopicDuration();
   for (PeriodPenalty periodPenalty : examination.getPeriodPenaltyList()) {
     if (periodPenalty.getLeftTopic().equals(exam.getTopic())) {
       switch (periodPenalty.getPeriodPenaltyType()) {
         case EXAM_COINCIDENCE:
           studentSizeTotal += periodPenalty.getRightTopic().getStudentSize();
           maximumDuration =
               Math.max(maximumDuration, periodPenalty.getRightTopic().getDuration());
           break;
         case EXCLUSION:
           // Do nothing
           break;
         case AFTER:
           // Do nothing
           break;
         default:
           throw new IllegalStateException(
               "The periodPenaltyType ("
                   + periodPenalty.getPeriodPenaltyType()
                   + ") is not implemented.");
       }
     } else if (periodPenalty.getRightTopic().equals(exam.getTopic())) {
       switch (periodPenalty.getPeriodPenaltyType()) {
         case EXAM_COINCIDENCE:
           studentSizeTotal += periodPenalty.getLeftTopic().getStudentSize();
           maximumDuration = Math.max(maximumDuration, periodPenalty.getLeftTopic().getDuration());
           break;
         case EXCLUSION:
           // Do nothing
           break;
         case AFTER:
           studentSizeTotal += periodPenalty.getLeftTopic().getStudentSize();
           maximumDuration = Math.max(maximumDuration, periodPenalty.getLeftTopic().getDuration());
           break;
         default:
           throw new IllegalStateException(
               "The periodPenaltyType ("
                   + periodPenalty.getPeriodPenaltyType()
                   + ") is not implemented.");
       }
     }
   }
   return new ExamDifficultyWeight(exam, studentSizeTotal, maximumDuration);
 }
 private void createExamList() {
   List<Topic> topicList = examination.getTopicList();
   List<Exam> examList = new ArrayList<Exam>(topicList.size());
   Map<Topic, LeadingExam> leadingTopicToExamMap =
       new HashMap<Topic, LeadingExam>(topicList.size());
   for (Topic topic : topicList) {
     Exam exam;
     Topic leadingTopic = topic;
     for (Topic coincidenceTopic : coincidenceMap.get(topic)) {
       if (coincidenceTopic.getId() < leadingTopic.getId()) {
         leadingTopic = coincidenceTopic;
       }
     }
     if (leadingTopic == topic) {
       LeadingExam leadingExam = new LeadingExam();
       leadingExam.setFollowingExamList(new ArrayList<FollowingExam>(10));
       leadingTopicToExamMap.put(topic, leadingExam);
       exam = leadingExam;
     } else {
       FollowingExam followingExam = new FollowingExam();
       LeadingExam leadingExam = leadingTopicToExamMap.get(leadingTopic);
       if (leadingExam == null) {
         throw new IllegalStateException(
             "The followingExam ("
                 + topic.getId()
                 + ")'s leadingExam ("
                 + leadingExam
                 + ") cannot be null.");
       }
       followingExam.setLeadingExam(leadingExam);
       leadingExam.getFollowingExamList().add(followingExam);
       exam = followingExam;
     }
     exam.setId(topic.getId());
     exam.setTopic(topic);
     // Notice that we leave the PlanningVariable properties on null
     examList.add(exam);
   }
   examination.setExamList(examList);
 }