private Map<CurricularYear, Inar> generateInarByCurricularYear(YearViewBean bean) {
    Map<CurricularYear, Inar> result =
        new TreeMap<CurricularYear, Inar>(
            new Comparator() {
              @Override
              public int compare(Object year1, Object year2) {
                return ((CurricularYear) year1)
                    .getYear()
                    .compareTo(((CurricularYear) year2).getYear());
              }
            });
    int years = bean.getDegreeCurricularPlan().getDegree().getDegreeType().getYears();
    for (int i = 1; i <= years; i++) {
      Inar inar = new Inar();
      result.put(CurricularYear.readByYear(i), inar);
    }

    for (Enrolment enrol : bean.getEnrolments()) {
      CurricularYear year = CurricularYear.readByYear(enrol.getRegistration().getCurricularYear());
      result.get(year).incEnrolled();
      Grade grade = enrol.getGrade();
      if (grade == null || grade.isEmpty()) {
        result.get(year).incFrequenting();
      } else if (grade.isApproved()) {
        result.get(year).incApproved();
      } else if (grade.isNotEvaluated()) {
        result.get(year).incNotEvaluated();
      } else if (grade.isNotApproved()) {
        result.get(year).incFlunked();
      }
    }

    return result;
  }
  private Map<BranchCourseGroup, Inar> generateInarByBranch(YearViewBean bean, BranchType bType) {
    Map<BranchCourseGroup, Inar> result =
        new TreeMap<BranchCourseGroup, Inar>(BranchCourseGroup.COMPARATOR_BY_NAME);
    Set<BranchCourseGroup> branches = bean.getDegreeCurricularPlan().getBranchesByType(bType);

    for (BranchCourseGroup branch : branches) {
      Inar inar = new Inar();
      result.put(branch, inar);
    }

    for (Enrolment enrol : bean.getEnrolments()) {
      BranchCourseGroup branch =
          enrol.getParentBranchCurriculumGroup() != null
              ? enrol.getParentBranchCurriculumGroup().getDegreeModule()
              : null;
      if (branch != null && branch.getBranchType() == bType) {
        result.get(branch).incEnrolled();
        Grade grade = enrol.getGrade();
        if (grade == null || grade.isEmpty()) {
          result.get(branch).incFrequenting();
        } else if (grade.isApproved()) {
          result.get(branch).incApproved();
        } else if (grade.isNotEvaluated()) {
          result.get(branch).incNotEvaluated();
        } else if (grade.isNotApproved()) {
          result.get(branch).incFlunked();
        }
      }
    }

    return result;
  }
  @Override
  public Double calculateStudentWeightedAverage(StudentCurricularPlan studentCurricularPlan) {
    float marks = 0;
    float numberOfWeigths = 0;

    for (Enrolment enrolment : studentCurricularPlan.getEnrolmentsSet()) {

      if (enrolment.isEnrolmentStateApproved()
          && !enrolment
              .getCurricularCourse()
              .getType()
              .equals(CurricularCourseType.P_TYPE_COURSE)) {
        if (!enrolment.isExtraCurricular()) {
          final Grade grade = enrolment.getGrade();
          if (grade.isNumeric()) {
            int enrolmentMark = Integer.valueOf(grade.getValue());
            double enrolmentWeight = enrolment.getCurricularCourse().getCredits();

            if (enrolmentMark > 0) {
              marks += (enrolmentMark * enrolmentWeight);
              numberOfWeigths += enrolmentWeight;
            }
          } else {
            // This mark will not count for the average
          }
        }
      }
    }

    if (marks == 0) {
      return new Double(0);
    }

    return NumberUtils.formatNumber(new Double(marks / numberOfWeigths), 1);
  }
  private Map<BranchCourseGroup, String> generateAverageByBranch(
      YearViewBean bean, BranchType bType) {
    Map<BranchCourseGroup, String> result =
        new TreeMap<BranchCourseGroup, String>(BranchCourseGroup.COMPARATOR_BY_NAME);

    Set<BranchCourseGroup> branches = bean.getDegreeCurricularPlan().getBranchesByType(bType);

    Map<BranchCourseGroup, BigDecimal> sigma = new HashMap<BranchCourseGroup, BigDecimal>();
    Map<BranchCourseGroup, BigDecimal> cardinality = new HashMap<BranchCourseGroup, BigDecimal>();
    Map<BranchCourseGroup, BigDecimal> average = new HashMap<BranchCourseGroup, BigDecimal>();

    for (BranchCourseGroup branch : branches) {
      sigma.put(branch, new BigDecimal(0));
      cardinality.put(branch, new BigDecimal(0));
      average.put(branch, new BigDecimal(0));
    }

    for (Enrolment enrol : bean.getEnrolments()) {
      BranchCourseGroup branch =
          enrol.getParentBranchCurriculumGroup() != null
              ? enrol.getParentBranchCurriculumGroup().getDegreeModule()
              : null;
      if (branch == null || branch.getBranchType() != bType) {
        continue;
      }

      Grade grade = enrol.getGrade();
      if (grade.isApproved() && grade.getGradeScale() == GradeScale.TYPE20) {
        BigDecimal biggy = sigma.get(branch);
        BigDecimal smalls = biggy.add(grade.getNumericValue());
        sigma.put(branch, smalls);

        BigDecimal notorious = cardinality.get(branch);
        BigDecimal big = notorious.add(BigDecimal.ONE);
        cardinality.put(branch, big);
      }
    }

    for (BranchCourseGroup branch : branches) {
      if (cardinality.get(branch).compareTo(BigDecimal.ZERO) == 0) {
        result.put(branch, "-");
      } else {
        result.put(
            branch,
            (sigma.get(branch))
                .divide(cardinality.get(branch), 2, RoundingMode.HALF_EVEN)
                .toPlainString());
      }
    }

    return result;
  }
  private Map<CurricularYear, String> generateAverageByCurricularYear(YearViewBean bean) {
    Map<CurricularYear, String> result =
        new TreeMap<CurricularYear, String>(
            new Comparator() {
              @Override
              public int compare(Object year1, Object year2) {
                return ((CurricularYear) year1)
                    .getYear()
                    .compareTo(((CurricularYear) year2).getYear());
              }
            });

    int years = bean.getDegreeCurricularPlan().getDegree().getDegreeType().getYears();

    BigDecimal[] sigma = new BigDecimal[years + 1];
    BigDecimal[] cardinality = new BigDecimal[years + 1];
    BigDecimal[] average = new BigDecimal[years + 1];

    for (int i = 1; i <= years; i++) {
      sigma[i] = new BigDecimal(0);
      cardinality[i] = new BigDecimal(0);
      average[i] = new BigDecimal(0);
    }

    for (Enrolment enrol : bean.getEnrolments()) {
      CurricularYear year = CurricularYear.readByYear(enrol.getRegistration().getCurricularYear());
      Grade grade = enrol.getGrade();
      if (grade.isApproved() && grade.getGradeScale() == GradeScale.TYPE20) {
        BigDecimal biggy = sigma[year.getYear()];
        BigDecimal smalls = biggy.add(grade.getNumericValue());
        sigma[year.getYear()] = smalls;

        BigDecimal notorious = cardinality[year.getYear()];
        BigDecimal big = notorious.add(BigDecimal.ONE);
        cardinality[year.getYear()] = big;
      }
    }

    for (int i = 1; i <= years; i++) {
      if (cardinality[i].compareTo(BigDecimal.ZERO) == 0) {
        result.put(CurricularYear.readByYear(i), "-");
      } else {
        result.put(
            CurricularYear.readByYear(i),
            sigma[i].divide(cardinality[i], 2, RoundingMode.HALF_EVEN).toPlainString());
      }
    }

    return result;
  }
  private Inar generateINAR(YearViewBean bean) {
    Inar inar = new Inar();

    for (Enrolment enrol : bean.getEnrolments()) {
      inar.incEnrolled();
      Grade grade = enrol.getGrade();
      if (grade == null || grade.isEmpty()) {
        inar.incFrequenting();
      } else if (grade.isApproved()) {
        inar.incApproved();
      } else if (grade.isNotEvaluated()) {
        inar.incNotEvaluated();
      } else if (grade.isNotApproved()) {
        inar.incFlunked();
      }
    }

    return inar;
  }
 @Override
 public Grade getGrade() {
   return Grade.createEmptyGrade();
 }
  @Override
  public void renderReport(final Spreadsheet spreadsheet) throws Exception {
    spreadsheet.setHeader("Número");
    spreadsheet.setHeader("Sexo");
    spreadsheet.setHeader("Média");
    spreadsheet.setHeader("Média Anual");
    spreadsheet.setHeader("Número Inscrições");
    spreadsheet.setHeader("Número Aprovações");
    spreadsheet.setHeader("Nota de Seriação");
    spreadsheet.setHeader("Local de Origem");

    final ExecutionYear executionYear = getExecutionYear();
    for (final Degree degree : Degree.readNotEmptyDegrees()) {
      if (checkDegreeType(getDegreeType(), degree)) {
        if (isActive(degree)) {
          for (final Registration registration : degree.getRegistrationsSet()) {
            if (registration.isRegistered(getExecutionYear())) {

              int enrolmentCounter = 0;
              int aprovalCounter = 0;
              BigDecimal bigDecimal = null;
              double totalCredits = 0;

              for (final Registration otherRegistration :
                  registration.getStudent().getRegistrationsSet()) {
                if (otherRegistration.getDegree() == registration.getDegree()) {
                  for (final StudentCurricularPlan studentCurricularPlan :
                      otherRegistration.getStudentCurricularPlansSet()) {
                    for (final Enrolment enrolment : studentCurricularPlan.getEnrolmentsSet()) {
                      final ExecutionSemester executionSemester = enrolment.getExecutionPeriod();
                      if (executionSemester.getExecutionYear() == executionYear) {
                        enrolmentCounter++;
                        if (enrolment.isApproved()) {
                          aprovalCounter++;
                          final Grade grade = enrolment.getGrade();
                          if (grade.isNumeric()) {
                            final double credits =
                                enrolment.getEctsCreditsForCurriculum().doubleValue();
                            totalCredits += credits;
                            bigDecimal =
                                bigDecimal == null
                                    ? grade.getNumericValue().multiply(new BigDecimal(credits))
                                    : bigDecimal.add(
                                        grade.getNumericValue().multiply(new BigDecimal(credits)));
                          }
                        }
                      }
                    }
                  }
                }
              }

              final Row row = spreadsheet.addRow();
              row.setCell(registration.getNumber().toString());
              row.setCell(registration.getPerson().getGender().toLocalizedString());
              row.setCell(registration.getAverage(executionYear));
              if (bigDecimal == null) {
                row.setCell("");
              } else {
                row.setCell(
                    bigDecimal.divide(new BigDecimal(totalCredits), 5, RoundingMode.HALF_UP));
              }
              row.setCell(Integer.toString(enrolmentCounter));
              row.setCell(Integer.toString(aprovalCounter));
              row.setCell(
                  registration.getEntryGrade() != null
                      ? registration.getEntryGrade().toString()
                      : StringUtils.EMPTY);
              Boolean dislocated = null;
              if (registration.hasStudentCandidacy()) {
                dislocated =
                    registration.getStudentCandidacy().getDislocatedFromPermanentResidence();
              }

              final String dislocatedString =
                  dislocated == null
                      ? ""
                      : (dislocated.booleanValue() ? "Deslocado" : "Não Deslocado");
              row.setCell(dislocatedString);
            }
          }
        }
      }
    }
  }