public static PhdCandidacyProcessState createStateWithInferredStateDate(
      final PhdProgramCandidacyProcess process,
      final PhdProgramCandidacyProcessState type,
      final Person person,
      final String remarks) {

    DateTime stateDate = null;

    PhdCandidacyProcessState mostRecentState = process.getMostRecentState();

    switch (type) {
      case PRE_CANDIDATE:
      case STAND_BY_WITH_MISSING_INFORMATION:
      case STAND_BY_WITH_COMPLETE_INFORMATION:
      case PENDING_FOR_COORDINATOR_OPINION:
      case WAITING_FOR_SCIENTIFIC_COUNCIL_RATIFICATION:
        if (mostRecentState != null) {
          stateDate = mostRecentState.getStateDate().plusMinutes(1);
        } else {
          if (process.getCandidacyDate() == null) {
            throw new PhdDomainOperationException(
                "error.phd.PhdCandidacyProcessState.candidacyDate.required");
          }

          stateDate = process.getCandidacyDate().toDateTimeAtStartOfDay();
        }

        break;
      case RATIFIED_BY_SCIENTIFIC_COUNCIL:
        if (process.getWhenRatified() == null) {
          throw new PhdDomainOperationException(
              "error.phd.PhdCandidacyProcessState.whenRatified.required");
        }

        stateDate = process.getWhenRatified().toDateTimeAtStartOfDay();
        break;
      case CONCLUDED:
        if (process.getWhenStartedStudies() == null) {
          throw new PhdDomainOperationException(
              "error.phd.PhdCandidacyProcessState.whenStartedStudies.required");
        }

        stateDate = process.getWhenStartedStudies().toDateTimeAtStartOfDay();
        break;
      case REJECTED:
        stateDate = mostRecentState.getStateDate().plusMinutes(1);
        break;
      default:
        throw new DomainException("I cant handle this");
    }

    return createStateWithGivenStateDate(process, type, person, remarks, stateDate);
  }
  @Override
  protected void fillReport() {

    final PhdProgramCandidacyProcess candidacyProcess = getNotification().getCandidacyProcess();
    final Person person = candidacyProcess.getPerson();
    final PhdIndividualProgramProcess individualProgramProcess =
        candidacyProcess.getIndividualProgramProcess();

    addParameter(
        "administrativeOfficeCoordinator",
        individualProgramProcess
            .getPhdProgram()
            .getAdministrativeOffice()
            .getUnit()
            .getActiveUnitCoordinator()
            .getFirstAndLastName());

    addParameter("name", person.getName());
    addParameter("address", person.getAddress());
    addParameter("areaCode", person.getAreaCode());
    addParameter("areaOfAreaCode", person.getAreaOfAreaCode());
    addParameter(
        "programName",
        individualProgramProcess.getPhdProgram().getName().getContent(getLanguage()));

    addParameter("processNumber", individualProgramProcess.getProcessNumber());

    final LocalDate whenRatified = candidacyProcess.getWhenRatified();

    addParameter(
        "ratificationDate", whenRatified != null ? whenRatified.toString(getDateFormat()) : "");

    addParameter("insuranceFee", getInsuranceFee(individualProgramProcess));
    addParameter("registrationFee", getRegistrationFee(individualProgramProcess, whenRatified));

    addParameter("date", new LocalDate().toString(getDateFormat()));
    addParameter("notificationNumber", getNotification().getNotificationNumber());

    addGuidingsParameter(individualProgramProcess);
  }