class RewardedAdsVerifier {

  public void verify(String rewardUrl) throws GeneralSecurityException {
    URI uri;
    try {
      uri = new URI(rewardUrl);
    } catch (URISyntaxException ex) {
      throw new GeneralSecurityException(ex);
    }
    String queryString = uri.getQuery();
    int i = queryString.indexOf(SIGNATURE_PARAM_NAME);
    if (i <= 0 || queryString.charAt(i - 1) != '&') {
      throw new GeneralSecurityException(
          "signature and key id must be the last two query parameters");
    }
    byte[] tbsData =
        queryString.substring(0, i - 1 /* i - 1 instead of i because of & */).getBytes(UTF_8);

    String sigAndKeyId = queryString.substring(i);
    i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME);
    if (i == -1 || sigAndKeyId.charAt(i - 1) != '&') {
      throw new GeneralSecurityException(
          "signature and key id must be the last two query parameters");
    }
    String sig =
        sigAndKeyId.substring(
            SIGNATURE_PARAM_NAME.length(), i - 1 /* i - 1 instead of i because of & */);

    // We don't have to check that keyId is the last parameter, because the long conversion would
    // fail anyway if there's any trailing data.
    try {
      long keyId = Long.parseLong(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length()));
      verify(tbsData, keyId, Base64.urlSafeDecode(sig));
    } catch (NumberFormatException ex) {
      throw new GeneralSecurityException("key_id must be a long");
    }
  }

    RewardedAdsVerifier(List<VerifyingPublicKeysProvider> verifyingPublicKeysProviders);
  private  RewardedAdsVerifier(Builder builder);

}