/** {@inheritDoc} */
  @Transactional(readOnly = true)
  @Timed(name = "GET_TICKET_TIMER")
  @Metered(name = "GET_TICKET_METER")
  @Counted(name = "GET_TICKET_COUNTER", monotonic = true)
  @Override
  public <T extends Ticket> T getTicket(final String ticketId, final Class<? extends Ticket> clazz)
      throws InvalidTicketException {
    Assert.notNull(ticketId, "ticketId cannot be null");
    final Ticket ticket = this.ticketRegistry.getTicket(ticketId, clazz);

    if (ticket == null) {
      logger.debug(
          "Ticket [{}] by type [{}] cannot be found in the ticket registry.",
          ticketId,
          clazz.getSimpleName());
      throw new InvalidTicketException(ticketId);
    }

    if (ticket instanceof TicketGrantingTicket) {
      synchronized (ticket) {
        if (ticket.isExpired()) {
          this.ticketRegistry.deleteTicket(ticketId);
          logger.debug(
              "Ticket [{}] has expired and is now deleted from the ticket registry.", ticketId);
          throw new InvalidTicketException(ticketId);
        }
      }
    }
    return (T) ticket;
  }