/** {@inheritDoc} */
  public AccessToken readAccessToken(OAuth2Request request, String tokenId)
      throws ServerException, InvalidGrantException, NotFoundException {

    logger.message("Reading access token");

    JsonValue token;

    // Read from CTS
    try {
      token = tokenStore.read(tokenId);
    } catch (CoreTokenException e) {
      logger.error("Unable to read access token corresponding to id: " + tokenId, e);
      throw new ServerException("Could not read token in CTS: " + e.getMessage());
    }

    if (token == null) {
      logger.error("Unable to read access token corresponding to id: " + tokenId);
      throw new InvalidGrantException("Could not read token in CTS");
    }

    OpenAMAccessToken accessToken = new OpenAMAccessToken(token);
    validateTokenRealm(accessToken.getRealm(), request);

    request.setToken(AccessToken.class, accessToken);
    return accessToken;
  }
  /** {@inheritDoc} */
  public AuthorizationCode readAuthorizationCode(OAuth2Request request, String code)
      throws InvalidGrantException, ServerException, NotFoundException {
    if (logger.messageEnabled()) {
      logger.message("Reading Authorization code: " + code);
    }
    final JsonValue token;

    // Read from CTS
    try {
      token = tokenStore.read(code);
    } catch (CoreTokenException e) {
      logger.error("Unable to read authorization code corresponding to id: " + code, e);
      throw new ServerException("Could not read token from CTS: " + e.getMessage());
    }

    if (token == null) {
      logger.error("Unable to read authorization code corresponding to id: " + code);
      throw new InvalidGrantException("The provided access grant is invalid, expired, or revoked.");
    }

    OpenAMAuthorizationCode authorizationCode = new OpenAMAuthorizationCode(token);
    validateTokenRealm(authorizationCode.getRealm(), request);

    request.setToken(AuthorizationCode.class, authorizationCode);
    return authorizationCode;
  }
  /** {@inheritDoc} */
  public void deleteAuthorizationCode(String authorizationCode) {
    if (logger.messageEnabled()) {
      logger.message(
          "DefaultOAuthTokenStoreImpl::Deleting Authorization code: " + authorizationCode);
    }
    JsonValue oAuthToken;

    // Read from CTS
    try {
      oAuthToken = tokenStore.read(authorizationCode);
    } catch (CoreTokenException e) {
      logger.error(
          "DefaultOAuthTokenStoreImpl::Unable to read authorization code corresponding to id: "
              + authorizationCode,
          e);
      throw new OAuthProblemException(
          Status.SERVER_ERROR_INTERNAL.getCode(),
          "Internal error",
          "Could not read token from CTS: " + e.getMessage(),
          null);
    }

    if (oAuthToken == null) {
      logger.error(
          "DefaultOAuthTokenStoreImpl::Unable to read authorization code corresponding to id: "
              + authorizationCode);
      throw new OAuthProblemException(
          Status.CLIENT_ERROR_NOT_FOUND.getCode(),
          "Not found",
          "Could not find token using CTS",
          null);
    }

    // Delete the code
    try {
      tokenStore.delete(authorizationCode);
    } catch (CoreTokenException e) {
      logger.error(
          "DefaultOAuthTokenStoreImpl::Unable to delete authorization code corresponding to id: "
              + authorizationCode,
          e);
      throw new OAuthProblemException(
          Status.SERVER_ERROR_INTERNAL.getCode(),
          "Internal error",
          "Could not delete token from CTS: " + e.getMessage(),
          null);
    }
  }
  @Override
  public DeviceCode readDeviceCode(String clientId, String code, OAuth2Request request)
      throws ServerException, NotFoundException, InvalidGrantException {
    try {
      JsonValue token = tokenStore.read(code);

      if (token == null) {
        return null;
      }

      DeviceCode deviceCode = new DeviceCode(token);
      if (!clientId.equals(deviceCode.getClientId())) {
        throw new InvalidGrantException();
      }
      validateTokenRealm(deviceCode.getRealm(), request);
      request.setToken(DeviceCode.class, deviceCode);
      return deviceCode;
    } catch (CoreTokenException e) {
      logger.error("Unable to read device code corresponding to id: " + code, e);
      throw new ServerException("Could not read token in CTS: " + e.getMessage());
    }
  }
  /** {@inheritDoc} */
  public RefreshToken readRefreshToken(OAuth2Request request, String tokenId)
      throws ServerException, InvalidGrantException, NotFoundException {

    logger.message("Read refresh token");
    JsonValue token;

    try {
      token = tokenStore.read(tokenId);
    } catch (CoreTokenException e) {
      logger.error("Unable to read refresh token corresponding to id: " + tokenId, e);
      throw new ServerException("Could not read token in CTS: " + e.getMessage());
    }

    if (token == null) {
      logger.error("Unable to read refresh token corresponding to id: " + tokenId);
      throw new InvalidGrantException("grant is invalid");
    }

    OpenAMRefreshToken refreshToken = new OpenAMRefreshToken(token);
    validateTokenRealm(refreshToken.getRealm(), request);

    request.setToken(RefreshToken.class, refreshToken);
    return refreshToken;
  }