@ConditionalOnMissingBean(name = "grantingTicketExpirationPolicy")
  @Bean
  public ExpirationPolicy grantingTicketExpirationPolicy() {
    final TicketGrantingTicketProperties tgt = casProperties.getTicket().getTgt();
    if (tgt.getRememberMe().isEnabled()) {
      final RememberMeDelegatingExpirationPolicy p = new RememberMeDelegatingExpirationPolicy();
      p.setRememberMeExpirationPolicy(
          new HardTimeoutExpirationPolicy(tgt.getRememberMe().getTimeToKillInSeconds()));
      p.setSessionExpirationPolicy(buildTicketGrantingTicketExpirationPolicy());
      return p;
    }

    return buildTicketGrantingTicketExpirationPolicy();
  }
  private ExpirationPolicy buildTicketGrantingTicketExpirationPolicy() {
    final TicketGrantingTicketProperties tgt = casProperties.getTicket().getTgt();
    if (tgt.getMaxTimeToLiveInSeconds() < 0 && tgt.getTimeToKillInSeconds() < 0) {
      LOGGER.warn("Ticket-granting ticket expiration policy is set to NEVER expire tickets.");
      return new NeverExpiresExpirationPolicy();
    }

    if (tgt.getTimeout().getMaxTimeToLiveInSeconds() > 0) {
      LOGGER.debug("Ticket-granting ticket expiration policy is based on a timeout");
      return new TimeoutExpirationPolicy(tgt.getTimeout().getMaxTimeToLiveInSeconds());
    }

    if (tgt.getMaxTimeToLiveInSeconds() > 0 && tgt.getTimeToKillInSeconds() > 0) {
      LOGGER.debug("Ticket-granting ticket expiration policy is based on hard/idle timeouts");
      return new TicketGrantingTicketExpirationPolicy(
          tgt.getMaxTimeToLiveInSeconds(), tgt.getTimeToKillInSeconds());
    }

    if (tgt.getThrottledTimeout().getTimeInBetweenUsesInSeconds() > 0
        && tgt.getThrottledTimeout().getTimeToKillInSeconds() > 0) {
      final ThrottledUseAndTimeoutExpirationPolicy p = new ThrottledUseAndTimeoutExpirationPolicy();
      p.setTimeToKillInSeconds(tgt.getThrottledTimeout().getTimeToKillInSeconds());
      p.setTimeInBetweenUsesInSeconds(tgt.getThrottledTimeout().getTimeInBetweenUsesInSeconds());
      LOGGER.debug("Ticket-granting ticket expiration policy is based on a throttled timeouts");
      return p;
    }

    if (tgt.getHardTimeout().getTimeToKillInSeconds() > 0) {
      LOGGER.debug("Ticket-granting ticket expiration policy is based on a hard timeout");
      return new HardTimeoutExpirationPolicy(tgt.getHardTimeout().getTimeToKillInSeconds());
    }

    LOGGER.warn("Ticket-granting ticket expiration policy is set to ALWAYS expire tickets.");
    return new AlwaysExpiresExpirationPolicy();
  }