@Override
    public boolean isExpired(final TicketGrantingTicketAwareTicket ticketState) {
        if (ticketState == null) {
            LOGGER.debug("Ticket state is null for [{}]. Ticket has expired.", getClass().getSimpleName());
            return true;
        }
        val countUses = ticketState.getCountOfUses();
        if (countUses >= numberOfUses) {
            LOGGER.debug("Ticket usage count [{}] is greater than or equal to [{}]. Ticket [{}] has expired",
                countUses, numberOfUses, ticketState.getId());
            return true;
        }
        val systemTime = ZonedDateTime.now(getClock());
        val creationTime = ticketState.getCreationTime();
        val expiringTime = creationTime.plusSeconds(this.timeToKillInSeconds);
        if (expiringTime.isBefore(systemTime)) {
            LOGGER.debug("Ticket [{}] has expired; difference between current time [{}] and ticket creation time [{}] is greater than or equal to [{}].",
                ticketState.getId(), systemTime, creationTime, this.timeToKillInSeconds);
            return true;
        }
        return super.isExpired(ticketState);
    }
ExpirationPolicy that is based on certain number of uses of a ticket or a
certain time period for a ticket to exist.

@author Scott Battaglia
@since 3.0.0
core/cas-server-core-tickets-api/src/main/java/org/apereo/cas/ticket/expiration/MultiTimeUseOrTimeoutExpirationPolicy.java