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);
  }