/**
   * Ranked students
   *
   * @param subject
   * @return
   */
  public Map getRankedStudents(String subject) {
    log(3, "Obtaining students interested in subject and sorting based on priority.");
    Vector students = (Vector) demandMap.get(subject);
    Map returnMap = new Hashtable();

    Map priorityMap = new Hashtable();

    for (Iterator ite1 = students.iterator(); ite1.hasNext(); ) {
      WriteIn wri = (WriteIn) ite1.next();
      Float priority = new Float(wri.getPriority());
      List samePriorityList = (List) priorityMap.get(priority);
      if (samePriorityList == null) samePriorityList = new Vector();
      samePriorityList.add(wri);
      priorityMap.put(priority, samePriorityList);
    }

    // TODO: sort the students on the same rank based on the number of
    // options available
    //

    for (Iterator ite2 = priorityMap.keySet().iterator(); ite2.hasNext(); ) { // for each rank
      Map sameRankMap = new Hashtable();
      Float studentRank = (Float) ite2.next();
      // logger.info(rank);
      List sameRankedStudents = (List) priorityMap.get(studentRank);

      for (Iterator ite3 = sameRankedStudents.iterator();
          ite3.hasNext(); ) { // for each student on the same rank
        WriteIn studentWI = (WriteIn) ite3.next();
        // Get the schedule of the student
        Schedule sked = (Schedule) schedules.get(studentWI.getStudentNumber());

        // Get the lec sections for the subject
        List lectures = offering.getLecSections(subject);

        // Get the lecture sections to count the number of options
        float numOptions = 0;
        float totalNumOptions = 0;
        Classlist cl;
        String clkey;

        for (Iterator ite4 = lectures.iterator(); ite4.hasNext(); ) {
          totalNumOptions++;
          Section lecture = (Section) ite4.next();
          // Passed constraints
          if (sked.passed(lecture)) {
            // Count as option only if section is not full
            clkey = lecture.getSubject().getName() + ":" + lecture.getSectionName();
            cl = (Classlist) classlists.get(clkey);
            if (cl == null) {
              cl = new Classlist(lecture, null);
            }

            // Get the lab if any
            List labs = offering.getLabSections(subject, lecture.getSectionName());
            if (labs.size() > 0) {
              totalNumOptions++;
              for (Iterator ite5 = labs.iterator(); ite5.hasNext(); ) {
                Section lab = (Section) ite5.next();
                if (sked.passed(lab)) {
                  // Create a classlist of the section if it
                  // does not exist yet
                  clkey = lab.getSubject().getName() + ":" + lab.getSectionName();
                  cl = (Classlist) classlists.get(clkey);
                  if (cl == null) {
                    cl = new Classlist(lecture, lab);
                  }
                  classlists.put(clkey, cl);
                  if (!cl.full()) {
                    numOptions++;
                  }
                }
              }
            } else {
              classlists.put(clkey, cl);
              if (!cl.full()) {
                numOptions++;
              }
            }
          }
        }

        float currentLoad = sked.getUnitsObtained();
        float allowed = studentWI.getUnitsAllowed();
        float percentageLoad = currentLoad / allowed;

        float percentageNumOptions = numOptions / totalNumOptions;

        ISubject subji = studentWI.getSubjectInfo(subject);
        float subjectPriority =
            (studentWI.getSubjectPriority(subji) - 1) / studentWI.getSubjects().size();

        Float key =
            new Float(
                percentageNumOptions * 0.0 + percentageLoad * 0.0 + (1 - subjectPriority) * 1.0);

        // key is based on the priority of the subject in the writein

        List tmpL = (List) sameRankMap.get(key);
        if (tmpL == null) {
          tmpL = new Vector();
        }
        studentWI.setOptionCount(numOptions);
        tmpL.add(studentWI);
        sameRankMap.put(key, tmpL);
      }

      returnMap.put(studentRank, sameRankMap);
    }

    return returnMap;
  }