// 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;

import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureClient;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.AzureServiceClient;
import com.microsoft.azure.keyvault.models.BackupKeyResult;
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.CertificateUpdateParameters;
import com.microsoft.azure.keyvault.models.Contacts;
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.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.SecretAttributes;
import com.microsoft.azure.keyvault.models.SecretBundle;
import com.microsoft.azure.keyvault.models.SecretItem;
import com.microsoft.azure.keyvault.models.SecretSetParameters;
import com.microsoft.azure.keyvault.models.SecretUpdateParameters;
import com.microsoft.azure.keyvault.webkey.JsonWebKey;
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.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.ServiceFuture;
import com.microsoft.rest.ServiceCallback;
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 KeyVaultClientImpl class.
 */
final class KeyVaultClientImpl extends AzureServiceClient {
    /** The Retrofit service to perform REST calls. */
    private KeyVaultClientService 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 KeyVaultClientImpl 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 KeyVaultClientImpl 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 KeyVaultClientImpl withGenerateClientRequestId(boolean generateClientRequestId) {
        this.generateClientRequestId = generateClientRequestId;
        return this;
    }

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

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

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

    protected void initialize() {
        this.apiVersion = "2016-10-01";
        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("Azure-SDK-For-Java/%s (%s)",
                getClass().getPackage().getImplementationVersion(),
                "KeyVaultClient, 2016-10-01");
    }

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

    /**
     * The interface defining all the services for KeyVaultClient to be
     * used by Retrofit to perform actually REST calls.
     */
    interface KeyVaultClientService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.keyvault.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient getCertificates" })
        @GET("certificates")
        Observable<Response<ResponseBody>> getCertificates(@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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient 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.KeyVaultClient getCertificateVersionsNext" })
        @GET
        Observable<Response<ResponseBody>> getCertificateVersionsNext(@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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @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;
        KeyCreateParameters parameters = new KeyCreateParameters();
        parameters.withKty(kty);
        parameters.withKeySize(null);
        parameters.withKeyOps(null);
        parameters.withKeyAttributes(null);
        parameters.withTags(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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bytes. For example, 1024 or 2048.
     * @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.
     * @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) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags).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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bytes. For example, 1024 or 2048.
     * @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 serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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, final ServiceCallback<KeyBundle> serviceCallback) {
        return ServiceFuture.fromResponse(createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags), 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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bytes. For example, 1024 or 2048.
     * @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.
     * @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) {
        return createKeyWithServiceResponseAsync(vaultBaseUrl, keyName, kty, keySize, keyOps, keyAttributes, tags).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. Authorization: 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 key types, see JsonWebKeyType. Supported JsonWebKey key types (kty) for Elliptic Curve, RSA, HSM, Octet. Possible values include: 'EC', 'RSA', 'RSA-HSM', 'oct'
     * @param keySize The key size in bytes. For example, 1024 or 2048.
     * @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.
     * @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) {
        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);
        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. Authorization: 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
     * @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. Authorization: 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.
     * @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. Authorization: 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
     * @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. Authorization: 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
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @return the KeyBundle object if successful.
     */
    public KeyBundle 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. Authorization: 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.
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<KeyBundle> deleteKeyAsync(String vaultBaseUrl, String keyName, final ServiceCallback<KeyBundle> 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. Authorization: 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.
     * @return the observable to the KeyBundle object
     */
    public Observable<KeyBundle> deleteKeyAsync(String vaultBaseUrl, String keyName) {
        return deleteKeyWithServiceResponseAsync(vaultBaseUrl, keyName).map(new Func1<ServiceResponse<KeyBundle>, KeyBundle>() {
            @Override
            public KeyBundle call(ServiceResponse<KeyBundle> 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. Authorization: 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.
     * @return the observable to the KeyBundle object
     */
    public Observable<ServiceResponse<KeyBundle>> 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<KeyBundle>>>() {
                @Override
                public Observable<ServiceResponse<KeyBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<KeyBundle> clientResponse = deleteKeyDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<KeyBundle> deleteKeyDelegate(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);
    }

    /**
     * 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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. The cryptographic material of a key itself cannot be changed. In order to perform this operation, the key must already exist in the Key Vault. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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. Authorization: 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.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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. Authorization: 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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyBundleBackup The backup blob associated with a key bundle.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param value the Base64Url value
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param value the Base64Url value
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param value the Base64Url value
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @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.
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @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.
     *
     * @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: 'RS256', 'RS384', 'RS512', 'RSNULL'
     * @param digest The digest used for signing.
     * @param signature The signature to be verified.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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.
     *
     * @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', 'RSA1_5'
     * @param value the Base64Url value
     * @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);
    }

    /**
     * Sets a secret in a specified key vault.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @return the SecretBundle object if successful.
     */
    public SecretBundle deleteSecret(String vaultBaseUrl, String secretName) {
        return deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName).toBlocking().single().body();
    }

    /**
     * Deletes a secret from a specified key vault.
     *
     * @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.
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<SecretBundle> deleteSecretAsync(String vaultBaseUrl, String secretName, final ServiceCallback<SecretBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName), serviceCallback);
    }

    /**
     * Deletes a secret from a specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @return the observable to the SecretBundle object
     */
    public Observable<SecretBundle> deleteSecretAsync(String vaultBaseUrl, String secretName) {
        return deleteSecretWithServiceResponseAsync(vaultBaseUrl, secretName).map(new Func1<ServiceResponse<SecretBundle>, SecretBundle>() {
            @Override
            public SecretBundle call(ServiceResponse<SecretBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a secret from a specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @return the observable to the SecretBundle object
     */
    public Observable<ServiceResponse<SecretBundle>> 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<SecretBundle>>>() {
                @Override
                public Observable<ServiceResponse<SecretBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<SecretBundle> clientResponse = deleteSecretDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<SecretBundle> deleteSecretDelegate(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);
    }

    /**
     * Updates the attributes associated with a specified secret in a given key vault.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @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 the versions of the specified secret.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @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 the versions of the specified secret.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param secretName The name of the secret.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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 the versions of the specified secret.
     *
     * @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.
     * @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);
    }

    /**
     * List certificates in a specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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;
        String parameterizedHost = Joiner.on(", ").join("{vaultBaseUrl}", vaultBaseUrl);
        return service.getCertificates(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 = 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.
     *
     * @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.
     * @return the PagedList&lt;CertificateItem&gt; object if successful.
     */
    public PagedList<CertificateItem> getCertificates(final String vaultBaseUrl, final Integer maxresults) {
        ServiceResponse<Page<CertificateItem>> response = getCertificatesSinglePageAsync(vaultBaseUrl, maxresults).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.
     *
     * @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.
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl, final Integer maxresults, final ListOperationCallback<CertificateItem> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            getCertificatesSinglePageAsync(vaultBaseUrl, maxresults),
            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.
     *
     * @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.
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<Page<CertificateItem>> getCertificatesAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getCertificatesWithServiceResponseAsync(vaultBaseUrl, maxresults)
            .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.
     *
     * @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.
     * @return the observable to the PagedList&lt;CertificateItem&gt; object
     */
    public Observable<ServiceResponse<Page<CertificateItem>>> getCertificatesWithServiceResponseAsync(final String vaultBaseUrl, final Integer maxresults) {
        return getCertificatesSinglePageAsync(vaultBaseUrl, 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(getCertificatesNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * List certificates in a specified key vault.
     *
     * @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.
     * @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) {
        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, 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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @return the CertificateBundle object if successful.
     */
    public CertificateBundle deleteCertificate(String vaultBaseUrl, String certificateName) {
        return deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Deletes a certificate from a specified key vault.
     *
     * @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.
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<CertificateBundle> deleteCertificateAsync(String vaultBaseUrl, String certificateName, final ServiceCallback<CertificateBundle> serviceCallback) {
        return ServiceFuture.fromResponse(deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName), serviceCallback);
    }

    /**
     * Deletes a certificate from a specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @return the observable to the CertificateBundle object
     */
    public Observable<CertificateBundle> deleteCertificateAsync(String vaultBaseUrl, String certificateName) {
        return deleteCertificateWithServiceResponseAsync(vaultBaseUrl, certificateName).map(new Func1<ServiceResponse<CertificateBundle>, CertificateBundle>() {
            @Override
            public CertificateBundle call(ServiceResponse<CertificateBundle> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a certificate from a specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @return the observable to the CertificateBundle object
     */
    public Observable<ServiceResponse<CertificateBundle>> 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<CertificateBundle>>>() {
                @Override
                public Observable<ServiceResponse<CertificateBundle>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<CertificateBundle> clientResponse = deleteCertificateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<CertificateBundle> deleteCertificateDelegate(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);
    }

    /**
     * Sets the certificate contacts for the specified key vault.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param contacts The contacts for the key vault certificate.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @param provider The issuer provider.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param issuerName The name of the issuer.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @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.
     *
     * @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.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @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.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate in a given key vault.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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 specified certificate.
     *
     * @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.
     * @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 specified certificate.
     *
     * @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.
     * @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 specified certificate.
     *
     * @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.
     * @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 specified certificate.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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 operation associated with a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation getCertificateOperation(String vaultBaseUrl, String certificateName) {
        return getCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Gets the operation associated with a specified certificate.
     *
     * @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.
     * @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 operation associated with a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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 operation associated with a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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 operation for a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @return the CertificateOperation object if successful.
     */
    public CertificateOperation deleteCertificateOperation(String vaultBaseUrl, String certificateName) {
        return deleteCertificateOperationWithServiceResponseAsync(vaultBaseUrl, certificateName).toBlocking().single().body();
    }

    /**
     * Deletes the operation for a specified certificate.
     *
     * @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.
     * @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 operation for a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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 operation for a specified certificate.
     *
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param certificateName The name of the certificate.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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.
     *
     * @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.
     * @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);
    }

    /**
     * Retrieves a list of individual key versions with the same key name. The full key identifier, attributes, and tags are provided in the response. Authorization: Requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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. Authorization: Requires the keys/list permission.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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);
    }

    /**
     * List secrets in a specified key vault.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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 the versions of the specified secret.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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 the versions of the specified secret.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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 the versions of the specified secret.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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 the versions of the specified secret.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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 the versions of the specified secret.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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);
    }

    /**
     * List certificates in a specified key vault.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceCall object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @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);
    }

}
