class KMS {

  @SuppressWarnings("rawtypes")
  @POST
  @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}/" +
      KMSRESTConstants.EEK_SUB_RESOURCE)
  @Produces(MediaType.APPLICATION_JSON)
  public Response decryptEncryptedKey(
      @PathParam("versionName") final String versionName,
      @QueryParam(KMSRESTConstants.EEK_OP) String eekOp,
      Map jsonPayload)
      throws Exception {
    UserGroupInformation user = HttpUserGroupInformation.get();
    KMSClientProvider.checkNotEmpty(versionName, "versionName");
    KMSClientProvider.checkNotNull(eekOp, "eekOp");

    final String keyName = (String) jsonPayload.get(
        KMSRESTConstants.NAME_FIELD);
    String ivStr = (String) jsonPayload.get(KMSRESTConstants.IV_FIELD);
    String encMaterialStr = 
        (String) jsonPayload.get(KMSRESTConstants.MATERIAL_FIELD);
    Object retJSON;
    if (eekOp.equals(KMSRESTConstants.EEK_DECRYPT)) {
      assertAccess(KMSACLs.Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, keyName);
      KMSClientProvider.checkNotNull(ivStr, KMSRESTConstants.IV_FIELD);
      final byte[] iv = Base64.decodeBase64(ivStr);
      KMSClientProvider.checkNotNull(encMaterialStr,
          KMSRESTConstants.MATERIAL_FIELD);
      final byte[] encMaterial = Base64.decodeBase64(encMaterialStr);

      KeyProvider.KeyVersion retKeyVersion = user.doAs(
          new PrivilegedExceptionAction<KeyVersion>() {
            @Override
            public KeyVersion run() throws Exception {
              return provider.decryptEncryptedKey(
                  new KMSClientProvider.KMSEncryptedKeyVersion(keyName,
                      versionName, iv, KeyProviderCryptoExtension.EEK,
                      encMaterial)
              );
            }
          }
      );

      retJSON = KMSServerJSONUtils.toJSON(retKeyVersion);
      kmsAudit.ok(user, KMSOp.DECRYPT_EEK, keyName, "");
    } else {
      throw new IllegalArgumentException("Wrong " + KMSRESTConstants.EEK_OP +
          " value, it must be " + KMSRESTConstants.EEK_GENERATE + " or " +
          KMSRESTConstants.EEK_DECRYPT);
    }
    KMSWebApp.getDecryptEEKCallsMeter().mark();
    return Response.ok().type(MediaType.APPLICATION_JSON).entity(retJSON)
        .build();
  }

  public  KMS();

}