// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator

package com.microsoft.azure.keyvault.implementation;

import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureClient;
import com.microsoft.azure.AzureServiceClient;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.keyvault.KeyVaultClientBase;
import com.microsoft.azure.keyvault.models.BackupCertificateResult;
import com.microsoft.azure.keyvault.models.BackupKeyResult;
import com.microsoft.azure.keyvault.models.BackupSecretResult;
import com.microsoft.azure.keyvault.models.BackupStorageResult;
import com.microsoft.azure.keyvault.models.CertificateAttributes;
import com.microsoft.azure.keyvault.models.CertificateBundle;
import com.microsoft.azure.keyvault.models.CertificateCreateParameters;
import com.microsoft.azure.keyvault.models.CertificateImportParameters;
import com.microsoft.azure.keyvault.models.CertificateIssuerItem;
import com.microsoft.azure.keyvault.models.CertificateIssuerSetParameters;
import com.microsoft.azure.keyvault.models.CertificateIssuerUpdateParameters;
import com.microsoft.azure.keyvault.models.CertificateItem;
import com.microsoft.azure.keyvault.models.CertificateMergeParameters;
import com.microsoft.azure.keyvault.models.CertificateOperation;
import com.microsoft.azure.keyvault.models.CertificateOperationUpdateParameter;
import com.microsoft.azure.keyvault.models.CertificatePolicy;
import com.microsoft.azure.keyvault.models.CertificateRestoreParameters;
import com.microsoft.azure.keyvault.models.CertificateUpdateParameters;
import com.microsoft.azure.keyvault.models.Contacts;
import com.microsoft.azure.keyvault.models.DeletedCertificateBundle;
import com.microsoft.azure.keyvault.models.DeletedCertificateItem;
import com.microsoft.azure.keyvault.models.DeletedKeyBundle;
import com.microsoft.azure.keyvault.models.DeletedKeyItem;
import com.microsoft.azure.keyvault.models.DeletedSasDefinitionBundle;
import com.microsoft.azure.keyvault.models.DeletedSasDefinitionItem;
import com.microsoft.azure.keyvault.models.DeletedSecretBundle;
import com.microsoft.azure.keyvault.models.DeletedSecretItem;
import com.microsoft.azure.keyvault.models.DeletedStorageAccountItem;
import com.microsoft.azure.keyvault.models.DeletedStorageBundle;
import com.microsoft.azure.keyvault.models.IssuerAttributes;
import com.microsoft.azure.keyvault.models.IssuerBundle;
import com.microsoft.azure.keyvault.models.IssuerCredentials;
import com.microsoft.azure.keyvault.webkey.JsonWebKey;
import com.microsoft.azure.keyvault.models.JsonWebKeyCurveName;
import com.microsoft.azure.keyvault.webkey.JsonWebKeyEncryptionAlgorithm;
import com.microsoft.azure.keyvault.webkey.JsonWebKeyOperation;
import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm;
import com.microsoft.azure.keyvault.webkey.JsonWebKeyType;
import com.microsoft.azure.keyvault.models.KeyAttributes;
import com.microsoft.azure.keyvault.models.KeyBundle;
import com.microsoft.azure.keyvault.models.KeyCreateParameters;
import com.microsoft.azure.keyvault.models.KeyImportParameters;
import com.microsoft.azure.keyvault.models.KeyItem;
import com.microsoft.azure.keyvault.models.KeyOperationResult;
import com.microsoft.azure.keyvault.models.KeyOperationsParameters;
import com.microsoft.azure.keyvault.models.KeyRestoreParameters;
import com.microsoft.azure.keyvault.models.KeySignParameters;
import com.microsoft.azure.keyvault.models.KeyUpdateParameters;
import com.microsoft.azure.keyvault.models.KeyVaultErrorException;
import com.microsoft.azure.keyvault.models.KeyVerifyParameters;
import com.microsoft.azure.keyvault.models.KeyVerifyResult;
import com.microsoft.azure.keyvault.models.OrganizationDetails;
import com.microsoft.azure.keyvault.models.PageImpl;
import com.microsoft.azure.keyvault.models.SasDefinitionAttributes;
import com.microsoft.azure.keyvault.models.SasDefinitionBundle;
import com.microsoft.azure.keyvault.models.SasDefinitionCreateParameters;
import com.microsoft.azure.keyvault.models.SasDefinitionItem;
import com.microsoft.azure.keyvault.models.SasDefinitionUpdateParameters;
import com.microsoft.azure.keyvault.models.SasTokenType;
import com.microsoft.azure.keyvault.models.SecretAttributes;
import com.microsoft.azure.keyvault.models.SecretBundle;
import com.microsoft.azure.keyvault.models.SecretItem;
import com.microsoft.azure.keyvault.models.SecretRestoreParameters;
import com.microsoft.azure.keyvault.models.SecretSetParameters;
import com.microsoft.azure.keyvault.models.SecretUpdateParameters;
import com.microsoft.azure.keyvault.models.StorageAccountAttributes;
import com.microsoft.azure.keyvault.models.StorageAccountCreateParameters;
import com.microsoft.azure.keyvault.models.StorageAccountItem;
import com.microsoft.azure.keyvault.models.StorageAccountRegenerteKeyParameters;
import com.microsoft.azure.keyvault.models.StorageAccountUpdateParameters;
import com.microsoft.azure.keyvault.models.StorageBundle;
import com.microsoft.azure.keyvault.models.StorageRestoreParameters;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
import com.microsoft.rest.credentials.ServiceClientCredentials;
import com.microsoft.rest.RestClient;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.Validator;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.HTTP;
import retrofit2.http.PATCH;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Query;
import retrofit2.http.Url;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * Initializes a new instance of the KeyVaultClientBaseImpl class.
 */
public class KeyVaultClientBaseImpl extends AzureServiceClient implements KeyVaultClientBase {
    /** The Retrofit service to perform REST calls. */
    private KeyVaultClientBaseService service;
    /** the {@link AzureClient} used for long running operations. */
    private AzureClient azureClient;

    /**
     * Gets the {@link AzureClient} used for long running operations.
     * @return the azure client;
     */
    public AzureClient getAzureClient() {
        return this.azureClient;
    }

    /** Client API version. */
    private String apiVersion;

    /**
     * Gets Client API version.
     *
     * @return the apiVersion value.
     */
    public String apiVersion() {
        return this.apiVersion;
    }

    /** Gets or sets the preferred language for the response. */
    private String acceptLanguage;

    /**
     * Gets Gets or sets the preferred language for the response.
     *
     * @return the acceptLanguage value.
     */
    public String acceptLanguage() {
        return this.acceptLanguage;
    }

    /**
     * Sets Gets or sets the preferred language for the response.
     *
     * @param acceptLanguage the acceptLanguage value.
     * @return the service client itself
     */
    public KeyVaultClientBaseImpl withAcceptLanguage(String acceptLanguage) {
        this.acceptLanguage = acceptLanguage;
        return this;
    }

    /** Gets or sets the retry timeout in seconds for Long Running Operations. Default value is 30. */
    private int longRunningOperationRetryTimeout;

    /**
     * Gets Gets or sets the retry timeout in seconds for Long Running Operations. Default value is 30.
     *
     * @return the longRunningOperationRetryTimeout value.
     */
    public int longRunningOperationRetryTimeout() {
        return this.longRunningOperationRetryTimeout;
    }

    /**
     * Sets Gets or sets the retry timeout in seconds for Long Running Operations. Default value is 30.
     *
     * @param longRunningOperationRetryTimeout the longRunningOperationRetryTimeout value.
     * @return the service client itself
     */
    public KeyVaultClientBaseImpl withLongRunningOperationRetryTimeout(int longRunningOperationRetryTimeout) {
        this.longRunningOperationRetryTimeout = longRunningOperationRetryTimeout;
        return this;
    }

    /** When set to true a unique x-ms-client-request-id value is generated and included in each request. Default is true. */
    private boolean generateClientRequestId;

    /**
     * Gets When set to true a unique x-ms-client-request-id value is generated and included in each request. Default is true.
     *
     * @return the generateClientRequestId value.
     */
    public boolean generateClientRequestId() {
        return this.generateClientRequestId;
    }

    /**
     * Sets When set to true a unique x-ms-client-request-id value is generated and included in each request. Default is true.
     *
     * @param generateClientRequestId the generateClientRequestId value.
     * @return the service client itself
     */
    public KeyVaultClientBaseImpl withGenerateClientRequestId(boolean generateClientRequestId) {
        this.generateClientRequestId = generateClientRequestId;
        return this;
    }

    /**
     * Initializes an instance of KeyVaultClientBase client.
     *
     * @param credentials the management credentials for Azure
     */
    public KeyVaultClientBaseImpl(ServiceClientCredentials credentials) {
        this("https://{vaultBaseUrl}", credentials);
    }

    /**
     * Initializes an instance of KeyVaultClientBase client.
     *
     * @param baseUrl the base URL of the host
     * @param credentials the management credentials for Azure
     */
    private KeyVaultClientBaseImpl(String baseUrl, ServiceClientCredentials credentials) {
        super(baseUrl, credentials);
        initialize();
    }

    /**
     * Initializes an instance of KeyVaultClientBase client.
     *
     * @param restClient the REST client to connect to Azure.
     */
    public KeyVaultClientBaseImpl(RestClient restClient) {
        super(restClient);
        initialize();
    }

    protected void initialize() {
        this.apiVersion = "7.0";
        this.acceptLanguage = "en-US";
        this.longRunningOperationRetryTimeout = 30;
        this.generateClientRequestId = true;
        this.azureClient = new AzureClient(this);
        initializeService();
    }

    /**
     * Gets the User-Agent header for the client.
     *
     * @return the user agent string.
     */
    @Override
    public String userAgent() {
        return String.format("%s (%s, %s)", super.userAgent(), "KeyVaultClientBase", "7.0");
    }

    private void initializeService() {
        service = restClient().retrofit().create(KeyVaultClientBaseService.class);
    }

    /**
     * The interface defining all the services for KeyVaultClientBase to be
     * used by Retrofit to perform actually REST calls.
     */
    interface KeyVaultClientBaseService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase createKey" })
        @POST("keys/{key-name}/create")
        Observable<Response<ResponseBody>> createKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyCreateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase importKey" })
        @PUT("keys/{key-name}")
        Observable<Response<ResponseBody>> importKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyImportParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteKey" })
        @HTTP(path = "keys/{key-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateKey" })
        @PATCH("keys/{key-name}/{key-version}")
        Observable<Response<ResponseBody>> updateKey(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyUpdateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getKey" })
        @GET("keys/{key-name}/{key-version}")
        Observable<Response<ResponseBody>> getKey(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getKeyVersions" })
        @GET("keys/{key-name}/versions")
        Observable<Response<ResponseBody>> getKeyVersions(@Path("key-name") String keyName, @Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getKeys" })
        @GET("keys")
        Observable<Response<ResponseBody>> getKeys(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase backupKey" })
        @POST("keys/{key-name}/backup")
        Observable<Response<ResponseBody>> backupKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase restoreKey" })
        @POST("keys/restore")
        Observable<Response<ResponseBody>> restoreKey(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyRestoreParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase encrypt" })
        @POST("keys/{key-name}/{key-version}/encrypt")
        Observable<Response<ResponseBody>> encrypt(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyOperationsParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase decrypt" })
        @POST("keys/{key-name}/{key-version}/decrypt")
        Observable<Response<ResponseBody>> decrypt(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyOperationsParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase sign" })
        @POST("keys/{key-name}/{key-version}/sign")
        Observable<Response<ResponseBody>> sign(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeySignParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase verify" })
        @POST("keys/{key-name}/{key-version}/verify")
        Observable<Response<ResponseBody>> verify(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyVerifyParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase wrapKey" })
        @POST("keys/{key-name}/{key-version}/wrapkey")
        Observable<Response<ResponseBody>> wrapKey(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyOperationsParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase unwrapKey" })
        @POST("keys/{key-name}/{key-version}/unwrapkey")
        Observable<Response<ResponseBody>> unwrapKey(@Path("key-name") String keyName, @Path("key-version") String keyVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body KeyOperationsParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedKeys" })
        @GET("deletedkeys")
        Observable<Response<ResponseBody>> getDeletedKeys(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedKey" })
        @GET("deletedkeys/{key-name}")
        Observable<Response<ResponseBody>> getDeletedKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase purgeDeletedKey" })
        @HTTP(path = "deletedkeys/{key-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> purgeDeletedKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase recoverDeletedKey" })
        @POST("deletedkeys/{key-name}/recover")
        Observable<Response<ResponseBody>> recoverDeletedKey(@Path("key-name") String keyName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase setSecret" })
        @PUT("secrets/{secret-name}")
        Observable<Response<ResponseBody>> setSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body SecretSetParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteSecret" })
        @HTTP(path = "secrets/{secret-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateSecret" })
        @PATCH("secrets/{secret-name}/{secret-version}")
        Observable<Response<ResponseBody>> updateSecret(@Path("secret-name") String secretName, @Path("secret-version") String secretVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body SecretUpdateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSecret" })
        @GET("secrets/{secret-name}/{secret-version}")
        Observable<Response<ResponseBody>> getSecret(@Path("secret-name") String secretName, @Path("secret-version") String secretVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSecrets" })
        @GET("secrets")
        Observable<Response<ResponseBody>> getSecrets(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSecretVersions" })
        @GET("secrets/{secret-name}/versions")
        Observable<Response<ResponseBody>> getSecretVersions(@Path("secret-name") String secretName, @Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSecrets" })
        @GET("deletedsecrets")
        Observable<Response<ResponseBody>> getDeletedSecrets(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSecret" })
        @GET("deletedsecrets/{secret-name}")
        Observable<Response<ResponseBody>> getDeletedSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase purgeDeletedSecret" })
        @HTTP(path = "deletedsecrets/{secret-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> purgeDeletedSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase recoverDeletedSecret" })
        @POST("deletedsecrets/{secret-name}/recover")
        Observable<Response<ResponseBody>> recoverDeletedSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase backupSecret" })
        @POST("secrets/{secret-name}/backup")
        Observable<Response<ResponseBody>> backupSecret(@Path("secret-name") String secretName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase restoreSecret" })
        @POST("secrets/restore")
        Observable<Response<ResponseBody>> restoreSecret(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body SecretRestoreParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificates" })
        @GET("certificates")
        Observable<Response<ResponseBody>> getCertificates(@Query("maxresults") Integer maxresults, @Query("includePending") Boolean includePending, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteCertificate" })
        @HTTP(path = "certificates/{certificate-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase setCertificateContacts" })
        @PUT("certificates/contacts")
        Observable<Response<ResponseBody>> setCertificateContacts(@Body Contacts contacts, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateContacts" })
        @GET("certificates/contacts")
        Observable<Response<ResponseBody>> getCertificateContacts(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteCertificateContacts" })
        @HTTP(path = "certificates/contacts", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteCertificateContacts(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateIssuers" })
        @GET("certificates/issuers")
        Observable<Response<ResponseBody>> getCertificateIssuers(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase setCertificateIssuer" })
        @PUT("certificates/issuers/{issuer-name}")
        Observable<Response<ResponseBody>> setCertificateIssuer(@Path("issuer-name") String issuerName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateIssuerSetParameters parameter, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateCertificateIssuer" })
        @PATCH("certificates/issuers/{issuer-name}")
        Observable<Response<ResponseBody>> updateCertificateIssuer(@Path("issuer-name") String issuerName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateIssuerUpdateParameters parameter, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateIssuer" })
        @GET("certificates/issuers/{issuer-name}")
        Observable<Response<ResponseBody>> getCertificateIssuer(@Path("issuer-name") String issuerName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteCertificateIssuer" })
        @HTTP(path = "certificates/issuers/{issuer-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteCertificateIssuer(@Path("issuer-name") String issuerName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase createCertificate" })
        @POST("certificates/{certificate-name}/create")
        Observable<Response<ResponseBody>> createCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateCreateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase importCertificate" })
        @POST("certificates/{certificate-name}/import")
        Observable<Response<ResponseBody>> importCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateImportParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateVersions" })
        @GET("certificates/{certificate-name}/versions")
        Observable<Response<ResponseBody>> getCertificateVersions(@Path("certificate-name") String certificateName, @Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificatePolicy" })
        @GET("certificates/{certificate-name}/policy")
        Observable<Response<ResponseBody>> getCertificatePolicy(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateCertificatePolicy" })
        @PATCH("certificates/{certificate-name}/policy")
        Observable<Response<ResponseBody>> updateCertificatePolicy(@Path("certificate-name") String certificateName, @Body CertificatePolicy certificatePolicy, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateCertificate" })
        @PATCH("certificates/{certificate-name}/{certificate-version}")
        Observable<Response<ResponseBody>> updateCertificate(@Path("certificate-name") String certificateName, @Path("certificate-version") String certificateVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateUpdateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificate" })
        @GET("certificates/{certificate-name}/{certificate-version}")
        Observable<Response<ResponseBody>> getCertificate(@Path("certificate-name") String certificateName, @Path("certificate-version") String certificateVersion, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateCertificateOperation" })
        @PATCH("certificates/{certificate-name}/pending")
        Observable<Response<ResponseBody>> updateCertificateOperation(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateOperationUpdateParameter certificateOperation, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateOperation" })
        @GET("certificates/{certificate-name}/pending")
        Observable<Response<ResponseBody>> getCertificateOperation(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteCertificateOperation" })
        @HTTP(path = "certificates/{certificate-name}/pending", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteCertificateOperation(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase mergeCertificate" })
        @POST("certificates/{certificate-name}/pending/merge")
        Observable<Response<ResponseBody>> mergeCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateMergeParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase backupCertificate" })
        @POST("certificates/{certificate-name}/backup")
        Observable<Response<ResponseBody>> backupCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase restoreCertificate" })
        @POST("certificates/restore")
        Observable<Response<ResponseBody>> restoreCertificate(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body CertificateRestoreParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedCertificates" })
        @GET("deletedcertificates")
        Observable<Response<ResponseBody>> getDeletedCertificates(@Query("maxresults") Integer maxresults, @Query("includePending") Boolean includePending, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedCertificate" })
        @GET("deletedcertificates/{certificate-name}")
        Observable<Response<ResponseBody>> getDeletedCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase purgeDeletedCertificate" })
        @HTTP(path = "deletedcertificates/{certificate-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> purgeDeletedCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase recoverDeletedCertificate" })
        @POST("deletedcertificates/{certificate-name}/recover")
        Observable<Response<ResponseBody>> recoverDeletedCertificate(@Path("certificate-name") String certificateName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getStorageAccounts" })
        @GET("storage")
        Observable<Response<ResponseBody>> getStorageAccounts(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedStorageAccounts" })
        @GET("deletedstorage")
        Observable<Response<ResponseBody>> getDeletedStorageAccounts(@Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedStorageAccount" })
        @GET("deletedstorage/{storage-account-name}")
        Observable<Response<ResponseBody>> getDeletedStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase purgeDeletedStorageAccount" })
        @HTTP(path = "deletedstorage/{storage-account-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> purgeDeletedStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase recoverDeletedStorageAccount" })
        @POST("deletedstorage/{storage-account-name}/recover")
        Observable<Response<ResponseBody>> recoverDeletedStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase backupStorageAccount" })
        @POST("storage/{storage-account-name}/backup")
        Observable<Response<ResponseBody>> backupStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase restoreStorageAccount" })
        @POST("storage/restore")
        Observable<Response<ResponseBody>> restoreStorageAccount(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body StorageRestoreParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteStorageAccount" })
        @HTTP(path = "storage/{storage-account-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getStorageAccount" })
        @GET("storage/{storage-account-name}")
        Observable<Response<ResponseBody>> getStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase setStorageAccount" })
        @PUT("storage/{storage-account-name}")
        Observable<Response<ResponseBody>> setStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body StorageAccountCreateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateStorageAccount" })
        @PATCH("storage/{storage-account-name}")
        Observable<Response<ResponseBody>> updateStorageAccount(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body StorageAccountUpdateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase regenerateStorageAccountKey" })
        @POST("storage/{storage-account-name}/regeneratekey")
        Observable<Response<ResponseBody>> regenerateStorageAccountKey(@Path("storage-account-name") String storageAccountName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body StorageAccountRegenerteKeyParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSasDefinitions" })
        @GET("storage/{storage-account-name}/sas")
        Observable<Response<ResponseBody>> getSasDefinitions(@Path("storage-account-name") String storageAccountName, @Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSasDefinitions" })
        @GET("deletedstorage/{storage-account-name}/sas")
        Observable<Response<ResponseBody>> getDeletedSasDefinitions(@Path("storage-account-name") String storageAccountName, @Query("maxresults") Integer maxresults, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSasDefinition" })
        @GET("deletedstorage/{storage-account-name}/sas/{sas-definition-name}")
        Observable<Response<ResponseBody>> getDeletedSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase recoverDeletedSasDefinition" })
        @POST("deletedstorage/{storage-account-name}/sas/{sas-definition-name}/recover")
        Observable<Response<ResponseBody>> recoverDeletedSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase deleteSasDefinition" })
        @HTTP(path = "storage/{storage-account-name}/sas/{sas-definition-name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> deleteSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSasDefinition" })
        @GET("storage/{storage-account-name}/sas/{sas-definition-name}")
        Observable<Response<ResponseBody>> getSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase setSasDefinition" })
        @PUT("storage/{storage-account-name}/sas/{sas-definition-name}")
        Observable<Response<ResponseBody>> setSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body SasDefinitionCreateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase updateSasDefinition" })
        @PATCH("storage/{storage-account-name}/sas/{sas-definition-name}")
        Observable<Response<ResponseBody>> updateSasDefinition(@Path("storage-account-name") String storageAccountName, @Path("sas-definition-name") String sasDefinitionName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Body SasDefinitionUpdateParameters parameters, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getKeyVersionsNext" })
        @GET
        Observable<Response<ResponseBody>> getKeyVersionsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getKeysNext" })
        @GET
        Observable<Response<ResponseBody>> getKeysNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedKeysNext" })
        @GET
        Observable<Response<ResponseBody>> getDeletedKeysNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSecretsNext" })
        @GET
        Observable<Response<ResponseBody>> getSecretsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSecretVersionsNext" })
        @GET
        Observable<Response<ResponseBody>> getSecretVersionsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSecretsNext" })
        @GET
        Observable<Response<ResponseBody>> getDeletedSecretsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificatesNext" })
        @GET
        Observable<Response<ResponseBody>> getCertificatesNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateIssuersNext" })
        @GET
        Observable<Response<ResponseBody>> getCertificateIssuersNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getCertificateVersionsNext" })
        @GET
        Observable<Response<ResponseBody>> getCertificateVersionsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedCertificatesNext" })
        @GET
        Observable<Response<ResponseBody>> getDeletedCertificatesNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getStorageAccountsNext" })
        @GET
        Observable<Response<ResponseBody>> getStorageAccountsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedStorageAccountsNext" })
        @GET
        Observable<Response<ResponseBody>> getDeletedStorageAccountsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getSasDefinitionsNext" })
        @GET
        Observable<Response<ResponseBody>> getSasDefinitionsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClientBase getDeletedSasDefinitionsNext" })
        @GET
        Observable<Response<ResponseBody>> getDeletedSasDefinitionsNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle createKey(String vaultBaseUrl, String keyName, JsonWebKeyType kty) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty).toBlocking().single().body();
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> createKeyAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty), serviceCallback);
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> createKeyAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> createKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (kty == null) {
            throw new IllegalArgumentException("Parameter kty is required and cannot be null.");
        }
        final Integer keySize = null;
        final List<JsonWebKeyOperation> keyOps = null;
        final KeyAttributes keyAttributes = null;
        final Map<String, String> tags = null;
        final JsonWebKeyCurveName curve = null;
        KeyCreateParameters parameters = new KeyCreateParameters();
        parameters.withKty(kty);
        parameters.withKeySize(null);
        parameters.withKeyOps(null);
        parameters.withKeyAttributes(null);
        parameters.withTags(null);
        parameters.withCurve(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.createKey(keyName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = createKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bits. For example: 2048, 3072, or 4096 for RSA.
     * @param keyOps the List&lt;JsonWebKeyOperation&gt; value
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param curve Elliptic curve name. For valid values, see JsonWebKeyCurveName. Possible values include: 'P-256', 'P-384', 'P-521', 'P-256K'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle createKey(String vaultBaseUrl, String keyName, JsonWebKeyType kty, Integer keySize, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags, JsonWebKeyCurveName curve) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags, curve).toBlocking().single().body();
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bits. For example: 2048, 3072, or 4096 for RSA.
     * @param keyOps the List&lt;JsonWebKeyOperation&gt; value
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param curve Elliptic curve name. For valid values, see JsonWebKeyCurveName. Possible values include: 'P-256', 'P-384', 'P-521', 'P-256K'
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> createKeyAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty, Integer keySize, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags, JsonWebKeyCurveName curve, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags, curve), serviceCallback);
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bits. For example: 2048, 3072, or 4096 for RSA.
     * @param keyOps the List&lt;JsonWebKeyOperation&gt; value
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param curve Elliptic curve name. For valid values, see JsonWebKeyCurveName. Possible values include: 'P-256', 'P-384', 'P-521', 'P-256K'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> createKeyAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty, Integer keySize, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags, JsonWebKeyCurveName curve) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags, curve).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a new key, stores it, then returns key parameters and attributes to the client.
     * The create key operation can be used to create any key type in Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. It requires the keys/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name for the new key. The system will generate the version name for the new key.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType. Possible values include: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bits. For example: 2048, 3072, or 4096 for RSA.
     * @param keyOps the List&lt;JsonWebKeyOperation&gt; value
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param curve Elliptic curve name. For valid values, see JsonWebKeyCurveName. Possible values include: 'P-256', 'P-384', 'P-521', 'P-256K'
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> createKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, JsonWebKeyType kty, Integer keySize, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags, JsonWebKeyCurveName curve) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (kty == null) {
            throw new IllegalArgumentException("Parameter kty is required and cannot be null.");
        }
        Validator.validate(keyOps);
        Validator.validate(keyAttributes);
        Validator.validate(tags);
        KeyCreateParameters parameters = new KeyCreateParameters();
        parameters.withKty(kty);
        parameters.withKeySize(keySize);
        parameters.withKeyOps(keyOps);
        parameters.withKeyAttributes(keyAttributes);
        parameters.withTags(tags);
        parameters.withCurve(curve);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.createKey(keyName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = createKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> createKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle importKey(String vaultBaseUrl, String keyName, JsonWebKey key) {
        return importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key).toBlocking().single().body();
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> importKeyAsync(String vaultBaseUrl, String keyName, JsonWebKey key, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key), serviceCallback);
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> importKeyAsync(String vaultBaseUrl, String keyName, JsonWebKey key) {
        return importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> importKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, JsonWebKey key) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (key == null) {
            throw new IllegalArgumentException("Parameter key is required and cannot be null.");
        }
        Validator.validate(key);
        final Boolean hsm = null;
        final KeyAttributes keyAttributes = null;
        final Map<String, String> tags = null;
        KeyImportParameters parameters = new KeyImportParameters();
        parameters.withHsm(null);
        parameters.withKey(key);
        parameters.withKeyAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.importKey(keyName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = importKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @param hsm Whether to import as a hardware key (HSM) or software key.
     * @param keyAttributes The key management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle importKey(String vaultBaseUrl, String keyName, JsonWebKey key, Boolean hsm, KeyAttributes keyAttributes, Map<String, String> tags) {
        return importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key, hsm, keyAttributes, tags).toBlocking().single().body();
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @param hsm Whether to import as a hardware key (HSM) or software key.
     * @param keyAttributes The key management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> importKeyAsync(String vaultBaseUrl, String keyName, JsonWebKey key, Boolean hsm, KeyAttributes keyAttributes, Map<String, String> tags, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key, hsm, keyAttributes, tags), serviceCallback);
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @param hsm Whether to import as a hardware key (HSM) or software key.
     * @param keyAttributes The key management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> importKeyAsync(String vaultBaseUrl, String keyName, JsonWebKey key, Boolean hsm, KeyAttributes keyAttributes, Map<String, String> tags) {
        return importKeyWithServiceResponseAsync(vaultBaseUrl, keyName, key, hsm, keyAttributes, tags).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports an externally created key, stores it, and returns key parameters and attributes to the client.
     * The import key operation may be used to import any key type into an Azure Key Vault. If the named key already exists, Azure Key Vault creates a new version of the key. This operation requires the keys/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName Name for the imported key.
     * @param key The Json web key
     * @param hsm Whether to import as a hardware key (HSM) or software key.
     * @param keyAttributes The key management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> importKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, JsonWebKey key, Boolean hsm, KeyAttributes keyAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (key == null) {
            throw new IllegalArgumentException("Parameter key is required and cannot be null.");
        }
        Validator.validate(key);
        Validator.validate(keyAttributes);
        Validator.validate(tags);
        KeyImportParameters parameters = new KeyImportParameters();
        parameters.withHsm(hsm);
        parameters.withKey(key);
        parameters.withKeyAttributes(keyAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.importKey(keyName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = importKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> importKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes a key of any type from storage in Azure Key Vault.
     * The delete key operation cannot be used to remove individual versions of a key. This operation removes the cryptographic material associated with the key, which means the key is not usable for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the keys/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedKeyBundle object if successful.
     */
    public DeletedKeyBundle deleteKey(String vaultBaseUrl, String keyName) {
        return deleteKeyWithServiceResponseAsync(vaultBaseUrl, keyName).toBlocking().single().body();
    }

    /**
     * Deletes a key of any type from storage in Azure Key Vault.
     * The delete key operation cannot be used to remove individual versions of a key. This operation removes the cryptographic material associated with the key, which means the key is not usable for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the keys/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to delete.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedKeyBundle> deleteKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<DeletedKeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteKeyWithServiceResponseAsync(vaultBaseUrl, keyName), serviceCallback);
    }

    /**
     * Deletes a key of any type from storage in Azure Key Vault.
     * The delete key operation cannot be used to remove individual versions of a key. This operation removes the cryptographic material associated with the key, which means the key is not usable for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the keys/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedKeyBundle object
     */
    public Observable<DeletedKeyBundle> deleteKeyAsync(String vaultBaseUrl, String keyName) {
        return deleteKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<DeletedKeyBundle>, DeletedKeyBundle>() {
            @Override
            public DeletedKeyBundle call(ServiceResponse<DeletedKeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a key of any type from storage in Azure Key Vault.
     * The delete key operation cannot be used to remove individual versions of a key. This operation removes the cryptographic material associated with the key, which means the key is not usable for Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the keys/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to delete.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedKeyBundle object
     */
    public Observable<ServiceResponse<DeletedKeyBundle>> deleteKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteKey(keyName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedKeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedKeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedKeyBundle> clientResponse = deleteKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedKeyBundle> deleteKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedKeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedKeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle updateKey(String vaultBaseUrl, String keyName, String keyVersion) {
        return updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion).toBlocking().single().body();
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> updateKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion), serviceCallback);
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> updateKeyAsync(String vaultBaseUrl, String keyName, String keyVersion) {
        return updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> updateKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final List<JsonWebKeyOperation> keyOps = null;
        final KeyAttributes keyAttributes = null;
        final Map<String, String> tags = null;
        KeyUpdateParameters parameters = new KeyUpdateParameters();
        parameters.withKeyOps(null);
        parameters.withKeyAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateKey(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = updateKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param keyOps Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle updateKey(String vaultBaseUrl, String keyName, String keyVersion, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags) {
        return updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, keyOps, keyAttributes, tags).toBlocking().single().body();
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param keyOps Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> updateKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, keyOps, keyAttributes, tags), serviceCallback);
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param keyOps Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> updateKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags) {
        return updateKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, keyOps, keyAttributes, tags).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * The update key operation changes specified attributes of a stored key and can be applied to any key type and key version stored in Azure Key Vault.
     * In order to perform this operation, the key must already exist in the Key Vault. Note: The cryptographic material of a key itself cannot be changed. This operation requires the keys/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to update.
     * @param keyVersion The version of the key to update.
     * @param keyOps Json web key operations. For more information on possible key operations, see JsonWebKeyOperation.
     * @param keyAttributes the KeyAttributes value
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> updateKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, List<JsonWebKeyOperation> keyOps, KeyAttributes keyAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(keyOps);
        Validator.validate(keyAttributes);
        Validator.validate(tags);
        KeyUpdateParameters parameters = new KeyUpdateParameters();
        parameters.withKeyOps(keyOps);
        parameters.withKeyAttributes(keyAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateKey(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = updateKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> updateKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the public part of a stored key.
     * The get key operation is applicable to all key types. If the requested key is symmetric, then no key material is released in the response. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle getKey(String vaultBaseUrl, String keyName, String keyVersion) {
        return getKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion).toBlocking().single().body();
    }

    /**
     * Gets the public part of a stored key.
     * The get key operation is applicable to all key types. If the requested key is symmetric, then no key material is released in the response. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> getKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion), serviceCallback);
    }

    /**
     * Gets the public part of a stored key.
     * The get key operation is applicable to all key types. If the requested key is symmetric, then no key material is released in the response. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> getKeyAsync(String vaultBaseUrl, String keyName, String keyVersion) {
        return getKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the public part of a stored key.
     * The get key operation is applicable to all key types. If the requested key is symmetric, then no key material is released in the response. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key to get.
     * @param keyVersion Adding the version parameter retrieves a specific version of a key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> getKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getKey(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = getKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> getKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeyVersions(final String vaultBaseUrl, final String keyName) {
        ServiceResponse<Page<KeyItem>> response = getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeyVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeyVersionsAsync(final String vaultBaseUrl, final String keyName, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeyVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeyVersionsAsync(final String vaultBaseUrl, final String keyName) {
        return getKeyVersionsWithServiceResponseAsync(vaultBaseUrl, keyName)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String keyName) {
        return getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeyVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsSinglePageAsync(final String vaultBaseUrl, final String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getKeyVersions(keyName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeyVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeyVersions(final String vaultBaseUrl, final String keyName, final Integer maxresults) {
        ServiceResponse<Page<KeyItem>> response = getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName, maxresults).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeyVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeyVersionsAsync(final String vaultBaseUrl, final String keyName, final Integer maxresults, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeyVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeyVersionsAsync(final String vaultBaseUrl, final String keyName, final Integer maxresults) {
        return getKeyVersionsWithServiceResponseAsync(vaultBaseUrl, keyName, maxresults)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String keyName, final Integer maxresults) {
        return getKeyVersionsSinglePageAsync(vaultBaseUrl, keyName, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeyVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsSinglePageAsync(final String vaultBaseUrl, final String keyName, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getKeyVersions(keyName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeyVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<KeyItem>> getKeyVersionsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<KeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<KeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeys(final String vaultBaseUrl) {
        ServiceResponse<Page<KeyItem>> response = getKeysSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeysAsync(final String vaultBaseUrl, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeysSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeysAsync(final String vaultBaseUrl) {
        return getKeysWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysWithServiceResponseAsync(final String vaultBaseUrl) {
        return getKeysSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getKeys(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeysDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeys(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<KeyItem>> response = getKeysSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeysAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeysSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeysAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getKeysWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getKeysSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getKeys(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeysDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<KeyItem>> getKeysDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<KeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<KeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Requests that a backup of the specified key be downloaded to the client.
     * The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this operation does NOT return key material in a form that can be used outside the Azure Key Vault system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key Vault itself. The intent of this operation is to allow a client to GENERATE a key in one Azure Key Vault instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance. The BACKUP operation may be used to export, in protected form, any key type from Azure Key Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE can be performed within geographical boundaries only; meaning that a BACKUP from one geographical area cannot be restored to another geographical area. For example, a backup from the US geographical area cannot be restored in an EU geographical area. This operation requires the key/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the BackupKeyResult object if successful.
     */
    public BackupKeyResult backupKey(String vaultBaseUrl, String keyName) {
        return backupKeyWithServiceResponseAsync(vaultBaseUrl, keyName).toBlocking().single().body();
    }

    /**
     * Requests that a backup of the specified key be downloaded to the client.
     * The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this operation does NOT return key material in a form that can be used outside the Azure Key Vault system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key Vault itself. The intent of this operation is to allow a client to GENERATE a key in one Azure Key Vault instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance. The BACKUP operation may be used to export, in protected form, any key type from Azure Key Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE can be performed within geographical boundaries only; meaning that a BACKUP from one geographical area cannot be restored to another geographical area. For example, a backup from the US geographical area cannot be restored in an EU geographical area. This operation requires the key/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<BackupKeyResult> backupKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<BackupKeyResult> serviceCallback) {
        return ServiceFuture.fromResponse(backupKeyWithServiceResponseAsync(vaultBaseUrl, keyName), serviceCallback);
    }

    /**
     * Requests that a backup of the specified key be downloaded to the client.
     * The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this operation does NOT return key material in a form that can be used outside the Azure Key Vault system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key Vault itself. The intent of this operation is to allow a client to GENERATE a key in one Azure Key Vault instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance. The BACKUP operation may be used to export, in protected form, any key type from Azure Key Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE can be performed within geographical boundaries only; meaning that a BACKUP from one geographical area cannot be restored to another geographical area. For example, a backup from the US geographical area cannot be restored in an EU geographical area. This operation requires the key/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupKeyResult object
     */
    public Observable<BackupKeyResult> backupKeyAsync(String vaultBaseUrl, String keyName) {
        return backupKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<BackupKeyResult>, BackupKeyResult>() {
            @Override
            public BackupKeyResult call(ServiceResponse<BackupKeyResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Requests that a backup of the specified key be downloaded to the client.
     * The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this operation does NOT return key material in a form that can be used outside the Azure Key Vault system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key Vault itself. The intent of this operation is to allow a client to GENERATE a key in one Azure Key Vault instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance. The BACKUP operation may be used to export, in protected form, any key type from Azure Key Vault. Individual versions of a key cannot be backed up. BACKUP / RESTORE can be performed within geographical boundaries only; meaning that a BACKUP from one geographical area cannot be restored to another geographical area. For example, a backup from the US geographical area cannot be restored in an EU geographical area. This operation requires the key/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupKeyResult object
     */
    public Observable<ServiceResponse<BackupKeyResult>> backupKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.backupKey(keyName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<BackupKeyResult>>>() {
                @Override
                public Observable<ServiceResponse<BackupKeyResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<BackupKeyResult> clientResponse = backupKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<BackupKeyResult> backupKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<BackupKeyResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<BackupKeyResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Restores a backed up key to a vault.
     * Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier, attributes and access control policies. The RESTORE operation may be used to import a previously backed up key. Individual versions of a key cannot be restored. The key is restored in its entirety with the same key name as it had when it was backed up. If the key name is not available in the target Key Vault, the RESTORE operation will be rejected. While the key name is retained during restore, the final key identifier will change if the key is restored to a different vault. Restore will restore all versions and preserve version identifiers. The RESTORE operation is subject to security constraints: The target Key Vault must be owned by the same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission in the target Key Vault. This operation requires the keys/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle restoreKey(String vaultBaseUrl, byte[] keyBundleBackup) {
        return restoreKeyWithServiceResponseAsync(vaultBaseUrl, keyBundleBackup).toBlocking().single().body();
    }

    /**
     * Restores a backed up key to a vault.
     * Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier, attributes and access control policies. The RESTORE operation may be used to import a previously backed up key. Individual versions of a key cannot be restored. The key is restored in its entirety with the same key name as it had when it was backed up. If the key name is not available in the target Key Vault, the RESTORE operation will be rejected. While the key name is retained during restore, the final key identifier will change if the key is restored to a different vault. Restore will restore all versions and preserve version identifiers. The RESTORE operation is subject to security constraints: The target Key Vault must be owned by the same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission in the target Key Vault. This operation requires the keys/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> restoreKeyAsync(String vaultBaseUrl, byte[] keyBundleBackup, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(restoreKeyWithServiceResponseAsync(vaultBaseUrl, keyBundleBackup), serviceCallback);
    }

    /**
     * Restores a backed up key to a vault.
     * Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier, attributes and access control policies. The RESTORE operation may be used to import a previously backed up key. Individual versions of a key cannot be restored. The key is restored in its entirety with the same key name as it had when it was backed up. If the key name is not available in the target Key Vault, the RESTORE operation will be rejected. While the key name is retained during restore, the final key identifier will change if the key is restored to a different vault. Restore will restore all versions and preserve version identifiers. The RESTORE operation is subject to security constraints: The target Key Vault must be owned by the same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission in the target Key Vault. This operation requires the keys/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> restoreKeyAsync(String vaultBaseUrl, byte[] keyBundleBackup) {
        return restoreKeyWithServiceResponseAsync(vaultBaseUrl, keyBundleBackup).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Restores a backed up key to a vault.
     * Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier, attributes and access control policies. The RESTORE operation may be used to import a previously backed up key. Individual versions of a key cannot be restored. The key is restored in its entirety with the same key name as it had when it was backed up. If the key name is not available in the target Key Vault, the RESTORE operation will be rejected. While the key name is retained during restore, the final key identifier will change if the key is restored to a different vault. Restore will restore all versions and preserve version identifiers. The RESTORE operation is subject to security constraints: The target Key Vault must be owned by the same Microsoft Azure Subscription as the source Key Vault The user must have RESTORE permission in the target Key Vault. This operation requires the keys/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> restoreKeyWithServiceResponseAsync(String vaultBaseUrl, byte[] keyBundleBackup) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (keyBundleBackup == null) {
            throw new IllegalArgumentException("Parameter keyBundleBackup is required and cannot be null.");
        }
        KeyRestoreParameters parameters = new KeyRestoreParameters();
        parameters.withKeyBundleBackup(keyBundleBackup);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.restoreKey(this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = restoreKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> restoreKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.
     * The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of data, the size of which is dependent on the target key and the encryption algorithm to be used. The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/encypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyOperationResult object if successful.
     */
    public KeyOperationResult encrypt(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return encryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).toBlocking().single().body();
    }

    /**
     * Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.
     * The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of data, the size of which is dependent on the target key and the encryption algorithm to be used. The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/encypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyOperationResult> encryptAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value, final ServiceCallback<KeyOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(encryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value), serviceCallback);
    }

    /**
     * Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.
     * The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of data, the size of which is dependent on the target key and the encryption algorithm to be used. The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/encypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<KeyOperationResult> encryptAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return encryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).map(new Func1<ServiceResponse<KeyOperationResult>, KeyOperationResult>() {
            @Override
            public KeyOperationResult call(ServiceResponse<KeyOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Encrypts an arbitrary sequence of bytes using an encryption key that is stored in a key vault.
     * The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is stored in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of data, the size of which is dependent on the target key and the encryption algorithm to be used. The ENCRYPT operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/encypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<ServiceResponse<KeyOperationResult>> encryptWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        KeyOperationsParameters parameters = new KeyOperationsParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.encrypt(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyOperationResult> clientResponse = encryptDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyOperationResult> encryptDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyOperationResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyOperationResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Decrypts a single block of encrypted data.
     * The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a single block of data may be decrypted, the size of this block is dependent on the target key and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyOperationResult object if successful.
     */
    public KeyOperationResult decrypt(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return decryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).toBlocking().single().body();
    }

    /**
     * Decrypts a single block of encrypted data.
     * The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a single block of data may be decrypted, the size of this block is dependent on the target key and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyOperationResult> decryptAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value, final ServiceCallback<KeyOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(decryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value), serviceCallback);
    }

    /**
     * Decrypts a single block of encrypted data.
     * The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a single block of data may be decrypted, the size of this block is dependent on the target key and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<KeyOperationResult> decryptAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return decryptWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).map(new Func1<ServiceResponse<KeyOperationResult>, KeyOperationResult>() {
            @Override
            public KeyOperationResult call(ServiceResponse<KeyOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Decrypts a single block of encrypted data.
     * The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption key and specified algorithm. This operation is the reverse of the ENCRYPT operation; only a single block of data may be decrypted, the size of this block is dependent on the target key and the algorithm to be used. The DECRYPT operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/decrypt permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<ServiceResponse<KeyOperationResult>> decryptWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        KeyOperationsParameters parameters = new KeyOperationsParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.decrypt(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyOperationResult> clientResponse = decryptDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyOperationResult> decryptDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyOperationResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyOperationResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Creates a signature from a digest using the specified key.
     * The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault since this operation uses the private portion of the key. This operation requires the keys/sign permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyOperationResult object if successful.
     */
    public KeyOperationResult sign(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] value) {
        return signWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).toBlocking().single().body();
    }

    /**
     * Creates a signature from a digest using the specified key.
     * The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault since this operation uses the private portion of the key. This operation requires the keys/sign permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyOperationResult> signAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] value, final ServiceCallback<KeyOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(signWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value), serviceCallback);
    }

    /**
     * Creates a signature from a digest using the specified key.
     * The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault since this operation uses the private portion of the key. This operation requires the keys/sign permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<KeyOperationResult> signAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] value) {
        return signWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).map(new Func1<ServiceResponse<KeyOperationResult>, KeyOperationResult>() {
            @Override
            public KeyOperationResult call(ServiceResponse<KeyOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a signature from a digest using the specified key.
     * The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault since this operation uses the private portion of the key. This operation requires the keys/sign permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm identifier. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<ServiceResponse<KeyOperationResult>> signWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        KeySignParameters parameters = new KeySignParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.sign(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyOperationResult> clientResponse = signDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyOperationResult> signDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyOperationResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyOperationResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Verifies a signature using a specified key.
     * The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification can be performed using the public portion of the key but this operation is supported as a convenience for callers that only have a key-reference and not the public portion of the key. This operation requires the keys/verify permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyVerifyResult object if successful.
     */
    public KeyVerifyResult verify(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] digest, byte[] signature) {
        return verifyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, digest, signature).toBlocking().single().body();
    }

    /**
     * Verifies a signature using a specified key.
     * The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification can be performed using the public portion of the key but this operation is supported as a convenience for callers that only have a key-reference and not the public portion of the key. This operation requires the keys/verify permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyVerifyResult> verifyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] digest, byte[] signature, final ServiceCallback<KeyVerifyResult> serviceCallback) {
        return ServiceFuture.fromResponse(verifyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, digest, signature), serviceCallback);
    }

    /**
     * Verifies a signature using a specified key.
     * The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification can be performed using the public portion of the key but this operation is supported as a convenience for callers that only have a key-reference and not the public portion of the key. This operation requires the keys/verify permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyVerifyResult object
     */
    public Observable<KeyVerifyResult> verifyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] digest, byte[] signature) {
        return verifyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, digest, signature).map(new Func1<ServiceResponse<KeyVerifyResult>, KeyVerifyResult>() {
            @Override
            public KeyVerifyResult call(ServiceResponse<KeyVerifyResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Verifies a signature using a specified key.
     * The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification can be performed using the public portion of the key but this operation is supported as a convenience for callers that only have a key-reference and not the public portion of the key. This operation requires the keys/verify permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm The signing/verification algorithm. For more information on possible algorithm types, see JsonWebKeySignatureAlgorithm. Possible values include: 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSNULL', 'ES256', 'ES384', 'ES512', 'ES256K'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyVerifyResult object
     */
    public Observable<ServiceResponse<KeyVerifyResult>> verifyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeySignatureAlgorithm algorithm, byte[] digest, byte[] signature) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (digest == null) {
            throw new IllegalArgumentException("Parameter digest is required and cannot be null.");
        }
        if (signature == null) {
            throw new IllegalArgumentException("Parameter signature is required and cannot be null.");
        }
        KeyVerifyParameters parameters = new KeyVerifyParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withDigest(digest);
        parameters.withSignature(signature);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.verify(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyVerifyResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyVerifyResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyVerifyResult> clientResponse = verifyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyVerifyResult> verifyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyVerifyResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyVerifyResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Wraps a symmetric key using a specified key.
     * The WRAP operation supports encryption of a symmetric key using a key encryption key that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using the public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/wrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyOperationResult object if successful.
     */
    public KeyOperationResult wrapKey(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return wrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).toBlocking().single().body();
    }

    /**
     * Wraps a symmetric key using a specified key.
     * The WRAP operation supports encryption of a symmetric key using a key encryption key that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using the public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/wrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyOperationResult> wrapKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value, final ServiceCallback<KeyOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(wrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value), serviceCallback);
    }

    /**
     * Wraps a symmetric key using a specified key.
     * The WRAP operation supports encryption of a symmetric key using a key encryption key that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using the public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/wrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<KeyOperationResult> wrapKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return wrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).map(new Func1<ServiceResponse<KeyOperationResult>, KeyOperationResult>() {
            @Override
            public KeyOperationResult call(ServiceResponse<KeyOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Wraps a symmetric key using a specified key.
     * The WRAP operation supports encryption of a symmetric key using a key encryption key that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using the public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/wrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<ServiceResponse<KeyOperationResult>> wrapKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        KeyOperationsParameters parameters = new KeyOperationsParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.wrapKey(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyOperationResult> clientResponse = wrapKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyOperationResult> wrapKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyOperationResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyOperationResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Unwraps a symmetric key using the specified key that was initially used for wrapping that key.
     * The UNWRAP operation supports decryption of a symmetric key using the target key encryption key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/unwrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyOperationResult object if successful.
     */
    public KeyOperationResult unwrapKey(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return unwrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).toBlocking().single().body();
    }

    /**
     * Unwraps a symmetric key using the specified key that was initially used for wrapping that key.
     * The UNWRAP operation supports decryption of a symmetric key using the target key encryption key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/unwrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyOperationResult> unwrapKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value, final ServiceCallback<KeyOperationResult> serviceCallback) {
        return ServiceFuture.fromResponse(unwrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value), serviceCallback);
    }

    /**
     * Unwraps a symmetric key using the specified key that was initially used for wrapping that key.
     * The UNWRAP operation supports decryption of a symmetric key using the target key encryption key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/unwrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<KeyOperationResult> unwrapKeyAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        return unwrapKeyWithServiceResponseAsync(vaultBaseUrl, keyName, keyVersion, algorithm, value).map(new Func1<ServiceResponse<KeyOperationResult>, KeyOperationResult>() {
            @Override
            public KeyOperationResult call(ServiceResponse<KeyOperationResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Unwraps a symmetric key using the specified key that was initially used for wrapping that key.
     * The UNWRAP operation supports decryption of a symmetric key using the target key encryption key. This operation is the reverse of the WRAP operation. The UNWRAP operation applies to asymmetric and symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This operation requires the keys/unwrapKey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param keyVersion The version of the key.
     * @param algorithm algorithm identifier. Possible values include: 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'
     * @param value the Base64Url value
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyOperationResult object
     */
    public Observable<ServiceResponse<KeyOperationResult>> unwrapKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName, String keyVersion, JsonWebKeyEncryptionAlgorithm algorithm, byte[] value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (keyVersion == null) {
            throw new IllegalArgumentException("Parameter keyVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (algorithm == null) {
            throw new IllegalArgumentException("Parameter algorithm is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        KeyOperationsParameters parameters = new KeyOperationsParameters();
        parameters.withAlgorithm(algorithm);
        parameters.withValue(value);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.unwrapKey(keyName, keyVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyOperationResult>>>() {
                @Override
                public Observable<ServiceResponse<KeyOperationResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyOperationResult> clientResponse = unwrapKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyOperationResult> unwrapKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyOperationResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyOperationResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedKeyItem&gt; object if successful.
     */
    public PagedList<DeletedKeyItem> getDeletedKeys(final String vaultBaseUrl) {
        ServiceResponse<Page<DeletedKeyItem>> response = getDeletedKeysSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<DeletedKeyItem>(response.body()) {
            @Override
            public Page<DeletedKeyItem> nextPage(String nextPageLink) {
                return getDeletedKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedKeyItem>> getDeletedKeysAsync(final String vaultBaseUrl, final ListOperationCallback<DeletedKeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedKeysSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(String nextPageLink) {
                    return getDeletedKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<Page<DeletedKeyItem>> getDeletedKeysAsync(final String vaultBaseUrl) {
        return getDeletedKeysWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Page<DeletedKeyItem>>() {
                @Override
                public Page<DeletedKeyItem> call(ServiceResponse<Page<DeletedKeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysWithServiceResponseAsync(final String vaultBaseUrl) {
        return getDeletedKeysSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(ServiceResponse<Page<DeletedKeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedKeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedKeys(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedKeyItem>> result = getDeletedKeysDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedKeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedKeyItem&gt; object if successful.
     */
    public PagedList<DeletedKeyItem> getDeletedKeys(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<DeletedKeyItem>> response = getDeletedKeysSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<DeletedKeyItem>(response.body()) {
            @Override
            public Page<DeletedKeyItem> nextPage(String nextPageLink) {
                return getDeletedKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedKeyItem>> getDeletedKeysAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<DeletedKeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedKeysSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(String nextPageLink) {
                    return getDeletedKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<Page<DeletedKeyItem>> getDeletedKeysAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedKeysWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Page<DeletedKeyItem>>() {
                @Override
                public Page<DeletedKeyItem> call(ServiceResponse<Page<DeletedKeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedKeysSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(ServiceResponse<Page<DeletedKeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedKeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedKeys(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedKeyItem>> result = getDeletedKeysDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedKeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedKeyItem>> getDeletedKeysDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedKeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedKeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the public part of a deleted key.
     * The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedKeyBundle object if successful.
     */
    public DeletedKeyBundle getDeletedKey(String vaultBaseUrl, String keyName) {
        return getDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).toBlocking().single().body();
    }

    /**
     * Gets the public part of a deleted key.
     * The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedKeyBundle> getDeletedKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<DeletedKeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName), serviceCallback);
    }

    /**
     * Gets the public part of a deleted key.
     * The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedKeyBundle object
     */
    public Observable<DeletedKeyBundle> getDeletedKeyAsync(String vaultBaseUrl, String keyName) {
        return getDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<DeletedKeyBundle>, DeletedKeyBundle>() {
            @Override
            public DeletedKeyBundle call(ServiceResponse<DeletedKeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the public part of a deleted key.
     * The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedKeyBundle object
     */
    public Observable<ServiceResponse<DeletedKeyBundle>> getDeletedKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedKey(keyName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedKeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedKeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedKeyBundle> clientResponse = getDeletedKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedKeyBundle> getDeletedKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedKeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedKeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Permanently deletes the specified key.
     * The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void purgeDeletedKey(String vaultBaseUrl, String keyName) {
        purgeDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).toBlocking().single().body();
    }

    /**
     * Permanently deletes the specified key.
     * The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> purgeDeletedKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(purgeDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName), serviceCallback);
    }

    /**
     * Permanently deletes the specified key.
     * The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> purgeDeletedKeyAsync(String vaultBaseUrl, String keyName) {
        return purgeDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Permanently deletes the specified key.
     * The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> purgeDeletedKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.purgeDeletedKey(keyName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = purgeDeletedKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> purgeDeletedKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Void, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Recovers the deleted key to its latest version.
     * The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults. It recovers the deleted key back to its latest version under /keys. An attempt to recover an non-deleted key will return an error. Consider this the inverse of the delete operation on soft-delete enabled vaults. This operation requires the keys/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the deleted key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the KeyBundle object if successful.
     */
    public KeyBundle recoverDeletedKey(String vaultBaseUrl, String keyName) {
        return recoverDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).toBlocking().single().body();
    }

    /**
     * Recovers the deleted key to its latest version.
     * The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults. It recovers the deleted key back to its latest version under /keys. An attempt to recover an non-deleted key will return an error. Consider this the inverse of the delete operation on soft-delete enabled vaults. This operation requires the keys/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the deleted key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> recoverDeletedKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(recoverDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName), serviceCallback);
    }

    /**
     * Recovers the deleted key to its latest version.
     * The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults. It recovers the deleted key back to its latest version under /keys. An attempt to recover an non-deleted key will return an error. Consider this the inverse of the delete operation on soft-delete enabled vaults. This operation requires the keys/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the deleted key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> recoverDeletedKeyAsync(String vaultBaseUrl, String keyName) {
        return recoverDeletedKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Recovers the deleted key to its latest version.
     * The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults. It recovers the deleted key back to its latest version under /keys. An attempt to recover an non-deleted key will return an error. Consider this the inverse of the delete operation on soft-delete enabled vaults. This operation requires the keys/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the deleted key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> recoverDeletedKeyWithServiceResponseAsync(String vaultBaseUrl, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.recoverDeletedKey(keyName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = recoverDeletedKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> recoverDeletedKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<KeyBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<KeyBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle setSecret(String vaultBaseUrl, String secretName, String value) {
        return setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value).toBlocking().single().body();
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> setSecretAsync(String vaultBaseUrl, String secretName, String value, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value), serviceCallback);
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> setSecretAsync(String vaultBaseUrl, String secretName, String value) {
        return setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> setSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName, String value) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        final Map<String, String> tags = null;
        final String contentType = null;
        final SecretAttributes secretAttributes = null;
        SecretSetParameters parameters = new SecretSetParameters();
        parameters.withValue(value);
        parameters.withTags(null);
        parameters.withContentType(null);
        parameters.withSecretAttributes(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = setSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle setSecret(String vaultBaseUrl, String secretName, String value, Map<String, String> tags, String contentType, SecretAttributes secretAttributes) {
        return setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value, tags, contentType, secretAttributes).toBlocking().single().body();
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> setSecretAsync(String vaultBaseUrl, String secretName, String value, Map<String, String> tags, String contentType, SecretAttributes secretAttributes, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value, tags, contentType, secretAttributes), serviceCallback);
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> setSecretAsync(String vaultBaseUrl, String secretName, String value, Map<String, String> tags, String contentType, SecretAttributes secretAttributes) {
        return setSecretWithServiceResponseAsync(vaultBaseUrl, secretName, value, tags, contentType, secretAttributes).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Sets a secret in a specified key vault.
     * The SET operation adds a secret to the Azure Key Vault. If the named secret already exists, Azure Key Vault creates a new version of that secret. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param value The value of the secret.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> setSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName, String value, Map<String, String> tags, String contentType, SecretAttributes secretAttributes) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (value == null) {
            throw new IllegalArgumentException("Parameter value is required and cannot be null.");
        }
        Validator.validate(tags);
        Validator.validate(secretAttributes);
        SecretSetParameters parameters = new SecretSetParameters();
        parameters.withValue(value);
        parameters.withTags(tags);
        parameters.withContentType(contentType);
        parameters.withSecretAttributes(secretAttributes);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = setSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> setSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes a secret from a specified key vault.
     * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual version of a secret. This operation requires the secrets/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedSecretBundle object if successful.
     */
    public DeletedSecretBundle deleteSecret(String vaultBaseUrl, String secretName) {
        return deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Deletes a secret from a specified key vault.
     * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual version of a secret. This operation requires the secrets/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedSecretBundle> deleteSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<DeletedSecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Deletes a secret from a specified key vault.
     * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual version of a secret. This operation requires the secrets/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSecretBundle object
     */
    public Observable<DeletedSecretBundle> deleteSecretAsync(String vaultBaseUrl, String secretName) {
        return deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<DeletedSecretBundle>, DeletedSecretBundle>() {
            @Override
            public DeletedSecretBundle call(ServiceResponse<DeletedSecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a secret from a specified key vault.
     * The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied to an individual version of a secret. This operation requires the secrets/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSecretBundle object
     */
    public Observable<ServiceResponse<DeletedSecretBundle>> deleteSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedSecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedSecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedSecretBundle> clientResponse = deleteSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedSecretBundle> deleteSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedSecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedSecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle updateSecret(String vaultBaseUrl, String secretName, String secretVersion) {
        return updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion).toBlocking().single().body();
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> updateSecretAsync(String vaultBaseUrl, String secretName, String secretVersion, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion), serviceCallback);
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> updateSecretAsync(String vaultBaseUrl, String secretName, String secretVersion) {
        return updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> updateSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName, String secretVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (secretVersion == null) {
            throw new IllegalArgumentException("Parameter secretVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final String contentType = null;
        final SecretAttributes secretAttributes = null;
        final Map<String, String> tags = null;
        SecretUpdateParameters parameters = new SecretUpdateParameters();
        parameters.withContentType(null);
        parameters.withSecretAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateSecret(secretName, secretVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = updateSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle updateSecret(String vaultBaseUrl, String secretName, String secretVersion, String contentType, SecretAttributes secretAttributes, Map<String, String> tags) {
        return updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion, contentType, secretAttributes, tags).toBlocking().single().body();
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> updateSecretAsync(String vaultBaseUrl, String secretName, String secretVersion, String contentType, SecretAttributes secretAttributes, Map<String, String> tags, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion, contentType, secretAttributes, tags), serviceCallback);
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> updateSecretAsync(String vaultBaseUrl, String secretName, String secretVersion, String contentType, SecretAttributes secretAttributes, Map<String, String> tags) {
        return updateSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion, contentType, secretAttributes, tags).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     * The UPDATE operation changes specified attributes of an existing stored secret. Attributes that are not specified in the request are left unchanged. The value of a secret itself cannot be changed. This operation requires the secrets/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param contentType Type of the secret value such as a password.
     * @param secretAttributes The secret management attributes.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> updateSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName, String secretVersion, String contentType, SecretAttributes secretAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (secretVersion == null) {
            throw new IllegalArgumentException("Parameter secretVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(secretAttributes);
        Validator.validate(tags);
        SecretUpdateParameters parameters = new SecretUpdateParameters();
        parameters.withContentType(contentType);
        parameters.withSecretAttributes(secretAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateSecret(secretName, secretVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = updateSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> updateSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Get a specified secret from a given key vault.
     * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle getSecret(String vaultBaseUrl, String secretName, String secretVersion) {
        return getSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion).toBlocking().single().body();
    }

    /**
     * Get a specified secret from a given key vault.
     * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> getSecretAsync(String vaultBaseUrl, String secretName, String secretVersion, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion), serviceCallback);
    }

    /**
     * Get a specified secret from a given key vault.
     * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> getSecretAsync(String vaultBaseUrl, String secretName, String secretVersion) {
        return getSecretWithServiceResponseAsync(vaultBaseUrl, secretName, secretVersion).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Get a specified secret from a given key vault.
     * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param secretVersion The version of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> getSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName, String secretVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (secretVersion == null) {
            throw new IllegalArgumentException("Parameter secretVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSecret(secretName, secretVersion, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = getSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> getSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecrets(final String vaultBaseUrl) {
        ServiceResponse<Page<SecretItem>> response = getSecretsSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretsAsync(final String vaultBaseUrl, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretsSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretsAsync(final String vaultBaseUrl) {
        return getSecretsWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsWithServiceResponseAsync(final String vaultBaseUrl) {
        return getSecretsSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSecrets(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecrets(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<SecretItem>> response = getSecretsSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretsAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretsSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretsAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getSecretsWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getSecretsSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSecrets(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SecretItem>> getSecretsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecretVersions(final String vaultBaseUrl, final String secretName) {
        ServiceResponse<Page<SecretItem>> response = getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretVersionsAsync(final String vaultBaseUrl, final String secretName, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretVersionsAsync(final String vaultBaseUrl, final String secretName) {
        return getSecretVersionsWithServiceResponseAsync(vaultBaseUrl, secretName)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String secretName) {
        return getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsSinglePageAsync(final String vaultBaseUrl, final String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSecretVersions(secretName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecretVersions(final String vaultBaseUrl, final String secretName, final Integer maxresults) {
        ServiceResponse<Page<SecretItem>> response = getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName, maxresults).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretVersionsAsync(final String vaultBaseUrl, final String secretName, final Integer maxresults, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretVersionsAsync(final String vaultBaseUrl, final String secretName, final Integer maxresults) {
        return getSecretVersionsWithServiceResponseAsync(vaultBaseUrl, secretName, maxresults)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String secretName, final Integer maxresults) {
        return getSecretVersionsSinglePageAsync(vaultBaseUrl, secretName, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param maxresults Maximum number of results to return in a page. If not specified, the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsSinglePageAsync(final String vaultBaseUrl, final String secretName, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSecretVersions(secretName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SecretItem>> getSecretVersionsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSecretItem&gt; object if successful.
     */
    public PagedList<DeletedSecretItem> getDeletedSecrets(final String vaultBaseUrl) {
        ServiceResponse<Page<DeletedSecretItem>> response = getDeletedSecretsSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<DeletedSecretItem>(response.body()) {
            @Override
            public Page<DeletedSecretItem> nextPage(String nextPageLink) {
                return getDeletedSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSecretItem>> getDeletedSecretsAsync(final String vaultBaseUrl, final ListOperationCallback<DeletedSecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSecretsSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(String nextPageLink) {
                    return getDeletedSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<Page<DeletedSecretItem>> getDeletedSecretsAsync(final String vaultBaseUrl) {
        return getDeletedSecretsWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Page<DeletedSecretItem>>() {
                @Override
                public Page<DeletedSecretItem> call(ServiceResponse<Page<DeletedSecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsWithServiceResponseAsync(final String vaultBaseUrl) {
        return getDeletedSecretsSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(ServiceResponse<Page<DeletedSecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSecrets(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSecretItem>> result = getDeletedSecretsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSecretItem&gt; object if successful.
     */
    public PagedList<DeletedSecretItem> getDeletedSecrets(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<DeletedSecretItem>> response = getDeletedSecretsSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<DeletedSecretItem>(response.body()) {
            @Override
            public Page<DeletedSecretItem> nextPage(String nextPageLink) {
                return getDeletedSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSecretItem>> getDeletedSecretsAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<DeletedSecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSecretsSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(String nextPageLink) {
                    return getDeletedSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<Page<DeletedSecretItem>> getDeletedSecretsAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedSecretsWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Page<DeletedSecretItem>>() {
                @Override
                public Page<DeletedSecretItem> call(ServiceResponse<Page<DeletedSecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedSecretsSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(ServiceResponse<Page<DeletedSecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSecrets(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSecretItem>> result = getDeletedSecretsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedSecretItem>> getDeletedSecretsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedSecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedSecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the specified deleted secret.
     * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedSecretBundle object if successful.
     */
    public DeletedSecretBundle getDeletedSecret(String vaultBaseUrl, String secretName) {
        return getDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Gets the specified deleted secret.
     * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedSecretBundle> getDeletedSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<DeletedSecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Gets the specified deleted secret.
     * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSecretBundle object
     */
    public Observable<DeletedSecretBundle> getDeletedSecretAsync(String vaultBaseUrl, String secretName) {
        return getDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<DeletedSecretBundle>, DeletedSecretBundle>() {
            @Override
            public DeletedSecretBundle call(ServiceResponse<DeletedSecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the specified deleted secret.
     * The Get Deleted Secret operation returns the specified deleted secret along with its attributes. This operation requires the secrets/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSecretBundle object
     */
    public Observable<ServiceResponse<DeletedSecretBundle>> getDeletedSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedSecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedSecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedSecretBundle> clientResponse = getDeletedSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedSecretBundle> getDeletedSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedSecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedSecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Permanently deletes the specified secret.
     * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void purgeDeletedSecret(String vaultBaseUrl, String secretName) {
        purgeDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Permanently deletes the specified secret.
     * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> purgeDeletedSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(purgeDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Permanently deletes the specified secret.
     * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> purgeDeletedSecretAsync(String vaultBaseUrl, String secretName) {
        return purgeDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Permanently deletes the specified secret.
     * The purge deleted secret operation removes the secret permanently, without the possibility of recovery. This operation can only be enabled on a soft-delete enabled vault. This operation requires the secrets/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> purgeDeletedSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.purgeDeletedSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = purgeDeletedSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> purgeDeletedSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Void, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Recovers the deleted secret to the latest version.
     * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the secrets/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the deleted secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle recoverDeletedSecret(String vaultBaseUrl, String secretName) {
        return recoverDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Recovers the deleted secret to the latest version.
     * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the secrets/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the deleted secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> recoverDeletedSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(recoverDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Recovers the deleted secret to the latest version.
     * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the secrets/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the deleted secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> recoverDeletedSecretAsync(String vaultBaseUrl, String secretName) {
        return recoverDeletedSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Recovers the deleted secret to the latest version.
     * Recovers the deleted secret in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the secrets/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the deleted secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> recoverDeletedSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.recoverDeletedSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = recoverDeletedSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> recoverDeletedSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Backs up the specified secret.
     * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be downloaded. This operation requires the secrets/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the BackupSecretResult object if successful.
     */
    public BackupSecretResult backupSecret(String vaultBaseUrl, String secretName) {
        return backupSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Backs up the specified secret.
     * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be downloaded. This operation requires the secrets/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<BackupSecretResult> backupSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<BackupSecretResult> serviceCallback) {
        return ServiceFuture.fromResponse(backupSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Backs up the specified secret.
     * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be downloaded. This operation requires the secrets/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupSecretResult object
     */
    public Observable<BackupSecretResult> backupSecretAsync(String vaultBaseUrl, String secretName) {
        return backupSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<BackupSecretResult>, BackupSecretResult>() {
            @Override
            public BackupSecretResult call(ServiceResponse<BackupSecretResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Backs up the specified secret.
     * Requests that a backup of the specified secret be downloaded to the client. All versions of the secret will be downloaded. This operation requires the secrets/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupSecretResult object
     */
    public Observable<ServiceResponse<BackupSecretResult>> backupSecretWithServiceResponseAsync(String vaultBaseUrl, String secretName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (secretName == null) {
            throw new IllegalArgumentException("Parameter secretName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.backupSecret(secretName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<BackupSecretResult>>>() {
                @Override
                public Observable<ServiceResponse<BackupSecretResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<BackupSecretResult> clientResponse = backupSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<BackupSecretResult> backupSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<BackupSecretResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<BackupSecretResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Restores a backed up secret to a vault.
     * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretBundleBackup The backup blob associated with a secret bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SecretBundle object if successful.
     */
    public SecretBundle restoreSecret(String vaultBaseUrl, byte[] secretBundleBackup) {
        return restoreSecretWithServiceResponseAsync(vaultBaseUrl, secretBundleBackup).toBlocking().single().body();
    }

    /**
     * Restores a backed up secret to a vault.
     * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretBundleBackup The backup blob associated with a secret bundle.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> restoreSecretAsync(String vaultBaseUrl, byte[] secretBundleBackup, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(restoreSecretWithServiceResponseAsync(vaultBaseUrl, secretBundleBackup), serviceCallback);
    }

    /**
     * Restores a backed up secret to a vault.
     * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretBundleBackup The backup blob associated with a secret bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> restoreSecretAsync(String vaultBaseUrl, byte[] secretBundleBackup) {
        return restoreSecretWithServiceResponseAsync(vaultBaseUrl, secretBundleBackup).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Restores a backed up secret to a vault.
     * Restores a backed up secret, and all its versions, to a vault. This operation requires the secrets/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretBundleBackup The backup blob associated with a secret bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> restoreSecretWithServiceResponseAsync(String vaultBaseUrl, byte[] secretBundleBackup) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (secretBundleBackup == null) {
            throw new IllegalArgumentException("Parameter secretBundleBackup is required and cannot be null.");
        }
        SecretRestoreParameters parameters = new SecretRestoreParameters();
        parameters.withSecretBundleBackup(secretBundleBackup);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.restoreSecret(this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = restoreSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> restoreSecretDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SecretBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SecretBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificates(final String vaultBaseUrl) {
        ServiceResponse<Page<CertificateItem>> response = getCertificatesSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificatesSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl) {
        return getCertificatesWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesWithServiceResponseAsync(final String vaultBaseUrl) {
        return getCertificatesSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        final Boolean includePending = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificates(maxresults, includePending, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificatesDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificates(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        ServiceResponse<Page<CertificateItem>> response = getCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        return getCertificatesWithServiceResponseAsync(vaultBaseUrl, maxresults, includePending)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        return getCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesSinglePageAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificates(maxresults, includePending, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificatesDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateItem>> getCertificatesDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes a certificate from a specified key vault.
     * Deletes all versions of a certificate object along with its associated policy. Delete certificate cannot be used to remove individual versions of a certificate object. This operation requires the certificates/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedCertificateBundle object if successful.
     */
    public DeletedCertificateBundle deleteCertificate(String vaultBaseUrl, String certificateName) {
        return deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Deletes a certificate from a specified key vault.
     * Deletes all versions of a certificate object along with its associated policy. Delete certificate cannot be used to remove individual versions of a certificate object. This operation requires the certificates/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedCertificateBundle> deleteCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<DeletedCertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Deletes a certificate from a specified key vault.
     * Deletes all versions of a certificate object along with its associated policy. Delete certificate cannot be used to remove individual versions of a certificate object. This operation requires the certificates/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedCertificateBundle object
     */
    public Observable<DeletedCertificateBundle> deleteCertificateAsync(String vaultBaseUrl, String certificateName) {
        return deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<DeletedCertificateBundle>, DeletedCertificateBundle>() {
            @Override
            public DeletedCertificateBundle call(ServiceResponse<DeletedCertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a certificate from a specified key vault.
     * Deletes all versions of a certificate object along with its associated policy. Delete certificate cannot be used to remove individual versions of a certificate object. This operation requires the certificates/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedCertificateBundle object
     */
    public Observable<ServiceResponse<DeletedCertificateBundle>> deleteCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedCertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedCertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedCertificateBundle> clientResponse = deleteCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedCertificateBundle> deleteCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedCertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedCertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Sets the certificate contacts for the specified key vault.
     * Sets the certificate contacts for the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Contacts object if successful.
     */
    public Contacts setCertificateContacts(String vaultBaseUrl, Contacts contacts) {
        return setCertificateContactsWithServiceResponseAsync(vaultBaseUrl, contacts).toBlocking().single().body();
    }

    /**
     * Sets the certificate contacts for the specified key vault.
     * Sets the certificate contacts for the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Contacts> setCertificateContactsAsync(String vaultBaseUrl, Contacts contacts, final ServiceCallback<Contacts> serviceCallback) {
        return ServiceFuture.fromResponse(setCertificateContactsWithServiceResponseAsync(vaultBaseUrl, contacts), serviceCallback);
    }

    /**
     * Sets the certificate contacts for the specified key vault.
     * Sets the certificate contacts for the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<Contacts> setCertificateContactsAsync(String vaultBaseUrl, Contacts contacts) {
        return setCertificateContactsWithServiceResponseAsync(vaultBaseUrl, contacts).map(new Func1<ServiceResponse<Contacts>, Contacts>() {
            @Override
            public Contacts call(ServiceResponse<Contacts> response) {
                return response.body();
            }
        });
    }

    /**
     * Sets the certificate contacts for the specified key vault.
     * Sets the certificate contacts for the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<ServiceResponse<Contacts>> setCertificateContactsWithServiceResponseAsync(String vaultBaseUrl, Contacts contacts) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (contacts == null) {
            throw new IllegalArgumentException("Parameter contacts is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(contacts);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setCertificateContacts(contacts, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Contacts>>>() {
                @Override
                public Observable<ServiceResponse<Contacts>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Contacts> clientResponse = setCertificateContactsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Contacts> setCertificateContactsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Contacts, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<Contacts>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the certificate contacts for a specified key vault.
     * The GetCertificateContacts operation returns the set of certificate contact resources in the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Contacts object if successful.
     */
    public Contacts getCertificateContacts(String vaultBaseUrl) {
        return getCertificateContactsWithServiceResponseAsync(vaultBaseUrl).toBlocking().single().body();
    }

    /**
     * Lists the certificate contacts for a specified key vault.
     * The GetCertificateContacts operation returns the set of certificate contact resources in the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Contacts> getCertificateContactsAsync(String vaultBaseUrl, final ServiceCallback<Contacts> serviceCallback) {
        return ServiceFuture.fromResponse(getCertificateContactsWithServiceResponseAsync(vaultBaseUrl), serviceCallback);
    }

    /**
     * Lists the certificate contacts for a specified key vault.
     * The GetCertificateContacts operation returns the set of certificate contact resources in the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<Contacts> getCertificateContactsAsync(String vaultBaseUrl) {
        return getCertificateContactsWithServiceResponseAsync(vaultBaseUrl).map(new Func1<ServiceResponse<Contacts>, Contacts>() {
            @Override
            public Contacts call(ServiceResponse<Contacts> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists the certificate contacts for a specified key vault.
     * The GetCertificateContacts operation returns the set of certificate contact resources in the specified key vault. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<ServiceResponse<Contacts>> getCertificateContactsWithServiceResponseAsync(String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateContacts(this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Contacts>>>() {
                @Override
                public Observable<ServiceResponse<Contacts>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Contacts> clientResponse = getCertificateContactsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Contacts> getCertificateContactsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Contacts, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<Contacts>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes the certificate contacts for a specified key vault.
     * Deletes the certificate contacts for a specified key vault certificate. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Contacts object if successful.
     */
    public Contacts deleteCertificateContacts(String vaultBaseUrl) {
        return deleteCertificateContactsWithServiceResponseAsync(vaultBaseUrl).toBlocking().single().body();
    }

    /**
     * Deletes the certificate contacts for a specified key vault.
     * Deletes the certificate contacts for a specified key vault certificate. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Contacts> deleteCertificateContactsAsync(String vaultBaseUrl, final ServiceCallback<Contacts> serviceCallback) {
        return ServiceFuture.fromResponse(deleteCertificateContactsWithServiceResponseAsync(vaultBaseUrl), serviceCallback);
    }

    /**
     * Deletes the certificate contacts for a specified key vault.
     * Deletes the certificate contacts for a specified key vault certificate. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<Contacts> deleteCertificateContactsAsync(String vaultBaseUrl) {
        return deleteCertificateContactsWithServiceResponseAsync(vaultBaseUrl).map(new Func1<ServiceResponse<Contacts>, Contacts>() {
            @Override
            public Contacts call(ServiceResponse<Contacts> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the certificate contacts for a specified key vault.
     * Deletes the certificate contacts for a specified key vault certificate. This operation requires the certificates/managecontacts permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Contacts object
     */
    public Observable<ServiceResponse<Contacts>> deleteCertificateContactsWithServiceResponseAsync(String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteCertificateContacts(this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Contacts>>>() {
                @Override
                public Observable<ServiceResponse<Contacts>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Contacts> clientResponse = deleteCertificateContactsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Contacts> deleteCertificateContactsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Contacts, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<Contacts>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateIssuerItem&gt; object if successful.
     */
    public PagedList<CertificateIssuerItem> getCertificateIssuers(final String vaultBaseUrl) {
        ServiceResponse<Page<CertificateIssuerItem>> response = getCertificateIssuersSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<CertificateIssuerItem>(response.body()) {
            @Override
            public Page<CertificateIssuerItem> nextPage(String nextPageLink) {
                return getCertificateIssuersNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateIssuerItem>> getCertificateIssuersAsync(final String vaultBaseUrl, final ListOperationCallback<CertificateIssuerItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateIssuersSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(String nextPageLink) {
                    return getCertificateIssuersNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<Page<CertificateIssuerItem>> getCertificateIssuersAsync(final String vaultBaseUrl) {
        return getCertificateIssuersWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Page<CertificateIssuerItem>>() {
                @Override
                public Page<CertificateIssuerItem> call(ServiceResponse<Page<CertificateIssuerItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersWithServiceResponseAsync(final String vaultBaseUrl) {
        return getCertificateIssuersSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(ServiceResponse<Page<CertificateIssuerItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateIssuersNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateIssuerItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateIssuers(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateIssuerItem>> result = getCertificateIssuersDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateIssuerItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateIssuerItem&gt; object if successful.
     */
    public PagedList<CertificateIssuerItem> getCertificateIssuers(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<CertificateIssuerItem>> response = getCertificateIssuersSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<CertificateIssuerItem>(response.body()) {
            @Override
            public Page<CertificateIssuerItem> nextPage(String nextPageLink) {
                return getCertificateIssuersNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateIssuerItem>> getCertificateIssuersAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<CertificateIssuerItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateIssuersSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(String nextPageLink) {
                    return getCertificateIssuersNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<Page<CertificateIssuerItem>> getCertificateIssuersAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getCertificateIssuersWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Page<CertificateIssuerItem>>() {
                @Override
                public Page<CertificateIssuerItem> call(ServiceResponse<Page<CertificateIssuerItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getCertificateIssuersSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(ServiceResponse<Page<CertificateIssuerItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateIssuersNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateIssuerItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateIssuers(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateIssuerItem>> result = getCertificateIssuersDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateIssuerItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateIssuerItem>> getCertificateIssuersDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateIssuerItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateIssuerItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle setCertificateIssuer(String vaultBaseUrl, String issuerName, String provider) {
        return setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider).toBlocking().single().body();
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> setCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider), serviceCallback);
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> setCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider) {
        return setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> setCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName, String provider) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (provider == null) {
            throw new IllegalArgumentException("Parameter provider is required and cannot be null.");
        }
        final IssuerCredentials credentials = null;
        final OrganizationDetails organizationDetails = null;
        final IssuerAttributes attributes = null;
        CertificateIssuerSetParameters parameter = new CertificateIssuerSetParameters();
        parameter.withProvider(provider);
        parameter.withCredentials(null);
        parameter.withOrganizationDetails(null);
        parameter.withAttributes(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameter, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = setCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle setCertificateIssuer(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        return setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes).toBlocking().single().body();
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> setCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes), serviceCallback);
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> setCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        return setCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Sets the specified certificate issuer.
     * The SetCertificateIssuer operation adds or updates the specified certificate issuer. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> setCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (provider == null) {
            throw new IllegalArgumentException("Parameter provider is required and cannot be null.");
        }
        Validator.validate(credentials);
        Validator.validate(organizationDetails);
        Validator.validate(attributes);
        CertificateIssuerSetParameters parameter = new CertificateIssuerSetParameters();
        parameter.withProvider(provider);
        parameter.withCredentials(credentials);
        parameter.withOrganizationDetails(organizationDetails);
        parameter.withAttributes(attributes);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameter, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = setCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<IssuerBundle> setCertificateIssuerDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<IssuerBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<IssuerBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle updateCertificateIssuer(String vaultBaseUrl, String issuerName) {
        return updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).toBlocking().single().body();
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> updateCertificateIssuerAsync(String vaultBaseUrl, String issuerName, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName), serviceCallback);
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> updateCertificateIssuerAsync(String vaultBaseUrl, String issuerName) {
        return updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> updateCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final String provider = null;
        final IssuerCredentials credentials = null;
        final OrganizationDetails organizationDetails = null;
        final IssuerAttributes attributes = null;
        CertificateIssuerUpdateParameters parameter = new CertificateIssuerUpdateParameters();
        parameter.withProvider(null);
        parameter.withCredentials(null);
        parameter.withOrganizationDetails(null);
        parameter.withAttributes(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameter, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = updateCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle updateCertificateIssuer(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        return updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes).toBlocking().single().body();
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> updateCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes), serviceCallback);
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> updateCertificateIssuerAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        return updateCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName, provider, credentials, organizationDetails, attributes).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified certificate issuer.
     * The UpdateCertificateIssuer operation performs an update on the specified certificate issuer entity. This operation requires the certificates/setissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @param credentials The credentials to be used for the issuer.
     * @param organizationDetails Details of the organization as provided to the issuer.
     * @param attributes Attributes of the issuer object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> updateCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName, String provider, IssuerCredentials credentials, OrganizationDetails organizationDetails, IssuerAttributes attributes) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(credentials);
        Validator.validate(organizationDetails);
        Validator.validate(attributes);
        CertificateIssuerUpdateParameters parameter = new CertificateIssuerUpdateParameters();
        parameter.withProvider(provider);
        parameter.withCredentials(credentials);
        parameter.withOrganizationDetails(organizationDetails);
        parameter.withAttributes(attributes);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameter, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = updateCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<IssuerBundle> updateCertificateIssuerDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<IssuerBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<IssuerBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the specified certificate issuer.
     * The GetCertificateIssuer operation returns the specified certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle getCertificateIssuer(String vaultBaseUrl, String issuerName) {
        return getCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).toBlocking().single().body();
    }

    /**
     * Lists the specified certificate issuer.
     * The GetCertificateIssuer operation returns the specified certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> getCertificateIssuerAsync(String vaultBaseUrl, String issuerName, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName), serviceCallback);
    }

    /**
     * Lists the specified certificate issuer.
     * The GetCertificateIssuer operation returns the specified certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> getCertificateIssuerAsync(String vaultBaseUrl, String issuerName) {
        return getCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists the specified certificate issuer.
     * The GetCertificateIssuer operation returns the specified certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> getCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = getCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<IssuerBundle> getCertificateIssuerDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<IssuerBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<IssuerBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes the specified certificate issuer.
     * The DeleteCertificateIssuer operation permanently removes the specified certificate issuer from the vault. This operation requires the certificates/manageissuers/deleteissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the IssuerBundle object if successful.
     */
    public IssuerBundle deleteCertificateIssuer(String vaultBaseUrl, String issuerName) {
        return deleteCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).toBlocking().single().body();
    }

    /**
     * Deletes the specified certificate issuer.
     * The DeleteCertificateIssuer operation permanently removes the specified certificate issuer from the vault. This operation requires the certificates/manageissuers/deleteissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<IssuerBundle> deleteCertificateIssuerAsync(String vaultBaseUrl, String issuerName, final ServiceCallback<IssuerBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName), serviceCallback);
    }

    /**
     * Deletes the specified certificate issuer.
     * The DeleteCertificateIssuer operation permanently removes the specified certificate issuer from the vault. This operation requires the certificates/manageissuers/deleteissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<IssuerBundle> deleteCertificateIssuerAsync(String vaultBaseUrl, String issuerName) {
        return deleteCertificateIssuerWithServiceResponseAsync(vaultBaseUrl, issuerName).map(new Func1<ServiceResponse<IssuerBundle>, IssuerBundle>() {
            @Override
            public IssuerBundle call(ServiceResponse<IssuerBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the specified certificate issuer.
     * The DeleteCertificateIssuer operation permanently removes the specified certificate issuer from the vault. This operation requires the certificates/manageissuers/deleteissuers permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the IssuerBundle object
     */
    public Observable<ServiceResponse<IssuerBundle>> deleteCertificateIssuerWithServiceResponseAsync(String vaultBaseUrl, String issuerName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (issuerName == null) {
            throw new IllegalArgumentException("Parameter issuerName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteCertificateIssuer(issuerName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<IssuerBundle>>>() {
                @Override
                public Observable<ServiceResponse<IssuerBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<IssuerBundle> clientResponse = deleteCertificateIssuerDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<IssuerBundle> deleteCertificateIssuerDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<IssuerBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<IssuerBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation createCertificate(String vaultBaseUrl, String certificateName) {
        return createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateOperation> createCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificateOperation> serviceCallback) {
        return ServiceFuture.fromResponse(createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<CertificateOperation> createCertificateAsync(String vaultBaseUrl, String certificateName) {
        return createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificateOperation>, CertificateOperation>() {
            @Override
            public CertificateOperation call(ServiceResponse<CertificateOperation> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<ServiceResponse<CertificateOperation>> createCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final CertificatePolicy certificatePolicy = null;
        final CertificateAttributes certificateAttributes = null;
        final Map<String, String> tags = null;
        CertificateCreateParameters parameters = new CertificateCreateParameters();
        parameters.withCertificatePolicy(null);
        parameters.withCertificateAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.createCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateOperation>>>() {
                @Override
                public Observable<ServiceResponse<CertificateOperation>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateOperation> clientResponse = createCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation createCertificate(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy, certificateAttributes, tags).toBlocking().single().body();
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateOperation> createCertificateAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags, final ServiceCallback<CertificateOperation> serviceCallback) {
        return ServiceFuture.fromResponse(createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy, certificateAttributes, tags), serviceCallback);
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<CertificateOperation> createCertificateAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return createCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy, certificateAttributes, tags).map(new Func1<ServiceResponse<CertificateOperation>, CertificateOperation>() {
            @Override
            public CertificateOperation call(ServiceResponse<CertificateOperation> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates a new certificate.
     * If this is the first version, the certificate resource is created. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<ServiceResponse<CertificateOperation>> createCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificatePolicy);
        Validator.validate(certificateAttributes);
        Validator.validate(tags);
        CertificateCreateParameters parameters = new CertificateCreateParameters();
        parameters.withCertificatePolicy(certificatePolicy);
        parameters.withCertificateAttributes(certificateAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.createCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateOperation>>>() {
                @Override
                public Observable<ServiceResponse<CertificateOperation>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateOperation> clientResponse = createCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateOperation> createCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateOperation, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(202, new TypeToken<CertificateOperation>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle importCertificate(String vaultBaseUrl, String certificateName, String base64EncodedCertificate) {
        return importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate).toBlocking().single().body();
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> importCertificateAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate), serviceCallback);
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> importCertificateAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate) {
        return importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> importCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (base64EncodedCertificate == null) {
            throw new IllegalArgumentException("Parameter base64EncodedCertificate is required and cannot be null.");
        }
        final String password = null;
        final CertificatePolicy certificatePolicy = null;
        final CertificateAttributes certificateAttributes = null;
        final Map<String, String> tags = null;
        CertificateImportParameters parameters = new CertificateImportParameters();
        parameters.withBase64EncodedCertificate(base64EncodedCertificate);
        parameters.withPassword(null);
        parameters.withCertificatePolicy(null);
        parameters.withCertificateAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.importCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = importCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @param password If the private key in base64EncodedCertificate is encrypted, the password used for encryption.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle importCertificate(String vaultBaseUrl, String certificateName, String base64EncodedCertificate, String password, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate, password, certificatePolicy, certificateAttributes, tags).toBlocking().single().body();
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @param password If the private key in base64EncodedCertificate is encrypted, the password used for encryption.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> importCertificateAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate, String password, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate, password, certificatePolicy, certificateAttributes, tags), serviceCallback);
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @param password If the private key in base64EncodedCertificate is encrypted, the password used for encryption.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> importCertificateAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate, String password, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return importCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, base64EncodedCertificate, password, certificatePolicy, certificateAttributes, tags).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Imports a certificate into a specified key vault.
     * Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. This operation requires the certificates/import permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param base64EncodedCertificate Base64 encoded representation of the certificate object to import. This certificate needs to contain the private key.
     * @param password If the private key in base64EncodedCertificate is encrypted, the password used for encryption.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> importCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, String base64EncodedCertificate, String password, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (base64EncodedCertificate == null) {
            throw new IllegalArgumentException("Parameter base64EncodedCertificate is required and cannot be null.");
        }
        Validator.validate(certificatePolicy);
        Validator.validate(certificateAttributes);
        Validator.validate(tags);
        CertificateImportParameters parameters = new CertificateImportParameters();
        parameters.withBase64EncodedCertificate(base64EncodedCertificate);
        parameters.withPassword(password);
        parameters.withCertificatePolicy(certificatePolicy);
        parameters.withCertificateAttributes(certificateAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.importCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = importCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> importCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificateVersions(final String vaultBaseUrl, final String certificateName) {
        ServiceResponse<Page<CertificateItem>> response = getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificateVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificateVersionsAsync(final String vaultBaseUrl, final String certificateName, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificateVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificateVersionsAsync(final String vaultBaseUrl, final String certificateName) {
        return getCertificateVersionsWithServiceResponseAsync(vaultBaseUrl, certificateName)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String certificateName) {
        return getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsSinglePageAsync(final String vaultBaseUrl, final String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateVersions(certificateName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificateVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificateVersions(final String vaultBaseUrl, final String certificateName, final Integer maxresults) {
        ServiceResponse<Page<CertificateItem>> response = getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName, maxresults).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificateVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificateVersionsAsync(final String vaultBaseUrl, final String certificateName, final Integer maxresults, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificateVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificateVersionsAsync(final String vaultBaseUrl, final String certificateName, final Integer maxresults) {
        return getCertificateVersionsWithServiceResponseAsync(vaultBaseUrl, certificateName, maxresults)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsWithServiceResponseAsync(final String vaultBaseUrl, final String certificateName, final Integer maxresults) {
        return getCertificateVersionsSinglePageAsync(vaultBaseUrl, certificateName, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsSinglePageAsync(final String vaultBaseUrl, final String certificateName, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateVersions(certificateName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificateVersionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateItem>> getCertificateVersionsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the policy for a certificate.
     * The GetCertificatePolicy operation returns the specified certificate policy resources in the specified key vault. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificatePolicy object if successful.
     */
    public CertificatePolicy getCertificatePolicy(String vaultBaseUrl, String certificateName) {
        return getCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Lists the policy for a certificate.
     * The GetCertificatePolicy operation returns the specified certificate policy resources in the specified key vault. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificatePolicy> getCertificatePolicyAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificatePolicy> serviceCallback) {
        return ServiceFuture.fromResponse(getCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Lists the policy for a certificate.
     * The GetCertificatePolicy operation returns the specified certificate policy resources in the specified key vault. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificatePolicy object
     */
    public Observable<CertificatePolicy> getCertificatePolicyAsync(String vaultBaseUrl, String certificateName) {
        return getCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificatePolicy>, CertificatePolicy>() {
            @Override
            public CertificatePolicy call(ServiceResponse<CertificatePolicy> response) {
                return response.body();
            }
        });
    }

    /**
     * Lists the policy for a certificate.
     * The GetCertificatePolicy operation returns the specified certificate policy resources in the specified key vault. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificatePolicy object
     */
    public Observable<ServiceResponse<CertificatePolicy>> getCertificatePolicyWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificatePolicy(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificatePolicy>>>() {
                @Override
                public Observable<ServiceResponse<CertificatePolicy>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificatePolicy> clientResponse = getCertificatePolicyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificatePolicy> getCertificatePolicyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificatePolicy, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificatePolicy>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the policy for a certificate.
     * Set specified members in the certificate policy. Leave others as null. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificatePolicy The policy for the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificatePolicy object if successful.
     */
    public CertificatePolicy updateCertificatePolicy(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy) {
        return updateCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy).toBlocking().single().body();
    }

    /**
     * Updates the policy for a certificate.
     * Set specified members in the certificate policy. Leave others as null. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificatePolicy The policy for the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificatePolicy> updateCertificatePolicyAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy, final ServiceCallback<CertificatePolicy> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy), serviceCallback);
    }

    /**
     * Updates the policy for a certificate.
     * Set specified members in the certificate policy. Leave others as null. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificatePolicy The policy for the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificatePolicy object
     */
    public Observable<CertificatePolicy> updateCertificatePolicyAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy) {
        return updateCertificatePolicyWithServiceResponseAsync(vaultBaseUrl, certificateName, certificatePolicy).map(new Func1<ServiceResponse<CertificatePolicy>, CertificatePolicy>() {
            @Override
            public CertificatePolicy call(ServiceResponse<CertificatePolicy> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the policy for a certificate.
     * Set specified members in the certificate policy. Leave others as null. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificatePolicy The policy for the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificatePolicy object
     */
    public Observable<ServiceResponse<CertificatePolicy>> updateCertificatePolicyWithServiceResponseAsync(String vaultBaseUrl, String certificateName, CertificatePolicy certificatePolicy) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (certificatePolicy == null) {
            throw new IllegalArgumentException("Parameter certificatePolicy is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificatePolicy);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificatePolicy(certificateName, certificatePolicy, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificatePolicy>>>() {
                @Override
                public Observable<ServiceResponse<CertificatePolicy>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificatePolicy> clientResponse = updateCertificatePolicyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificatePolicy> updateCertificatePolicyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificatePolicy, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificatePolicy>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle updateCertificate(String vaultBaseUrl, String certificateName, String certificateVersion) {
        return updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> updateCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> updateCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion) {
        return updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> updateCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, String certificateVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (certificateVersion == null) {
            throw new IllegalArgumentException("Parameter certificateVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final CertificatePolicy certificatePolicy = null;
        final CertificateAttributes certificateAttributes = null;
        final Map<String, String> tags = null;
        CertificateUpdateParameters parameters = new CertificateUpdateParameters();
        parameters.withCertificatePolicy(null);
        parameters.withCertificateAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificate(certificateName, certificateVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = updateCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle updateCertificate(String vaultBaseUrl, String certificateName, String certificateVersion, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion, certificatePolicy, certificateAttributes, tags).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> updateCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion, certificatePolicy, certificateAttributes, tags), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> updateCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return updateCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion, certificatePolicy, certificateAttributes, tags).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given certificate.
     * The UpdateCertificate operation applies the specified update on the given certificate; the only elements updated are the certificate's attributes. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given key vault.
     * @param certificateVersion The version of the certificate.
     * @param certificatePolicy The management policy for the certificate.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> updateCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, String certificateVersion, CertificatePolicy certificatePolicy, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (certificateVersion == null) {
            throw new IllegalArgumentException("Parameter certificateVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificatePolicy);
        Validator.validate(certificateAttributes);
        Validator.validate(tags);
        CertificateUpdateParameters parameters = new CertificateUpdateParameters();
        parameters.withCertificatePolicy(certificatePolicy);
        parameters.withCertificateAttributes(certificateAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificate(certificateName, certificateVersion, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = updateCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> updateCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets information about a certificate.
     * Gets information about a specific certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle getCertificate(String vaultBaseUrl, String certificateName, String certificateVersion) {
        return getCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion).toBlocking().single().body();
    }

    /**
     * Gets information about a certificate.
     * Gets information about a specific certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificateVersion The version of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> getCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion), serviceCallback);
    }

    /**
     * Gets information about a certificate.
     * Gets information about a specific certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> getCertificateAsync(String vaultBaseUrl, String certificateName, String certificateVersion) {
        return getCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, certificateVersion).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about a certificate.
     * Gets information about a specific certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in the given vault.
     * @param certificateVersion The version of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> getCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, String certificateVersion) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (certificateVersion == null) {
            throw new IllegalArgumentException("Parameter certificateVersion is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificate(certificateName, certificateVersion, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = getCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> getCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates a certificate operation.
     * Updates a certificate creation operation that is already in progress. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param cancellationRequested Indicates if cancellation was requested on the certificate operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation updateCertificateOperation(String vaultBaseUrl, String certificateName, boolean cancellationRequested) {
        return updateCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName, cancellationRequested).toBlocking().single().body();
    }

    /**
     * Updates a certificate operation.
     * Updates a certificate creation operation that is already in progress. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param cancellationRequested Indicates if cancellation was requested on the certificate operation.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateOperation> updateCertificateOperationAsync(String vaultBaseUrl, String certificateName, boolean cancellationRequested, final ServiceCallback<CertificateOperation> serviceCallback) {
        return ServiceFuture.fromResponse(updateCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName, cancellationRequested), serviceCallback);
    }

    /**
     * Updates a certificate operation.
     * Updates a certificate creation operation that is already in progress. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param cancellationRequested Indicates if cancellation was requested on the certificate operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<CertificateOperation> updateCertificateOperationAsync(String vaultBaseUrl, String certificateName, boolean cancellationRequested) {
        return updateCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName, cancellationRequested).map(new Func1<ServiceResponse<CertificateOperation>, CertificateOperation>() {
            @Override
            public CertificateOperation call(ServiceResponse<CertificateOperation> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates a certificate operation.
     * Updates a certificate creation operation that is already in progress. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param cancellationRequested Indicates if cancellation was requested on the certificate operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<ServiceResponse<CertificateOperation>> updateCertificateOperationWithServiceResponseAsync(String vaultBaseUrl, String certificateName, boolean cancellationRequested) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        CertificateOperationUpdateParameter certificateOperation = new CertificateOperationUpdateParameter();
        certificateOperation.withCancellationRequested(cancellationRequested);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateCertificateOperation(certificateName, this.apiVersion(), this.acceptLanguage(), certificateOperation, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateOperation>>>() {
                @Override
                public Observable<ServiceResponse<CertificateOperation>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateOperation> clientResponse = updateCertificateOperationDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateOperation> updateCertificateOperationDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateOperation, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateOperation>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the creation operation of a certificate.
     * Gets the creation operation associated with a specified certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation getCertificateOperation(String vaultBaseUrl, String certificateName) {
        return getCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Gets the creation operation of a certificate.
     * Gets the creation operation associated with a specified certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateOperation> getCertificateOperationAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificateOperation> serviceCallback) {
        return ServiceFuture.fromResponse(getCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Gets the creation operation of a certificate.
     * Gets the creation operation associated with a specified certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<CertificateOperation> getCertificateOperationAsync(String vaultBaseUrl, String certificateName) {
        return getCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificateOperation>, CertificateOperation>() {
            @Override
            public CertificateOperation call(ServiceResponse<CertificateOperation> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the creation operation of a certificate.
     * Gets the creation operation associated with a specified certificate. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<ServiceResponse<CertificateOperation>> getCertificateOperationWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificateOperation(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateOperation>>>() {
                @Override
                public Observable<ServiceResponse<CertificateOperation>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateOperation> clientResponse = getCertificateOperationDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateOperation> getCertificateOperationDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateOperation, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateOperation>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes the creation operation for a specific certificate.
     * Deletes the creation operation for a specified certificate that is in the process of being created. The certificate is no longer created. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation deleteCertificateOperation(String vaultBaseUrl, String certificateName) {
        return deleteCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Deletes the creation operation for a specific certificate.
     * Deletes the creation operation for a specified certificate that is in the process of being created. The certificate is no longer created. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateOperation> deleteCertificateOperationAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificateOperation> serviceCallback) {
        return ServiceFuture.fromResponse(deleteCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Deletes the creation operation for a specific certificate.
     * Deletes the creation operation for a specified certificate that is in the process of being created. The certificate is no longer created. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<CertificateOperation> deleteCertificateOperationAsync(String vaultBaseUrl, String certificateName) {
        return deleteCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificateOperation>, CertificateOperation>() {
            @Override
            public CertificateOperation call(ServiceResponse<CertificateOperation> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the creation operation for a specific certificate.
     * Deletes the creation operation for a specified certificate that is in the process of being created. The certificate is no longer created. This operation requires the certificates/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateOperation object
     */
    public Observable<ServiceResponse<CertificateOperation>> deleteCertificateOperationWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteCertificateOperation(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateOperation>>>() {
                @Override
                public Observable<ServiceResponse<CertificateOperation>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateOperation> clientResponse = deleteCertificateOperationDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateOperation> deleteCertificateOperationDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateOperation, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateOperation>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle mergeCertificate(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates) {
        return mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates).toBlocking().single().body();
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> mergeCertificateAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates), serviceCallback);
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> mergeCertificateAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates) {
        return mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> mergeCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (x509Certificates == null) {
            throw new IllegalArgumentException("Parameter x509Certificates is required and cannot be null.");
        }
        Validator.validate(x509Certificates);
        final CertificateAttributes certificateAttributes = null;
        final Map<String, String> tags = null;
        CertificateMergeParameters parameters = new CertificateMergeParameters();
        parameters.withX509Certificates(x509Certificates);
        parameters.withCertificateAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.mergeCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = mergeCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle mergeCertificate(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates, certificateAttributes, tags).toBlocking().single().body();
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> mergeCertificateAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates, CertificateAttributes certificateAttributes, Map<String, String> tags, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates, certificateAttributes, tags), serviceCallback);
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> mergeCertificateAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        return mergeCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName, x509Certificates, certificateAttributes, tags).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Merges a certificate or a certificate chain with a key pair existing on the server.
     * The MergeCertificate operation performs the merging of a certificate or certificate chain with a key pair currently available in the service. This operation requires the certificates/create permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param x509Certificates The certificate or the certificate chain to merge.
     * @param certificateAttributes The attributes of the certificate (optional).
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> mergeCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName, List<byte[]> x509Certificates, CertificateAttributes certificateAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (x509Certificates == null) {
            throw new IllegalArgumentException("Parameter x509Certificates is required and cannot be null.");
        }
        Validator.validate(x509Certificates);
        Validator.validate(certificateAttributes);
        Validator.validate(tags);
        CertificateMergeParameters parameters = new CertificateMergeParameters();
        parameters.withX509Certificates(x509Certificates);
        parameters.withCertificateAttributes(certificateAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.mergeCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = mergeCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> mergeCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(201, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Backs up the specified certificate.
     * Requests that a backup of the specified certificate be downloaded to the client. All versions of the certificate will be downloaded. This operation requires the certificates/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the BackupCertificateResult object if successful.
     */
    public BackupCertificateResult backupCertificate(String vaultBaseUrl, String certificateName) {
        return backupCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Backs up the specified certificate.
     * Requests that a backup of the specified certificate be downloaded to the client. All versions of the certificate will be downloaded. This operation requires the certificates/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<BackupCertificateResult> backupCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<BackupCertificateResult> serviceCallback) {
        return ServiceFuture.fromResponse(backupCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Backs up the specified certificate.
     * Requests that a backup of the specified certificate be downloaded to the client. All versions of the certificate will be downloaded. This operation requires the certificates/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupCertificateResult object
     */
    public Observable<BackupCertificateResult> backupCertificateAsync(String vaultBaseUrl, String certificateName) {
        return backupCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<BackupCertificateResult>, BackupCertificateResult>() {
            @Override
            public BackupCertificateResult call(ServiceResponse<BackupCertificateResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Backs up the specified certificate.
     * Requests that a backup of the specified certificate be downloaded to the client. All versions of the certificate will be downloaded. This operation requires the certificates/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupCertificateResult object
     */
    public Observable<ServiceResponse<BackupCertificateResult>> backupCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.backupCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<BackupCertificateResult>>>() {
                @Override
                public Observable<ServiceResponse<BackupCertificateResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<BackupCertificateResult> clientResponse = backupCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<BackupCertificateResult> backupCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<BackupCertificateResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<BackupCertificateResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Restores a backed up certificate to a vault.
     * Restores a backed up certificate, and all its versions, to a vault. This operation requires the certificates/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateBundleBackup The backup blob associated with a certificate bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle restoreCertificate(String vaultBaseUrl, byte[] certificateBundleBackup) {
        return restoreCertificateWithServiceResponseAsync(vaultBaseUrl, certificateBundleBackup).toBlocking().single().body();
    }

    /**
     * Restores a backed up certificate to a vault.
     * Restores a backed up certificate, and all its versions, to a vault. This operation requires the certificates/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateBundleBackup The backup blob associated with a certificate bundle.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> restoreCertificateAsync(String vaultBaseUrl, byte[] certificateBundleBackup, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(restoreCertificateWithServiceResponseAsync(vaultBaseUrl, certificateBundleBackup), serviceCallback);
    }

    /**
     * Restores a backed up certificate to a vault.
     * Restores a backed up certificate, and all its versions, to a vault. This operation requires the certificates/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateBundleBackup The backup blob associated with a certificate bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> restoreCertificateAsync(String vaultBaseUrl, byte[] certificateBundleBackup) {
        return restoreCertificateWithServiceResponseAsync(vaultBaseUrl, certificateBundleBackup).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Restores a backed up certificate to a vault.
     * Restores a backed up certificate, and all its versions, to a vault. This operation requires the certificates/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateBundleBackup The backup blob associated with a certificate bundle.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> restoreCertificateWithServiceResponseAsync(String vaultBaseUrl, byte[] certificateBundleBackup) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (certificateBundleBackup == null) {
            throw new IllegalArgumentException("Parameter certificateBundleBackup is required and cannot be null.");
        }
        CertificateRestoreParameters parameters = new CertificateRestoreParameters();
        parameters.withCertificateBundleBackup(certificateBundleBackup);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.restoreCertificate(this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = restoreCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> restoreCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedCertificateItem&gt; object if successful.
     */
    public PagedList<DeletedCertificateItem> getDeletedCertificates(final String vaultBaseUrl) {
        ServiceResponse<Page<DeletedCertificateItem>> response = getDeletedCertificatesSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<DeletedCertificateItem>(response.body()) {
            @Override
            public Page<DeletedCertificateItem> nextPage(String nextPageLink) {
                return getDeletedCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedCertificateItem>> getDeletedCertificatesAsync(final String vaultBaseUrl, final ListOperationCallback<DeletedCertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedCertificatesSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(String nextPageLink) {
                    return getDeletedCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<Page<DeletedCertificateItem>> getDeletedCertificatesAsync(final String vaultBaseUrl) {
        return getDeletedCertificatesWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Page<DeletedCertificateItem>>() {
                @Override
                public Page<DeletedCertificateItem> call(ServiceResponse<Page<DeletedCertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesWithServiceResponseAsync(final String vaultBaseUrl) {
        return getDeletedCertificatesSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(ServiceResponse<Page<DeletedCertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedCertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        final Boolean includePending = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedCertificates(maxresults, includePending, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedCertificateItem>> result = getDeletedCertificatesDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedCertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedCertificateItem&gt; object if successful.
     */
    public PagedList<DeletedCertificateItem> getDeletedCertificates(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        ServiceResponse<Page<DeletedCertificateItem>> response = getDeletedCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending).toBlocking().single();
        return new PagedList<DeletedCertificateItem>(response.body()) {
            @Override
            public Page<DeletedCertificateItem> nextPage(String nextPageLink) {
                return getDeletedCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedCertificateItem>> getDeletedCertificatesAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending, final ListOperationCallback<DeletedCertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending),
            new Func1<String, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(String nextPageLink) {
                    return getDeletedCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<Page<DeletedCertificateItem>> getDeletedCertificatesAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        return getDeletedCertificatesWithServiceResponseAsync(vaultBaseUrl, maxresults, includePending)
            .map(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Page<DeletedCertificateItem>>() {
                @Override
                public Page<DeletedCertificateItem> call(ServiceResponse<Page<DeletedCertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        return getDeletedCertificatesSinglePageAsync(vaultBaseUrl, maxresults, includePending)
            .concatMap(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(ServiceResponse<Page<DeletedCertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param includePending Specifies whether to include certificates which are not completely provisioned.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedCertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesSinglePageAsync(final String vaultBaseUrl, final Integer maxresults, final Boolean includePending) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedCertificates(maxresults, includePending, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedCertificateItem>> result = getDeletedCertificatesDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedCertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedCertificateItem>> getDeletedCertificatesDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedCertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedCertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Retrieves information about the specified deleted certificate.
     * The GetDeletedCertificate operation retrieves the deleted certificate information plus its attributes, such as retention interval, scheduled permanent deletion and the current deletion recovery level. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedCertificateBundle object if successful.
     */
    public DeletedCertificateBundle getDeletedCertificate(String vaultBaseUrl, String certificateName) {
        return getDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Retrieves information about the specified deleted certificate.
     * The GetDeletedCertificate operation retrieves the deleted certificate information plus its attributes, such as retention interval, scheduled permanent deletion and the current deletion recovery level. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedCertificateBundle> getDeletedCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<DeletedCertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Retrieves information about the specified deleted certificate.
     * The GetDeletedCertificate operation retrieves the deleted certificate information plus its attributes, such as retention interval, scheduled permanent deletion and the current deletion recovery level. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedCertificateBundle object
     */
    public Observable<DeletedCertificateBundle> getDeletedCertificateAsync(String vaultBaseUrl, String certificateName) {
        return getDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<DeletedCertificateBundle>, DeletedCertificateBundle>() {
            @Override
            public DeletedCertificateBundle call(ServiceResponse<DeletedCertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Retrieves information about the specified deleted certificate.
     * The GetDeletedCertificate operation retrieves the deleted certificate information plus its attributes, such as retention interval, scheduled permanent deletion and the current deletion recovery level. This operation requires the certificates/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedCertificateBundle object
     */
    public Observable<ServiceResponse<DeletedCertificateBundle>> getDeletedCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedCertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedCertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedCertificateBundle> clientResponse = getDeletedCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedCertificateBundle> getDeletedCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedCertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedCertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Permanently deletes the specified deleted certificate.
     * The PurgeDeletedCertificate operation performs an irreversible deletion of the specified certificate, without possibility for recovery. The operation is not available if the recovery level does not specify 'Purgeable'. This operation requires the certificate/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void purgeDeletedCertificate(String vaultBaseUrl, String certificateName) {
        purgeDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Permanently deletes the specified deleted certificate.
     * The PurgeDeletedCertificate operation performs an irreversible deletion of the specified certificate, without possibility for recovery. The operation is not available if the recovery level does not specify 'Purgeable'. This operation requires the certificate/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> purgeDeletedCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(purgeDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Permanently deletes the specified deleted certificate.
     * The PurgeDeletedCertificate operation performs an irreversible deletion of the specified certificate, without possibility for recovery. The operation is not available if the recovery level does not specify 'Purgeable'. This operation requires the certificate/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> purgeDeletedCertificateAsync(String vaultBaseUrl, String certificateName) {
        return purgeDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Permanently deletes the specified deleted certificate.
     * The PurgeDeletedCertificate operation performs an irreversible deletion of the specified certificate, without possibility for recovery. The operation is not available if the recovery level does not specify 'Purgeable'. This operation requires the certificate/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> purgeDeletedCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.purgeDeletedCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = purgeDeletedCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> purgeDeletedCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Void, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Recovers the deleted certificate back to its current version under /certificates.
     * The RecoverDeletedCertificate operation performs the reversal of the Delete operation. The operation is applicable in vaults enabled for soft-delete, and must be issued during the retention interval (available in the deleted certificate's attributes). This operation requires the certificates/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the deleted certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle recoverDeletedCertificate(String vaultBaseUrl, String certificateName) {
        return recoverDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Recovers the deleted certificate back to its current version under /certificates.
     * The RecoverDeletedCertificate operation performs the reversal of the Delete operation. The operation is applicable in vaults enabled for soft-delete, and must be issued during the retention interval (available in the deleted certificate's attributes). This operation requires the certificates/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the deleted certificate
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> recoverDeletedCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(recoverDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Recovers the deleted certificate back to its current version under /certificates.
     * The RecoverDeletedCertificate operation performs the reversal of the Delete operation. The operation is applicable in vaults enabled for soft-delete, and must be issued during the retention interval (available in the deleted certificate's attributes). This operation requires the certificates/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the deleted certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> recoverDeletedCertificateAsync(String vaultBaseUrl, String certificateName) {
        return recoverDeletedCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Recovers the deleted certificate back to its current version under /certificates.
     * The RecoverDeletedCertificate operation performs the reversal of the Delete operation. The operation is applicable in vaults enabled for soft-delete, and must be issued during the retention interval (available in the deleted certificate's attributes). This operation requires the certificates/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the deleted certificate
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> recoverDeletedCertificateWithServiceResponseAsync(String vaultBaseUrl, String certificateName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (certificateName == null) {
            throw new IllegalArgumentException("Parameter certificateName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.recoverDeletedCertificate(certificateName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = recoverDeletedCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> recoverDeletedCertificateDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<CertificateBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<CertificateBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;StorageAccountItem&gt; object if successful.
     */
    public PagedList<StorageAccountItem> getStorageAccounts(final String vaultBaseUrl) {
        ServiceResponse<Page<StorageAccountItem>> response = getStorageAccountsSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<StorageAccountItem>(response.body()) {
            @Override
            public Page<StorageAccountItem> nextPage(String nextPageLink) {
                return getStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<StorageAccountItem>> getStorageAccountsAsync(final String vaultBaseUrl, final ListOperationCallback<StorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getStorageAccountsSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(String nextPageLink) {
                    return getStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<Page<StorageAccountItem>> getStorageAccountsAsync(final String vaultBaseUrl) {
        return getStorageAccountsWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<StorageAccountItem>>, Page<StorageAccountItem>>() {
                @Override
                public Page<StorageAccountItem> call(ServiceResponse<Page<StorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsWithServiceResponseAsync(final String vaultBaseUrl) {
        return getStorageAccountsSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<StorageAccountItem>>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(ServiceResponse<Page<StorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;StorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getStorageAccounts(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<StorageAccountItem>> result = getStorageAccountsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<StorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;StorageAccountItem&gt; object if successful.
     */
    public PagedList<StorageAccountItem> getStorageAccounts(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<StorageAccountItem>> response = getStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<StorageAccountItem>(response.body()) {
            @Override
            public Page<StorageAccountItem> nextPage(String nextPageLink) {
                return getStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<StorageAccountItem>> getStorageAccountsAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<StorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(String nextPageLink) {
                    return getStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<Page<StorageAccountItem>> getStorageAccountsAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getStorageAccountsWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<StorageAccountItem>>, Page<StorageAccountItem>>() {
                @Override
                public Page<StorageAccountItem> call(ServiceResponse<Page<StorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<StorageAccountItem>>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(ServiceResponse<Page<StorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;StorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getStorageAccounts(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<StorageAccountItem>> result = getStorageAccountsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<StorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<StorageAccountItem>> getStorageAccountsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<StorageAccountItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<StorageAccountItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object if successful.
     */
    public PagedList<DeletedStorageAccountItem> getDeletedStorageAccounts(final String vaultBaseUrl) {
        ServiceResponse<Page<DeletedStorageAccountItem>> response = getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl).toBlocking().single();
        return new PagedList<DeletedStorageAccountItem>(response.body()) {
            @Override
            public Page<DeletedStorageAccountItem> nextPage(String nextPageLink) {
                return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedStorageAccountItem>> getDeletedStorageAccountsAsync(final String vaultBaseUrl, final ListOperationCallback<DeletedStorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl),
            new Func1<String, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(String nextPageLink) {
                    return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<Page<DeletedStorageAccountItem>> getDeletedStorageAccountsAsync(final String vaultBaseUrl) {
        return getDeletedStorageAccountsWithServiceResponseAsync(vaultBaseUrl)
            .map(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Page<DeletedStorageAccountItem>>() {
                @Override
                public Page<DeletedStorageAccountItem> call(ServiceResponse<Page<DeletedStorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsWithServiceResponseAsync(final String vaultBaseUrl) {
        return getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl)
            .concatMap(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(ServiceResponse<Page<DeletedStorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsSinglePageAsync(final String vaultBaseUrl) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedStorageAccounts(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedStorageAccountItem>> result = getDeletedStorageAccountsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedStorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object if successful.
     */
    public PagedList<DeletedStorageAccountItem> getDeletedStorageAccounts(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<DeletedStorageAccountItem>> response = getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults).toBlocking().single();
        return new PagedList<DeletedStorageAccountItem>(response.body()) {
            @Override
            public Page<DeletedStorageAccountItem> nextPage(String nextPageLink) {
                return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedStorageAccountItem>> getDeletedStorageAccountsAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<DeletedStorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(String nextPageLink) {
                    return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<Page<DeletedStorageAccountItem>> getDeletedStorageAccountsAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedStorageAccountsWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .map(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Page<DeletedStorageAccountItem>>() {
                @Override
                public Page<DeletedStorageAccountItem> call(ServiceResponse<Page<DeletedStorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getDeletedStorageAccountsSinglePageAsync(vaultBaseUrl, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(ServiceResponse<Page<DeletedStorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsSinglePageAsync(final String vaultBaseUrl, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedStorageAccounts(maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedStorageAccountItem>> result = getDeletedStorageAccountsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedStorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedStorageAccountItem>> getDeletedStorageAccountsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedStorageAccountItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedStorageAccountItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the specified deleted storage account.
     * The Get Deleted Storage Account operation returns the specified deleted storage account along with its attributes. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedStorageBundle object if successful.
     */
    public DeletedStorageBundle getDeletedStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return getDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Gets the specified deleted storage account.
     * The Get Deleted Storage Account operation returns the specified deleted storage account along with its attributes. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedStorageBundle> getDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<DeletedStorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Gets the specified deleted storage account.
     * The Get Deleted Storage Account operation returns the specified deleted storage account along with its attributes. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedStorageBundle object
     */
    public Observable<DeletedStorageBundle> getDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return getDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<DeletedStorageBundle>, DeletedStorageBundle>() {
            @Override
            public DeletedStorageBundle call(ServiceResponse<DeletedStorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the specified deleted storage account.
     * The Get Deleted Storage Account operation returns the specified deleted storage account along with its attributes. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedStorageBundle object
     */
    public Observable<ServiceResponse<DeletedStorageBundle>> getDeletedStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedStorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedStorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedStorageBundle> clientResponse = getDeletedStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedStorageBundle> getDeletedStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedStorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedStorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Permanently deletes the specified storage account.
     * The purge deleted storage account operation removes the secret permanently, without the possibility of recovery. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void purgeDeletedStorageAccount(String vaultBaseUrl, String storageAccountName) {
        purgeDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Permanently deletes the specified storage account.
     * The purge deleted storage account operation removes the secret permanently, without the possibility of recovery. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> purgeDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(purgeDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Permanently deletes the specified storage account.
     * The purge deleted storage account operation removes the secret permanently, without the possibility of recovery. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> purgeDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return purgeDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Permanently deletes the specified storage account.
     * The purge deleted storage account operation removes the secret permanently, without the possibility of recovery. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/purge permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> purgeDeletedStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.purgeDeletedStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = purgeDeletedStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> purgeDeletedStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<Void, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Recovers the deleted storage account.
     * Recovers the deleted storage account in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle recoverDeletedStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return recoverDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Recovers the deleted storage account.
     * Recovers the deleted storage account in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> recoverDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(recoverDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Recovers the deleted storage account.
     * Recovers the deleted storage account in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> recoverDeletedStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return recoverDeletedStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Recovers the deleted storage account.
     * Recovers the deleted storage account in the specified vault. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> recoverDeletedStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.recoverDeletedStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = recoverDeletedStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> recoverDeletedStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Backs up the specified storage account.
     * Requests that a backup of the specified storage account be downloaded to the client. This operation requires the storage/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the BackupStorageResult object if successful.
     */
    public BackupStorageResult backupStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return backupStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Backs up the specified storage account.
     * Requests that a backup of the specified storage account be downloaded to the client. This operation requires the storage/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<BackupStorageResult> backupStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<BackupStorageResult> serviceCallback) {
        return ServiceFuture.fromResponse(backupStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Backs up the specified storage account.
     * Requests that a backup of the specified storage account be downloaded to the client. This operation requires the storage/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupStorageResult object
     */
    public Observable<BackupStorageResult> backupStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return backupStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<BackupStorageResult>, BackupStorageResult>() {
            @Override
            public BackupStorageResult call(ServiceResponse<BackupStorageResult> response) {
                return response.body();
            }
        });
    }

    /**
     * Backs up the specified storage account.
     * Requests that a backup of the specified storage account be downloaded to the client. This operation requires the storage/backup permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the BackupStorageResult object
     */
    public Observable<ServiceResponse<BackupStorageResult>> backupStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.backupStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<BackupStorageResult>>>() {
                @Override
                public Observable<ServiceResponse<BackupStorageResult>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<BackupStorageResult> clientResponse = backupStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<BackupStorageResult> backupStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<BackupStorageResult, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<BackupStorageResult>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Restores a backed up storage account to a vault.
     * Restores a backed up storage account to a vault. This operation requires the storage/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageBundleBackup The backup blob associated with a storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle restoreStorageAccount(String vaultBaseUrl, byte[] storageBundleBackup) {
        return restoreStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageBundleBackup).toBlocking().single().body();
    }

    /**
     * Restores a backed up storage account to a vault.
     * Restores a backed up storage account to a vault. This operation requires the storage/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageBundleBackup The backup blob associated with a storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> restoreStorageAccountAsync(String vaultBaseUrl, byte[] storageBundleBackup, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(restoreStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageBundleBackup), serviceCallback);
    }

    /**
     * Restores a backed up storage account to a vault.
     * Restores a backed up storage account to a vault. This operation requires the storage/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageBundleBackup The backup blob associated with a storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> restoreStorageAccountAsync(String vaultBaseUrl, byte[] storageBundleBackup) {
        return restoreStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageBundleBackup).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Restores a backed up storage account to a vault.
     * Restores a backed up storage account to a vault. This operation requires the storage/restore permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageBundleBackup The backup blob associated with a storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> restoreStorageAccountWithServiceResponseAsync(String vaultBaseUrl, byte[] storageBundleBackup) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (storageBundleBackup == null) {
            throw new IllegalArgumentException("Parameter storageBundleBackup is required and cannot be null.");
        }
        StorageRestoreParameters parameters = new StorageRestoreParameters();
        parameters.withStorageBundleBackup(storageBundleBackup);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.restoreStorageAccount(this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = restoreStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> restoreStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes a storage account. This operation requires the storage/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedStorageBundle object if successful.
     */
    public DeletedStorageBundle deleteStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return deleteStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Deletes a storage account. This operation requires the storage/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedStorageBundle> deleteStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<DeletedStorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Deletes a storage account. This operation requires the storage/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedStorageBundle object
     */
    public Observable<DeletedStorageBundle> deleteStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return deleteStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<DeletedStorageBundle>, DeletedStorageBundle>() {
            @Override
            public DeletedStorageBundle call(ServiceResponse<DeletedStorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a storage account. This operation requires the storage/delete permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedStorageBundle object
     */
    public Observable<ServiceResponse<DeletedStorageBundle>> deleteStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedStorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedStorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedStorageBundle> clientResponse = deleteStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedStorageBundle> deleteStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedStorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedStorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets information about a specified storage account. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle getStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return getStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Gets information about a specified storage account. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> getStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Gets information about a specified storage account. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> getStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return getStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about a specified storage account. This operation requires the storage/get permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> getStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = getStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> getStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle setStorageAccount(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey) {
        return setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey).toBlocking().single().body();
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> setStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey), serviceCallback);
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> setStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey) {
        return setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> setStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (resourceId == null) {
            throw new IllegalArgumentException("Parameter resourceId is required and cannot be null.");
        }
        if (activeKeyName == null) {
            throw new IllegalArgumentException("Parameter activeKeyName is required and cannot be null.");
        }
        final String regenerationPeriod = null;
        final StorageAccountAttributes storageAccountAttributes = null;
        final Map<String, String> tags = null;
        StorageAccountCreateParameters parameters = new StorageAccountCreateParameters();
        parameters.withResourceId(resourceId);
        parameters.withActiveKeyName(activeKeyName);
        parameters.withAutoRegenerateKey(autoRegenerateKey);
        parameters.withRegenerationPeriod(null);
        parameters.withStorageAccountAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = setStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle setStorageAccount(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        return setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags).toBlocking().single().body();
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> setStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags), serviceCallback);
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> setStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        return setStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, resourceId, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a new storage account. This operation requires the storage/set permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param resourceId Storage account resource id.
     * @param activeKeyName Current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> setStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String resourceId, String activeKeyName, boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (resourceId == null) {
            throw new IllegalArgumentException("Parameter resourceId is required and cannot be null.");
        }
        if (activeKeyName == null) {
            throw new IllegalArgumentException("Parameter activeKeyName is required and cannot be null.");
        }
        Validator.validate(storageAccountAttributes);
        Validator.validate(tags);
        StorageAccountCreateParameters parameters = new StorageAccountCreateParameters();
        parameters.withResourceId(resourceId);
        parameters.withActiveKeyName(activeKeyName);
        parameters.withAutoRegenerateKey(autoRegenerateKey);
        parameters.withRegenerationPeriod(regenerationPeriod);
        parameters.withStorageAccountAttributes(storageAccountAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = setStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> setStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle updateStorageAccount(String vaultBaseUrl, String storageAccountName) {
        return updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> updateStorageAccountAsync(String vaultBaseUrl, String storageAccountName, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> updateStorageAccountAsync(String vaultBaseUrl, String storageAccountName) {
        return updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> updateStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final String activeKeyName = null;
        final Boolean autoRegenerateKey = null;
        final String regenerationPeriod = null;
        final StorageAccountAttributes storageAccountAttributes = null;
        final Map<String, String> tags = null;
        StorageAccountUpdateParameters parameters = new StorageAccountUpdateParameters();
        parameters.withActiveKeyName(null);
        parameters.withAutoRegenerateKey(null);
        parameters.withRegenerationPeriod(null);
        parameters.withStorageAccountAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = updateStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param activeKeyName The current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle updateStorageAccount(String vaultBaseUrl, String storageAccountName, String activeKeyName, Boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        return updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param activeKeyName The current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> updateStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String activeKeyName, Boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param activeKeyName The current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> updateStorageAccountAsync(String vaultBaseUrl, String storageAccountName, String activeKeyName, Boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        return updateStorageAccountWithServiceResponseAsync(vaultBaseUrl, storageAccountName, activeKeyName, autoRegenerateKey, regenerationPeriod, storageAccountAttributes, tags).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given storage account. This operation requires the storage/set/update permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param activeKeyName The current active storage account key name.
     * @param autoRegenerateKey whether keyvault should manage the storage account for the user.
     * @param regenerationPeriod The key regeneration time duration specified in ISO-8601 format.
     * @param storageAccountAttributes The attributes of the storage account.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> updateStorageAccountWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String activeKeyName, Boolean autoRegenerateKey, String regenerationPeriod, StorageAccountAttributes storageAccountAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(storageAccountAttributes);
        Validator.validate(tags);
        StorageAccountUpdateParameters parameters = new StorageAccountUpdateParameters();
        parameters.withActiveKeyName(activeKeyName);
        parameters.withAutoRegenerateKey(autoRegenerateKey);
        parameters.withRegenerationPeriod(regenerationPeriod);
        parameters.withStorageAccountAttributes(storageAccountAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateStorageAccount(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = updateStorageAccountDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> updateStorageAccountDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Regenerates the specified key value for the given storage account. This operation requires the storage/regeneratekey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param keyName The storage account key name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the StorageBundle object if successful.
     */
    public StorageBundle regenerateStorageAccountKey(String vaultBaseUrl, String storageAccountName, String keyName) {
        return regenerateStorageAccountKeyWithServiceResponseAsync(vaultBaseUrl, storageAccountName, keyName).toBlocking().single().body();
    }

    /**
     * Regenerates the specified key value for the given storage account. This operation requires the storage/regeneratekey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param keyName The storage account key name.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<StorageBundle> regenerateStorageAccountKeyAsync(String vaultBaseUrl, String storageAccountName, String keyName, final ServiceCallback<StorageBundle> serviceCallback) {
        return ServiceFuture.fromResponse(regenerateStorageAccountKeyWithServiceResponseAsync(vaultBaseUrl, storageAccountName, keyName), serviceCallback);
    }

    /**
     * Regenerates the specified key value for the given storage account. This operation requires the storage/regeneratekey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param keyName The storage account key name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<StorageBundle> regenerateStorageAccountKeyAsync(String vaultBaseUrl, String storageAccountName, String keyName) {
        return regenerateStorageAccountKeyWithServiceResponseAsync(vaultBaseUrl, storageAccountName, keyName).map(new Func1<ServiceResponse<StorageBundle>, StorageBundle>() {
            @Override
            public StorageBundle call(ServiceResponse<StorageBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Regenerates the specified key value for the given storage account. This operation requires the storage/regeneratekey permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param keyName The storage account key name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the StorageBundle object
     */
    public Observable<ServiceResponse<StorageBundle>> regenerateStorageAccountKeyWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String keyName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (keyName == null) {
            throw new IllegalArgumentException("Parameter keyName is required and cannot be null.");
        }
        StorageAccountRegenerteKeyParameters parameters = new StorageAccountRegenerteKeyParameters();
        parameters.withKeyName(keyName);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.regenerateStorageAccountKey(storageAccountName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<StorageBundle>>>() {
                @Override
                public Observable<ServiceResponse<StorageBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<StorageBundle> clientResponse = regenerateStorageAccountKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<StorageBundle> regenerateStorageAccountKeyDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<StorageBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<StorageBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SasDefinitionItem&gt; object if successful.
     */
    public PagedList<SasDefinitionItem> getSasDefinitions(final String vaultBaseUrl, final String storageAccountName) {
        ServiceResponse<Page<SasDefinitionItem>> response = getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName).toBlocking().single();
        return new PagedList<SasDefinitionItem>(response.body()) {
            @Override
            public Page<SasDefinitionItem> nextPage(String nextPageLink) {
                return getSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SasDefinitionItem>> getSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final ListOperationCallback<SasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName),
            new Func1<String, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(String nextPageLink) {
                    return getSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<Page<SasDefinitionItem>> getSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName) {
        return getSasDefinitionsWithServiceResponseAsync(vaultBaseUrl, storageAccountName)
            .map(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Page<SasDefinitionItem>>() {
                @Override
                public Page<SasDefinitionItem> call(ServiceResponse<Page<SasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsWithServiceResponseAsync(final String vaultBaseUrl, final String storageAccountName) {
        return getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName)
            .concatMap(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(ServiceResponse<Page<SasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsSinglePageAsync(final String vaultBaseUrl, final String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSasDefinitions(storageAccountName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SasDefinitionItem>> result = getSasDefinitionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SasDefinitionItem&gt; object if successful.
     */
    public PagedList<SasDefinitionItem> getSasDefinitions(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        ServiceResponse<Page<SasDefinitionItem>> response = getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults).toBlocking().single();
        return new PagedList<SasDefinitionItem>(response.body()) {
            @Override
            public Page<SasDefinitionItem> nextPage(String nextPageLink) {
                return getSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SasDefinitionItem>> getSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults, final ListOperationCallback<SasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(String nextPageLink) {
                    return getSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<Page<SasDefinitionItem>> getSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        return getSasDefinitionsWithServiceResponseAsync(vaultBaseUrl, storageAccountName, maxresults)
            .map(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Page<SasDefinitionItem>>() {
                @Override
                public Page<SasDefinitionItem> call(ServiceResponse<Page<SasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsWithServiceResponseAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        return getSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(ServiceResponse<Page<SasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsSinglePageAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSasDefinitions(storageAccountName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SasDefinitionItem>> result = getSasDefinitionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SasDefinitionItem>> getSasDefinitionsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SasDefinitionItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SasDefinitionItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object if successful.
     */
    public PagedList<DeletedSasDefinitionItem> getDeletedSasDefinitions(final String vaultBaseUrl, final String storageAccountName) {
        ServiceResponse<Page<DeletedSasDefinitionItem>> response = getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName).toBlocking().single();
        return new PagedList<DeletedSasDefinitionItem>(response.body()) {
            @Override
            public Page<DeletedSasDefinitionItem> nextPage(String nextPageLink) {
                return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSasDefinitionItem>> getDeletedSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final ListOperationCallback<DeletedSasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(String nextPageLink) {
                    return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<Page<DeletedSasDefinitionItem>> getDeletedSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName) {
        return getDeletedSasDefinitionsWithServiceResponseAsync(vaultBaseUrl, storageAccountName)
            .map(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Page<DeletedSasDefinitionItem>>() {
                @Override
                public Page<DeletedSasDefinitionItem> call(ServiceResponse<Page<DeletedSasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsWithServiceResponseAsync(final String vaultBaseUrl, final String storageAccountName) {
        return getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(ServiceResponse<Page<DeletedSasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsSinglePageAsync(final String vaultBaseUrl, final String storageAccountName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final Integer maxresults = null;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSasDefinitions(storageAccountName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSasDefinitionItem>> result = getDeletedSasDefinitionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object if successful.
     */
    public PagedList<DeletedSasDefinitionItem> getDeletedSasDefinitions(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        ServiceResponse<Page<DeletedSasDefinitionItem>> response = getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults).toBlocking().single();
        return new PagedList<DeletedSasDefinitionItem>(response.body()) {
            @Override
            public Page<DeletedSasDefinitionItem> nextPage(String nextPageLink) {
                return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSasDefinitionItem>> getDeletedSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults, final ListOperationCallback<DeletedSasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(String nextPageLink) {
                    return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<Page<DeletedSasDefinitionItem>> getDeletedSasDefinitionsAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        return getDeletedSasDefinitionsWithServiceResponseAsync(vaultBaseUrl, storageAccountName, maxresults)
            .map(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Page<DeletedSasDefinitionItem>>() {
                @Override
                public Page<DeletedSasDefinitionItem> call(ServiceResponse<Page<DeletedSasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsWithServiceResponseAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        return getDeletedSasDefinitionsSinglePageAsync(vaultBaseUrl, storageAccountName, maxresults)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(ServiceResponse<Page<DeletedSasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param maxresults Maximum number of results to return in a page. If not specified the service will return up to 25 results.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsSinglePageAsync(final String vaultBaseUrl, final String storageAccountName, final Integer maxresults) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSasDefinitions(storageAccountName, maxresults, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSasDefinitionItem>> result = getDeletedSasDefinitionsDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedSasDefinitionItem>> getDeletedSasDefinitionsDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedSasDefinitionItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedSasDefinitionItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets the specified deleted sas definition.
     * The Get Deleted SAS Definition operation returns the specified deleted SAS definition along with its attributes. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedSasDefinitionBundle object if successful.
     */
    public DeletedSasDefinitionBundle getDeletedSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return getDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).toBlocking().single().body();
    }

    /**
     * Gets the specified deleted sas definition.
     * The Get Deleted SAS Definition operation returns the specified deleted SAS definition along with its attributes. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedSasDefinitionBundle> getDeletedSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, final ServiceCallback<DeletedSasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName), serviceCallback);
    }

    /**
     * Gets the specified deleted sas definition.
     * The Get Deleted SAS Definition operation returns the specified deleted SAS definition along with its attributes. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSasDefinitionBundle object
     */
    public Observable<DeletedSasDefinitionBundle> getDeletedSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return getDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).map(new Func1<ServiceResponse<DeletedSasDefinitionBundle>, DeletedSasDefinitionBundle>() {
            @Override
            public DeletedSasDefinitionBundle call(ServiceResponse<DeletedSasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets the specified deleted sas definition.
     * The Get Deleted SAS Definition operation returns the specified deleted SAS definition along with its attributes. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSasDefinitionBundle object
     */
    public Observable<ServiceResponse<DeletedSasDefinitionBundle>> getDeletedSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getDeletedSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedSasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedSasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedSasDefinitionBundle> clientResponse = getDeletedSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedSasDefinitionBundle> getDeletedSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedSasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedSasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Recovers the deleted SAS definition.
     * Recovers the deleted SAS definition for the specified storage account. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle recoverDeletedSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return recoverDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).toBlocking().single().body();
    }

    /**
     * Recovers the deleted SAS definition.
     * Recovers the deleted SAS definition for the specified storage account. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> recoverDeletedSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(recoverDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName), serviceCallback);
    }

    /**
     * Recovers the deleted SAS definition.
     * Recovers the deleted SAS definition for the specified storage account. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> recoverDeletedSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return recoverDeletedSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Recovers the deleted SAS definition.
     * Recovers the deleted SAS definition for the specified storage account. This operation can only be performed on a soft-delete enabled vault. This operation requires the storage/recover permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> recoverDeletedSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.recoverDeletedSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = recoverDeletedSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SasDefinitionBundle> recoverDeletedSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Deletes a SAS definition from a specified storage account. This operation requires the storage/deletesas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the DeletedSasDefinitionBundle object if successful.
     */
    public DeletedSasDefinitionBundle deleteSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return deleteSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).toBlocking().single().body();
    }

    /**
     * Deletes a SAS definition from a specified storage account. This operation requires the storage/deletesas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<DeletedSasDefinitionBundle> deleteSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, final ServiceCallback<DeletedSasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName), serviceCallback);
    }

    /**
     * Deletes a SAS definition from a specified storage account. This operation requires the storage/deletesas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSasDefinitionBundle object
     */
    public Observable<DeletedSasDefinitionBundle> deleteSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return deleteSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).map(new Func1<ServiceResponse<DeletedSasDefinitionBundle>, DeletedSasDefinitionBundle>() {
            @Override
            public DeletedSasDefinitionBundle call(ServiceResponse<DeletedSasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a SAS definition from a specified storage account. This operation requires the storage/deletesas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the DeletedSasDefinitionBundle object
     */
    public Observable<ServiceResponse<DeletedSasDefinitionBundle>> deleteSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.deleteSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<DeletedSasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<DeletedSasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<DeletedSasDefinitionBundle> clientResponse = deleteSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<DeletedSasDefinitionBundle> deleteSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<DeletedSasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<DeletedSasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Gets information about a SAS definition for the specified storage account. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle getSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return getSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).toBlocking().single().body();
    }

    /**
     * Gets information about a SAS definition for the specified storage account. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> getSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(getSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName), serviceCallback);
    }

    /**
     * Gets information about a SAS definition for the specified storage account. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> getSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return getSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about a SAS definition for the specified storage account. This operation requires the storage/getsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> getSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = getSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SasDefinitionBundle> getSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle setSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod) {
        return setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod).toBlocking().single().body();
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> setSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod), serviceCallback);
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> setSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod) {
        return setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> setSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (templateUri == null) {
            throw new IllegalArgumentException("Parameter templateUri is required and cannot be null.");
        }
        if (sasType == null) {
            throw new IllegalArgumentException("Parameter sasType is required and cannot be null.");
        }
        if (validityPeriod == null) {
            throw new IllegalArgumentException("Parameter validityPeriod is required and cannot be null.");
        }
        final SasDefinitionAttributes sasDefinitionAttributes = null;
        final Map<String, String> tags = null;
        SasDefinitionCreateParameters parameters = new SasDefinitionCreateParameters();
        parameters.withTemplateUri(templateUri);
        parameters.withSasType(sasType);
        parameters.withValidityPeriod(validityPeriod);
        parameters.withSasDefinitionAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = setSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle setSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        return setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags).toBlocking().single().body();
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> setSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags), serviceCallback);
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> setSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        return setSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a new SAS definition for the specified storage account. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> setSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        if (templateUri == null) {
            throw new IllegalArgumentException("Parameter templateUri is required and cannot be null.");
        }
        if (sasType == null) {
            throw new IllegalArgumentException("Parameter sasType is required and cannot be null.");
        }
        if (validityPeriod == null) {
            throw new IllegalArgumentException("Parameter validityPeriod is required and cannot be null.");
        }
        Validator.validate(sasDefinitionAttributes);
        Validator.validate(tags);
        SasDefinitionCreateParameters parameters = new SasDefinitionCreateParameters();
        parameters.withTemplateUri(templateUri);
        parameters.withSasType(sasType);
        parameters.withValidityPeriod(validityPeriod);
        parameters.withSasDefinitionAttributes(sasDefinitionAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.setSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = setSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SasDefinitionBundle> setSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle updateSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> updateSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> updateSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        return updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> updateSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        final String templateUri = null;
        final SasTokenType sasType = null;
        final String validityPeriod = null;
        final SasDefinitionAttributes sasDefinitionAttributes = null;
        final Map<String, String> tags = null;
        SasDefinitionUpdateParameters parameters = new SasDefinitionUpdateParameters();
        parameters.withTemplateUri(null);
        parameters.withSasType(null);
        parameters.withValidityPeriod(null);
        parameters.withSasDefinitionAttributes(null);
        parameters.withTags(null);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = updateSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the SasDefinitionBundle object if successful.
     */
    public SasDefinitionBundle updateSasDefinition(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        return updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags).toBlocking().single().body();
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SasDefinitionBundle> updateSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags, final ServiceCallback<SasDefinitionBundle> serviceCallback) {
        return ServiceFuture.fromResponse(updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags), serviceCallback);
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<SasDefinitionBundle> updateSasDefinitionAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        return updateSasDefinitionWithServiceResponseAsync(vaultBaseUrl, storageAccountName, sasDefinitionName, templateUri, sasType, validityPeriod, sasDefinitionAttributes, tags).map(new Func1<ServiceResponse<SasDefinitionBundle>, SasDefinitionBundle>() {
            @Override
            public SasDefinitionBundle call(ServiceResponse<SasDefinitionBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Updates the specified attributes associated with the given SAS definition. This operation requires the storage/setsas permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param storageAccountName The name of the storage account.
     * @param sasDefinitionName The name of the SAS definition.
     * @param templateUri The SAS definition token template signed with an arbitrary key.  Tokens created according to the SAS definition will have the same properties as the template.
     * @param sasType The type of SAS token the SAS definition will create. Possible values include: 'account', 'service'
     * @param validityPeriod The validity period of SAS tokens created according to the SAS definition.
     * @param sasDefinitionAttributes The attributes of the SAS definition.
     * @param tags Application specific metadata in the form of key-value pairs.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the SasDefinitionBundle object
     */
    public Observable<ServiceResponse<SasDefinitionBundle>> updateSasDefinitionWithServiceResponseAsync(String vaultBaseUrl, String storageAccountName, String sasDefinitionName, String templateUri, SasTokenType sasType, String validityPeriod, SasDefinitionAttributes sasDefinitionAttributes, Map<String, String> tags) {
        if (vaultBaseUrl == null) {
            throw new IllegalArgumentException("Parameter vaultBaseUrl is required and cannot be null.");
        }
        if (storageAccountName == null) {
            throw new IllegalArgumentException("Parameter storageAccountName is required and cannot be null.");
        }
        if (sasDefinitionName == null) {
            throw new IllegalArgumentException("Parameter sasDefinitionName is required and cannot be null.");
        }
        if (this.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.apiVersion() is required and cannot be null.");
        }
        Validator.validate(sasDefinitionAttributes);
        Validator.validate(tags);
        SasDefinitionUpdateParameters parameters = new SasDefinitionUpdateParameters();
        parameters.withTemplateUri(templateUri);
        parameters.withSasType(sasType);
        parameters.withValidityPeriod(validityPeriod);
        parameters.withSasDefinitionAttributes(sasDefinitionAttributes);
        parameters.withTags(tags);
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.updateSasDefinition(storageAccountName, sasDefinitionName, this.apiVersion(), this.acceptLanguage(), parameters, parameterizedHost, this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<SasDefinitionBundle>>>() {
                @Override
                public Observable<ServiceResponse<SasDefinitionBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SasDefinitionBundle> clientResponse = updateSasDefinitionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SasDefinitionBundle> updateSasDefinitionDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<SasDefinitionBundle, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<SasDefinitionBundle>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeyVersionsNext(final String nextPageLink) {
        ServiceResponse<Page<KeyItem>> response = getKeyVersionsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeyVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeyVersionsNextAsync(final String nextPageLink, final ServiceFuture<List<KeyItem>> serviceFuture, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeyVersionsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeyVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeyVersionsNextAsync(final String nextPageLink) {
        return getKeyVersionsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsNextWithServiceResponseAsync(final String nextPageLink) {
        return getKeyVersionsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeyVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Retrieves a list of individual key versions with the same key name.
     * The full key identifier, attributes, and tags are provided in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeyVersionsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getKeyVersionsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeyVersionsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<KeyItem>> getKeyVersionsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<KeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<KeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;KeyItem&gt; object if successful.
     */
    public PagedList<KeyItem> getKeysNext(final String nextPageLink) {
        ServiceResponse<Page<KeyItem>> response = getKeysNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<KeyItem>(response.body()) {
            @Override
            public Page<KeyItem> nextPage(String nextPageLink) {
                return getKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<KeyItem>> getKeysNextAsync(final String nextPageLink, final ServiceFuture<List<KeyItem>> serviceFuture, final ListOperationCallback<KeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getKeysNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(String nextPageLink) {
                    return getKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<Page<KeyItem>> getKeysNextAsync(final String nextPageLink) {
        return getKeysNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<KeyItem>>, Page<KeyItem>>() {
                @Override
                public Page<KeyItem> call(ServiceResponse<Page<KeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;KeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysNextWithServiceResponseAsync(final String nextPageLink) {
        return getKeysNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<KeyItem>>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(ServiceResponse<Page<KeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a stored key. The LIST operation is applicable to all key types, however only the base key identifier, attributes, and tags are provided in the response. Individual versions of a key are not listed in the response. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;KeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<KeyItem>>> getKeysNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getKeysNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<KeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<KeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<KeyItem>> result = getKeysNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<KeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<KeyItem>> getKeysNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<KeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<KeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedKeyItem&gt; object if successful.
     */
    public PagedList<DeletedKeyItem> getDeletedKeysNext(final String nextPageLink) {
        ServiceResponse<Page<DeletedKeyItem>> response = getDeletedKeysNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<DeletedKeyItem>(response.body()) {
            @Override
            public Page<DeletedKeyItem> nextPage(String nextPageLink) {
                return getDeletedKeysNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedKeyItem>> getDeletedKeysNextAsync(final String nextPageLink, final ServiceFuture<List<DeletedKeyItem>> serviceFuture, final ListOperationCallback<DeletedKeyItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedKeysNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(String nextPageLink) {
                    return getDeletedKeysNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<Page<DeletedKeyItem>> getDeletedKeysNextAsync(final String nextPageLink) {
        return getDeletedKeysNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Page<DeletedKeyItem>>() {
                @Override
                public Page<DeletedKeyItem> call(ServiceResponse<Page<DeletedKeyItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedKeyItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysNextWithServiceResponseAsync(final String nextPageLink) {
        return getDeletedKeysNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<DeletedKeyItem>>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(ServiceResponse<Page<DeletedKeyItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedKeysNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted keys in the specified vault.
     * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedKeyItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedKeyItem>>> getDeletedKeysNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getDeletedKeysNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedKeyItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedKeyItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedKeyItem>> result = getDeletedKeysNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedKeyItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedKeyItem>> getDeletedKeysNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedKeyItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedKeyItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecretsNext(final String nextPageLink) {
        ServiceResponse<Page<SecretItem>> response = getSecretsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretsNextAsync(final String nextPageLink, final ServiceFuture<List<SecretItem>> serviceFuture, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretsNextAsync(final String nextPageLink) {
        return getSecretsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsNextWithServiceResponseAsync(final String nextPageLink) {
        return getSecretsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List secrets in a specified key vault.
     * The Get Secrets operation is applicable to the entire vault. However, only the base secret identifier and its attributes are provided in the response. Individual secret versions are not listed in the response. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getSecretsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SecretItem>> getSecretsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SecretItem&gt; object if successful.
     */
    public PagedList<SecretItem> getSecretVersionsNext(final String nextPageLink) {
        ServiceResponse<Page<SecretItem>> response = getSecretVersionsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<SecretItem>(response.body()) {
            @Override
            public Page<SecretItem> nextPage(String nextPageLink) {
                return getSecretVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SecretItem>> getSecretVersionsNextAsync(final String nextPageLink, final ServiceFuture<List<SecretItem>> serviceFuture, final ListOperationCallback<SecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSecretVersionsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(String nextPageLink) {
                    return getSecretVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<Page<SecretItem>> getSecretVersionsNextAsync(final String nextPageLink) {
        return getSecretVersionsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<SecretItem>>, Page<SecretItem>>() {
                @Override
                public Page<SecretItem> call(ServiceResponse<Page<SecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsNextWithServiceResponseAsync(final String nextPageLink) {
        return getSecretVersionsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<SecretItem>>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(ServiceResponse<Page<SecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSecretVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List all versions of the specified secret.
     * The full secret identifier and attributes are provided in the response. No values are returned for the secrets. This operations requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SecretItem>>> getSecretVersionsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getSecretVersionsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SecretItem>> result = getSecretVersionsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SecretItem>> getSecretVersionsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSecretItem&gt; object if successful.
     */
    public PagedList<DeletedSecretItem> getDeletedSecretsNext(final String nextPageLink) {
        ServiceResponse<Page<DeletedSecretItem>> response = getDeletedSecretsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<DeletedSecretItem>(response.body()) {
            @Override
            public Page<DeletedSecretItem> nextPage(String nextPageLink) {
                return getDeletedSecretsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSecretItem>> getDeletedSecretsNextAsync(final String nextPageLink, final ServiceFuture<List<DeletedSecretItem>> serviceFuture, final ListOperationCallback<DeletedSecretItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSecretsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(String nextPageLink) {
                    return getDeletedSecretsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<Page<DeletedSecretItem>> getDeletedSecretsNextAsync(final String nextPageLink) {
        return getDeletedSecretsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Page<DeletedSecretItem>>() {
                @Override
                public Page<DeletedSecretItem> call(ServiceResponse<Page<DeletedSecretItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSecretItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsNextWithServiceResponseAsync(final String nextPageLink) {
        return getDeletedSecretsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSecretItem>>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(ServiceResponse<Page<DeletedSecretItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSecretsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted secrets for the specified vault.
     * The Get Deleted Secrets operation returns the secrets that have been deleted for a vault enabled for soft-delete. This operation requires the secrets/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSecretItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSecretItem>>> getDeletedSecretsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getDeletedSecretsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSecretItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSecretItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSecretItem>> result = getDeletedSecretsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSecretItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedSecretItem>> getDeletedSecretsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedSecretItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedSecretItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificatesNext(final String nextPageLink) {
        ServiceResponse<Page<CertificateItem>> response = getCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificatesNextAsync(final String nextPageLink, final ServiceFuture<List<CertificateItem>> serviceFuture, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificatesNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificatesNextAsync(final String nextPageLink) {
        return getCertificatesNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesNextWithServiceResponseAsync(final String nextPageLink) {
        return getCertificatesNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     * The GetCertificates operation returns the set of certificates resources in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getCertificatesNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificatesNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateItem>> getCertificatesNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateIssuerItem&gt; object if successful.
     */
    public PagedList<CertificateIssuerItem> getCertificateIssuersNext(final String nextPageLink) {
        ServiceResponse<Page<CertificateIssuerItem>> response = getCertificateIssuersNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CertificateIssuerItem>(response.body()) {
            @Override
            public Page<CertificateIssuerItem> nextPage(String nextPageLink) {
                return getCertificateIssuersNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateIssuerItem>> getCertificateIssuersNextAsync(final String nextPageLink, final ServiceFuture<List<CertificateIssuerItem>> serviceFuture, final ListOperationCallback<CertificateIssuerItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateIssuersNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(String nextPageLink) {
                    return getCertificateIssuersNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<Page<CertificateIssuerItem>> getCertificateIssuersNextAsync(final String nextPageLink) {
        return getCertificateIssuersNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Page<CertificateIssuerItem>>() {
                @Override
                public Page<CertificateIssuerItem> call(ServiceResponse<Page<CertificateIssuerItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateIssuerItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersNextWithServiceResponseAsync(final String nextPageLink) {
        return getCertificateIssuersNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<CertificateIssuerItem>>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(ServiceResponse<Page<CertificateIssuerItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateIssuersNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificate issuers for a specified key vault.
     * The GetCertificateIssuers operation returns the set of certificate issuer resources in the specified key vault. This operation requires the certificates/manageissuers/getissuers permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateIssuerItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateIssuerItem>>> getCertificateIssuersNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getCertificateIssuersNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateIssuerItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateIssuerItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateIssuerItem>> result = getCertificateIssuersNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateIssuerItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateIssuerItem>> getCertificateIssuersNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateIssuerItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateIssuerItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificateVersionsNext(final String nextPageLink) {
        ServiceResponse<Page<CertificateItem>> response = getCertificateVersionsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<CertificateItem>(response.body()) {
            @Override
            public Page<CertificateItem> nextPage(String nextPageLink) {
                return getCertificateVersionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificateVersionsNextAsync(final String nextPageLink, final ServiceFuture<List<CertificateItem>> serviceFuture, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificateVersionsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(String nextPageLink) {
                    return getCertificateVersionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificateVersionsNextAsync(final String nextPageLink) {
        return getCertificateVersionsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<CertificateItem>>, Page<CertificateItem>>() {
                @Override
                public Page<CertificateItem> call(ServiceResponse<Page<CertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsNextWithServiceResponseAsync(final String nextPageLink) {
        return getCertificateVersionsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<CertificateItem>>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(ServiceResponse<Page<CertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getCertificateVersionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List the versions of a certificate.
     * The GetCertificateVersions operation returns the versions of a certificate in the specified key vault. This operation requires the certificates/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;CertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificateVersionsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getCertificateVersionsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<CertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<CertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<CertificateItem>> result = getCertificateVersionsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<CertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<CertificateItem>> getCertificateVersionsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<CertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<CertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedCertificateItem&gt; object if successful.
     */
    public PagedList<DeletedCertificateItem> getDeletedCertificatesNext(final String nextPageLink) {
        ServiceResponse<Page<DeletedCertificateItem>> response = getDeletedCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<DeletedCertificateItem>(response.body()) {
            @Override
            public Page<DeletedCertificateItem> nextPage(String nextPageLink) {
                return getDeletedCertificatesNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedCertificateItem>> getDeletedCertificatesNextAsync(final String nextPageLink, final ServiceFuture<List<DeletedCertificateItem>> serviceFuture, final ListOperationCallback<DeletedCertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedCertificatesNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(String nextPageLink) {
                    return getDeletedCertificatesNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<Page<DeletedCertificateItem>> getDeletedCertificatesNextAsync(final String nextPageLink) {
        return getDeletedCertificatesNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Page<DeletedCertificateItem>>() {
                @Override
                public Page<DeletedCertificateItem> call(ServiceResponse<Page<DeletedCertificateItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedCertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesNextWithServiceResponseAsync(final String nextPageLink) {
        return getDeletedCertificatesNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<DeletedCertificateItem>>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(ServiceResponse<Page<DeletedCertificateItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists the deleted certificates in the specified vault currently available for recovery.
     * The GetDeletedCertificates operation retrieves the certificates in the current vault which are in a deleted state and ready for recovery or purging. This operation includes deletion-specific information. This operation requires the certificates/get/list permission. This operation can only be enabled on soft-delete enabled vaults.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedCertificateItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedCertificateItem>>> getDeletedCertificatesNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getDeletedCertificatesNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedCertificateItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedCertificateItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedCertificateItem>> result = getDeletedCertificatesNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedCertificateItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedCertificateItem>> getDeletedCertificatesNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedCertificateItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedCertificateItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;StorageAccountItem&gt; object if successful.
     */
    public PagedList<StorageAccountItem> getStorageAccountsNext(final String nextPageLink) {
        ServiceResponse<Page<StorageAccountItem>> response = getStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<StorageAccountItem>(response.body()) {
            @Override
            public Page<StorageAccountItem> nextPage(String nextPageLink) {
                return getStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<StorageAccountItem>> getStorageAccountsNextAsync(final String nextPageLink, final ServiceFuture<List<StorageAccountItem>> serviceFuture, final ListOperationCallback<StorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getStorageAccountsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(String nextPageLink) {
                    return getStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<Page<StorageAccountItem>> getStorageAccountsNextAsync(final String nextPageLink) {
        return getStorageAccountsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<StorageAccountItem>>, Page<StorageAccountItem>>() {
                @Override
                public Page<StorageAccountItem> call(ServiceResponse<Page<StorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;StorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsNextWithServiceResponseAsync(final String nextPageLink) {
        return getStorageAccountsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<StorageAccountItem>>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(ServiceResponse<Page<StorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage accounts managed by the specified key vault. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;StorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<StorageAccountItem>>> getStorageAccountsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getStorageAccountsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<StorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<StorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<StorageAccountItem>> result = getStorageAccountsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<StorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<StorageAccountItem>> getStorageAccountsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<StorageAccountItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<StorageAccountItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object if successful.
     */
    public PagedList<DeletedStorageAccountItem> getDeletedStorageAccountsNext(final String nextPageLink) {
        ServiceResponse<Page<DeletedStorageAccountItem>> response = getDeletedStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<DeletedStorageAccountItem>(response.body()) {
            @Override
            public Page<DeletedStorageAccountItem> nextPage(String nextPageLink) {
                return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedStorageAccountItem>> getDeletedStorageAccountsNextAsync(final String nextPageLink, final ServiceFuture<List<DeletedStorageAccountItem>> serviceFuture, final ListOperationCallback<DeletedStorageAccountItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedStorageAccountsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(String nextPageLink) {
                    return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<Page<DeletedStorageAccountItem>> getDeletedStorageAccountsNextAsync(final String nextPageLink) {
        return getDeletedStorageAccountsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Page<DeletedStorageAccountItem>>() {
                @Override
                public Page<DeletedStorageAccountItem> call(ServiceResponse<Page<DeletedStorageAccountItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedStorageAccountItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsNextWithServiceResponseAsync(final String nextPageLink) {
        return getDeletedStorageAccountsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<DeletedStorageAccountItem>>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(ServiceResponse<Page<DeletedStorageAccountItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedStorageAccountsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted storage accounts for the specified vault.
     * The Get Deleted Storage Accounts operation returns the storage accounts that have been deleted for a vault enabled for soft-delete. This operation requires the storage/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedStorageAccountItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> getDeletedStorageAccountsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getDeletedStorageAccountsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedStorageAccountItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedStorageAccountItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedStorageAccountItem>> result = getDeletedStorageAccountsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedStorageAccountItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedStorageAccountItem>> getDeletedStorageAccountsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedStorageAccountItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedStorageAccountItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;SasDefinitionItem&gt; object if successful.
     */
    public PagedList<SasDefinitionItem> getSasDefinitionsNext(final String nextPageLink) {
        ServiceResponse<Page<SasDefinitionItem>> response = getSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<SasDefinitionItem>(response.body()) {
            @Override
            public Page<SasDefinitionItem> nextPage(String nextPageLink) {
                return getSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<SasDefinitionItem>> getSasDefinitionsNextAsync(final String nextPageLink, final ServiceFuture<List<SasDefinitionItem>> serviceFuture, final ListOperationCallback<SasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getSasDefinitionsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(String nextPageLink) {
                    return getSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<Page<SasDefinitionItem>> getSasDefinitionsNextAsync(final String nextPageLink) {
        return getSasDefinitionsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Page<SasDefinitionItem>>() {
                @Override
                public Page<SasDefinitionItem> call(ServiceResponse<Page<SasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;SasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsNextWithServiceResponseAsync(final String nextPageLink) {
        return getSasDefinitionsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<SasDefinitionItem>>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(ServiceResponse<Page<SasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List storage SAS definitions for the given storage account. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;SasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<SasDefinitionItem>>> getSasDefinitionsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getSasDefinitionsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<SasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<SasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<SasDefinitionItem>> result = getSasDefinitionsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<SasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<SasDefinitionItem>> getSasDefinitionsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<SasDefinitionItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<SasDefinitionItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws KeyVaultErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object if successful.
     */
    public PagedList<DeletedSasDefinitionItem> getDeletedSasDefinitionsNext(final String nextPageLink) {
        ServiceResponse<Page<DeletedSasDefinitionItem>> response = getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<DeletedSasDefinitionItem>(response.body()) {
            @Override
            public Page<DeletedSasDefinitionItem> nextPage(String nextPageLink) {
                return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<DeletedSasDefinitionItem>> getDeletedSasDefinitionsNextAsync(final String nextPageLink, final ServiceFuture<List<DeletedSasDefinitionItem>> serviceFuture, final ListOperationCallback<DeletedSasDefinitionItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(String nextPageLink) {
                    return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<Page<DeletedSasDefinitionItem>> getDeletedSasDefinitionsNextAsync(final String nextPageLink) {
        return getDeletedSasDefinitionsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Page<DeletedSasDefinitionItem>>() {
                @Override
                public Page<DeletedSasDefinitionItem> call(ServiceResponse<Page<DeletedSasDefinitionItem>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;DeletedSasDefinitionItem&gt; object
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsNextWithServiceResponseAsync(final String nextPageLink) {
        return getDeletedSasDefinitionsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<DeletedSasDefinitionItem>>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(ServiceResponse<Page<DeletedSasDefinitionItem>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(getDeletedSasDefinitionsNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists deleted SAS definitions for the specified vault and storage account.
     * The Get Deleted Sas Definitions operation returns the SAS definitions that have been deleted for a vault enabled for soft-delete. This operation requires the storage/listsas permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;DeletedSasDefinitionItem&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> getDeletedSasDefinitionsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.getDeletedSasDefinitionsNext(nextUrl, this.acceptLanguage(), this.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>>>() {
                @Override
                public Observable<ServiceResponse<Page<DeletedSasDefinitionItem>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<DeletedSasDefinitionItem>> result = getDeletedSasDefinitionsNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<DeletedSasDefinitionItem>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<PageImpl<DeletedSasDefinitionItem>> getDeletedSasDefinitionsNextDelegate(Response<ResponseBody> response) throws KeyVaultErrorException, IOException, IllegalArgumentException {
        return this.restClient().responseBuilderFactory().<PageImpl<DeletedSasDefinitionItem>, KeyVaultErrorException>newInstance(this.serializerAdapter())
                .register(200, new TypeToken<PageImpl<DeletedSasDefinitionItem>>() { }.getType())
                .registerError(KeyVaultErrorException.class)
                .build(response);
    }

}
