/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 */

package com.microsoft.azure.batch.protocol.implementation;

import retrofit2.Retrofit;
import com.microsoft.azure.batch.protocol.Certificates;
import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.batch.protocol.models.BatchErrorException;
import com.microsoft.azure.batch.protocol.models.Certificate;
import com.microsoft.azure.batch.protocol.models.CertificateAddHeaders;
import com.microsoft.azure.batch.protocol.models.CertificateAddOptions;
import com.microsoft.azure.batch.protocol.models.CertificateAddParameter;
import com.microsoft.azure.batch.protocol.models.CertificateCancelDeletionHeaders;
import com.microsoft.azure.batch.protocol.models.CertificateCancelDeletionOptions;
import com.microsoft.azure.batch.protocol.models.CertificateDeleteHeaders;
import com.microsoft.azure.batch.protocol.models.CertificateDeleteOptions;
import com.microsoft.azure.batch.protocol.models.CertificateGetHeaders;
import com.microsoft.azure.batch.protocol.models.CertificateGetOptions;
import com.microsoft.azure.batch.protocol.models.CertificateListHeaders;
import com.microsoft.azure.batch.protocol.models.CertificateListNextOptions;
import com.microsoft.azure.batch.protocol.models.CertificateListOptions;
import com.microsoft.azure.batch.protocol.models.PageImpl;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
import com.microsoft.rest.DateTimeRfc1123;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponseWithHeaders;
import com.microsoft.rest.Validator;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import okhttp3.ResponseBody;
import org.joda.time.DateTime;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.HTTP;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.Url;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Certificates.
 */
public class CertificatesImpl implements Certificates {
    /** The Retrofit service to perform REST calls. */
    private CertificatesService service;
    /** The service client containing this operation class. */
    private BatchServiceClientImpl client;

    /**
     * Initializes an instance of CertificatesImpl.
     *
     * @param retrofit the Retrofit instance built from a Retrofit Builder.
     * @param client the instance of the service client containing this operation class.
     */
    public CertificatesImpl(Retrofit retrofit, BatchServiceClientImpl client) {
        this.service = retrofit.create(CertificatesService.class);
        this.client = client;
    }

    /**
     * The interface defining all the services for Certificates to be
     * used by Retrofit to perform actually REST calls.
     */
    interface CertificatesService {
        @Headers({ "Content-Type: application/json; odata=minimalmetadata; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Certificates add" })
        @POST("certificates")
        Observable<Response<ResponseBody>> add(@Body CertificateAddParameter certificate, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @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.batch.protocol.Certificates list" })
        @GET("certificates")
        Observable<Response<ResponseBody>> list(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$filter") String filter, @Query("$select") String select, @Query("maxresults") Integer maxResults, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @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.batch.protocol.Certificates cancelDeletion" })
        @POST("certificates(thumbprintAlgorithm={thumbprintAlgorithm},thumbprint={thumbprint})/canceldelete")
        Observable<Response<ResponseBody>> cancelDeletion(@Path("thumbprintAlgorithm") String thumbprintAlgorithm, @Path("thumbprint") String thumbprint, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @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.batch.protocol.Certificates delete" })
        @HTTP(path = "certificates(thumbprintAlgorithm={thumbprintAlgorithm},thumbprint={thumbprint})", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("thumbprintAlgorithm") String thumbprintAlgorithm, @Path("thumbprint") String thumbprint, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @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.batch.protocol.Certificates get" })
        @GET("certificates(thumbprintAlgorithm={thumbprintAlgorithm},thumbprint={thumbprint})")
        Observable<Response<ResponseBody>> get(@Path("thumbprintAlgorithm") String thumbprintAlgorithm, @Path("thumbprint") String thumbprint, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$select") String select, @Query("timeout") Integer timeout, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @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.batch.protocol.Certificates listNext" })
        @GET
        Observable<Response<ResponseBody>> listNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("client-request-id") UUID clientRequestId, @Header("return-client-request-id") Boolean returnClientRequestId, @Header("ocp-date") DateTimeRfc1123 ocpDate, @Header("User-Agent") String userAgent);

    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void add(CertificateAddParameter certificate) {
        addWithServiceResponseAsync(certificate).toBlocking().single().body();
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> addAsync(CertificateAddParameter certificate, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(certificate), serviceCallback);
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(CertificateAddParameter certificate) {
        return addWithServiceResponseAsync(certificate).map(new Func1<ServiceResponseWithHeaders<Void, CertificateAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>> addWithServiceResponseAsync(CertificateAddParameter certificate) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (certificate == null) {
            throw new IllegalArgumentException("Parameter certificate is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificate);
        final CertificateAddOptions certificateAddOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.add(certificate, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @param certificateAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void add(CertificateAddParameter certificate, CertificateAddOptions certificateAddOptions) {
        addWithServiceResponseAsync(certificate, certificateAddOptions).toBlocking().single().body();
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @param certificateAddOptions Additional parameters for the operation
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> addAsync(CertificateAddParameter certificate, CertificateAddOptions certificateAddOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(addWithServiceResponseAsync(certificate, certificateAddOptions), serviceCallback);
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @param certificateAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> addAsync(CertificateAddParameter certificate, CertificateAddOptions certificateAddOptions) {
        return addWithServiceResponseAsync(certificate, certificateAddOptions).map(new Func1<ServiceResponseWithHeaders<Void, CertificateAddHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateAddHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Adds a Certificate to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificate The Certificate to be added.
     * @param certificateAddOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>> addWithServiceResponseAsync(CertificateAddParameter certificate, CertificateAddOptions certificateAddOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (certificate == null) {
            throw new IllegalArgumentException("Parameter certificate is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificate);
        Validator.validate(certificateAddOptions);
        Integer timeout = null;
        if (certificateAddOptions != null) {
            timeout = certificateAddOptions.timeout();
        }
        UUID clientRequestId = null;
        if (certificateAddOptions != null) {
            clientRequestId = certificateAddOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateAddOptions != null) {
            returnClientRequestId = certificateAddOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateAddOptions != null) {
            ocpDate = certificateAddOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.add(certificate, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateAddHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateAddHeaders> clientResponse = addDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, CertificateAddHeaders> addDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<Void, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(201, new TypeToken<Void>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateAddHeaders.class);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;Certificate&gt; object if successful.
     */
    public PagedList<Certificate> list() {
        ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response = listSinglePageAsync().toBlocking().single();
        return new PagedList<Certificate>(response.body()) {
            @Override
            public Page<Certificate> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<Certificate>> listAsync(final ListOperationCallback<Certificate> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<Page<Certificate>> listAsync() {
        return listWithServiceResponseAsync()
            .map(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Page<Certificate>>() {
                @Override
                public Page<Certificate> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listWithServiceResponseAsync() {
        return listSinglePageAsync()
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;Certificate&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listSinglePageAsync() {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        final CertificateListOptions certificateListOptions = null;
        String filter = null;
        String select = null;
        Integer maxResults = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.list(this.client.apiVersion(), this.client.acceptLanguage(), filter, select, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificateListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;Certificate&gt; object if successful.
     */
    public PagedList<Certificate> list(final CertificateListOptions certificateListOptions) {
        ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response = listSinglePageAsync(certificateListOptions).toBlocking().single();
        return new PagedList<Certificate>(response.body()) {
            @Override
            public Page<Certificate> nextPage(String nextPageLink) {
                CertificateListNextOptions certificateListNextOptions = null;
                if (certificateListOptions != null) {
                    certificateListNextOptions = new CertificateListNextOptions();
                    certificateListNextOptions.withClientRequestId(certificateListOptions.clientRequestId());
                    certificateListNextOptions.withReturnClientRequestId(certificateListOptions.returnClientRequestId());
                    certificateListNextOptions.withOcpDate(certificateListOptions.ocpDate());
                }
                return listNextSinglePageAsync(nextPageLink, certificateListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificateListOptions Additional parameters for the operation
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<Certificate>> listAsync(final CertificateListOptions certificateListOptions, final ListOperationCallback<Certificate> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSinglePageAsync(certificateListOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(String nextPageLink) {
                    CertificateListNextOptions certificateListNextOptions = null;
                    if (certificateListOptions != null) {
                        certificateListNextOptions = new CertificateListNextOptions();
                        certificateListNextOptions.withClientRequestId(certificateListOptions.clientRequestId());
                        certificateListNextOptions.withReturnClientRequestId(certificateListOptions.returnClientRequestId());
                        certificateListNextOptions.withOcpDate(certificateListOptions.ocpDate());
                    }
                    return listNextSinglePageAsync(nextPageLink, certificateListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificateListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<Page<Certificate>> listAsync(final CertificateListOptions certificateListOptions) {
        return listWithServiceResponseAsync(certificateListOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Page<Certificate>>() {
                @Override
                public Page<Certificate> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param certificateListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listWithServiceResponseAsync(final CertificateListOptions certificateListOptions) {
        return listSinglePageAsync(certificateListOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    CertificateListNextOptions certificateListNextOptions = null;
                    if (certificateListOptions != null) {
                        certificateListNextOptions = new CertificateListNextOptions();
                        certificateListNextOptions.withClientRequestId(certificateListOptions.clientRequestId());
                        certificateListNextOptions.withReturnClientRequestId(certificateListOptions.returnClientRequestId());
                        certificateListNextOptions.withOcpDate(certificateListOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, certificateListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
    ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> * @param certificateListOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;Certificate&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listSinglePageAsync(final CertificateListOptions certificateListOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificateListOptions);
        String filter = null;
        if (certificateListOptions != null) {
            filter = certificateListOptions.filter();
        }
        String select = null;
        if (certificateListOptions != null) {
            select = certificateListOptions.select();
        }
        Integer maxResults = null;
        if (certificateListOptions != null) {
            maxResults = certificateListOptions.maxResults();
        }
        Integer timeout = null;
        if (certificateListOptions != null) {
            timeout = certificateListOptions.timeout();
        }
        UUID clientRequestId = null;
        if (certificateListOptions != null) {
            clientRequestId = certificateListOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateListOptions != null) {
            returnClientRequestId = certificateListOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateListOptions != null) {
            ocpDate = certificateListOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.list(this.client.apiVersion(), this.client.acceptLanguage(), filter, select, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> result = listDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> listDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<PageImpl<Certificate>, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<PageImpl<Certificate>>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateListHeaders.class);
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void cancelDeletion(String thumbprintAlgorithm, String thumbprint) {
        cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).toBlocking().single().body();
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> cancelDeletionAsync(String thumbprintAlgorithm, String thumbprint, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint), serviceCallback);
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> cancelDeletionAsync(String thumbprintAlgorithm, String thumbprint) {
        return cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).map(new Func1<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>> cancelDeletionWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        final CertificateCancelDeletionOptions certificateCancelDeletionOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.cancelDeletion(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders> clientResponse = cancelDeletionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @param certificateCancelDeletionOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void cancelDeletion(String thumbprintAlgorithm, String thumbprint, CertificateCancelDeletionOptions certificateCancelDeletionOptions) {
        cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateCancelDeletionOptions).toBlocking().single().body();
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @param certificateCancelDeletionOptions Additional parameters for the operation
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> cancelDeletionAsync(String thumbprintAlgorithm, String thumbprint, CertificateCancelDeletionOptions certificateCancelDeletionOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateCancelDeletionOptions), serviceCallback);
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @param certificateCancelDeletionOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> cancelDeletionAsync(String thumbprintAlgorithm, String thumbprint, CertificateCancelDeletionOptions certificateCancelDeletionOptions) {
        return cancelDeletionWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateCancelDeletionOptions).map(new Func1<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Cancels a failed deletion of a Certificate from the specified Account.
     * If you try to delete a Certificate that is being used by a Pool or Compute Node, the status of the Certificate changes to deleteFailed. If you decide that you want to continue using the Certificate, you can use this operation to set the status of the Certificate back to active. If you intend to delete the Certificate, you do not need to run this operation after the deletion failed. You must make sure that the Certificate is not being used by any resources, and then you can try again to delete the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate being deleted.
     * @param certificateCancelDeletionOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>> cancelDeletionWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint, CertificateCancelDeletionOptions certificateCancelDeletionOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificateCancelDeletionOptions);
        Integer timeout = null;
        if (certificateCancelDeletionOptions != null) {
            timeout = certificateCancelDeletionOptions.timeout();
        }
        UUID clientRequestId = null;
        if (certificateCancelDeletionOptions != null) {
            clientRequestId = certificateCancelDeletionOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateCancelDeletionOptions != null) {
            returnClientRequestId = certificateCancelDeletionOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateCancelDeletionOptions != null) {
            ocpDate = certificateCancelDeletionOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.cancelDeletion(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders> clientResponse = cancelDeletionDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, CertificateCancelDeletionHeaders> cancelDeletionDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<Void, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateCancelDeletionHeaders.class);
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void delete(String thumbprintAlgorithm, String thumbprint) {
        deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).toBlocking().single().body();
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> deleteAsync(String thumbprintAlgorithm, String thumbprint, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint), serviceCallback);
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> deleteAsync(String thumbprintAlgorithm, String thumbprint) {
        return deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).map(new Func1<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>> deleteWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        final CertificateDeleteOptions certificateDeleteOptions = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.delete(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @param certificateDeleteOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void delete(String thumbprintAlgorithm, String thumbprint, CertificateDeleteOptions certificateDeleteOptions) {
        deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateDeleteOptions).toBlocking().single().body();
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @param certificateDeleteOptions Additional parameters for the operation
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Void> deleteAsync(String thumbprintAlgorithm, String thumbprint, CertificateDeleteOptions certificateDeleteOptions, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateDeleteOptions), serviceCallback);
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @param certificateDeleteOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<Void> deleteAsync(String thumbprintAlgorithm, String thumbprint, CertificateDeleteOptions certificateDeleteOptions) {
        return deleteWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateDeleteOptions).map(new Func1<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>, Void>() {
            @Override
            public Void call(ServiceResponseWithHeaders<Void, CertificateDeleteHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes a Certificate from the specified Account.
     * You cannot delete a Certificate if a resource (Pool or Compute Node) is using it. Before you can delete a Certificate, you must therefore make sure that the Certificate is not associated with any existing Pools, the Certificate is not installed on any Nodes (even if you remove a Certificate from a Pool, it is not removed from existing Compute Nodes in that Pool until they restart), and no running Tasks depend on the Certificate. If you try to delete a Certificate that is in use, the deletion fails. The Certificate status changes to deleteFailed. You can use Cancel Delete Certificate to set the status back to active if you decide that you want to continue using the Certificate.
     Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to be deleted.
     * @param certificateDeleteOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponseWithHeaders} object if successful.
     */
    public Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>> deleteWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint, CertificateDeleteOptions certificateDeleteOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificateDeleteOptions);
        Integer timeout = null;
        if (certificateDeleteOptions != null) {
            timeout = certificateDeleteOptions.timeout();
        }
        UUID clientRequestId = null;
        if (certificateDeleteOptions != null) {
            clientRequestId = certificateDeleteOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateDeleteOptions != null) {
            returnClientRequestId = certificateDeleteOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateDeleteOptions != null) {
            ocpDate = certificateDeleteOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.delete(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Void, CertificateDeleteHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Void, CertificateDeleteHeaders> clientResponse = deleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Void, CertificateDeleteHeaders> deleteDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<Void, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(202, new TypeToken<Void>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateDeleteHeaders.class);
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Certificate object if successful.
     */
    public Certificate get(String thumbprintAlgorithm, String thumbprint) {
        return getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Certificate> getAsync(String thumbprintAlgorithm, String thumbprint, final ServiceCallback<Certificate> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint), serviceCallback);
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Certificate object
     */
    public Observable<Certificate> getAsync(String thumbprintAlgorithm, String thumbprint) {
        return getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint).map(new Func1<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>, Certificate>() {
            @Override
            public Certificate call(ServiceResponseWithHeaders<Certificate, CertificateGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Certificate object
     */
    public Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>> getWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        final CertificateGetOptions certificateGetOptions = null;
        String select = null;
        Integer timeout = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.get(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), select, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Certificate, CertificateGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @param certificateGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the Certificate object if successful.
     */
    public Certificate get(String thumbprintAlgorithm, String thumbprint, CertificateGetOptions certificateGetOptions) {
        return getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateGetOptions).toBlocking().single().body();
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @param certificateGetOptions Additional parameters for the operation
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<Certificate> getAsync(String thumbprintAlgorithm, String thumbprint, CertificateGetOptions certificateGetOptions, final ServiceCallback<Certificate> serviceCallback) {
        return ServiceFuture.fromHeaderResponse(getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateGetOptions), serviceCallback);
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @param certificateGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Certificate object
     */
    public Observable<Certificate> getAsync(String thumbprintAlgorithm, String thumbprint, CertificateGetOptions certificateGetOptions) {
        return getWithServiceResponseAsync(thumbprintAlgorithm, thumbprint, certificateGetOptions).map(new Func1<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>, Certificate>() {
            @Override
            public Certificate call(ServiceResponseWithHeaders<Certificate, CertificateGetHeaders> response) {
                return response.body();
            }
        });
    }

    /**
     * Gets information about the specified Certificate.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param thumbprintAlgorithm The algorithm used to derive the thumbprint parameter. This must be sha1.
     * @param thumbprint The thumbprint of the Certificate to get.
     * @param certificateGetOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the Certificate object
     */
    public Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>> getWithServiceResponseAsync(String thumbprintAlgorithm, String thumbprint, CertificateGetOptions certificateGetOptions) {
        if (this.client.batchUrl() == null) {
            throw new IllegalArgumentException("Parameter this.client.batchUrl() is required and cannot be null.");
        }
        if (thumbprintAlgorithm == null) {
            throw new IllegalArgumentException("Parameter thumbprintAlgorithm is required and cannot be null.");
        }
        if (thumbprint == null) {
            throw new IllegalArgumentException("Parameter thumbprint is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(certificateGetOptions);
        String select = null;
        if (certificateGetOptions != null) {
            select = certificateGetOptions.select();
        }
        Integer timeout = null;
        if (certificateGetOptions != null) {
            timeout = certificateGetOptions.timeout();
        }
        UUID clientRequestId = null;
        if (certificateGetOptions != null) {
            clientRequestId = certificateGetOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateGetOptions != null) {
            returnClientRequestId = certificateGetOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateGetOptions != null) {
            ocpDate = certificateGetOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.get(thumbprintAlgorithm, thumbprint, this.client.apiVersion(), this.client.acceptLanguage(), select, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Certificate, CertificateGetHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<Certificate, CertificateGetHeaders> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<Certificate, CertificateGetHeaders> getDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<Certificate, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<Certificate>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateGetHeaders.class);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;Certificate&gt; object if successful.
     */
    public PagedList<Certificate> listNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response = listNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<Certificate>(response.body()) {
            @Override
            public Page<Certificate> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<Certificate>> listNextAsync(final String nextPageLink, final ServiceFuture<List<Certificate>> serviceFuture, final ListOperationCallback<Certificate> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<Page<Certificate>> listNextAsync(final String nextPageLink) {
        return listNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Page<Certificate>>() {
                @Override
                public Page<Certificate> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink) {
        return listNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;Certificate&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final CertificateListNextOptions certificateListNextOptions = null;
        UUID clientRequestId = null;
        Boolean returnClientRequestId = null;
        DateTime ocpDate = null;
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param certificateListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws BatchErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;Certificate&gt; object if successful.
     */
    public PagedList<Certificate> listNext(final String nextPageLink, final CertificateListNextOptions certificateListNextOptions) {
        ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response = listNextSinglePageAsync(nextPageLink, certificateListNextOptions).toBlocking().single();
        return new PagedList<Certificate>(response.body()) {
            @Override
            public Page<Certificate> nextPage(String nextPageLink) {
                return listNextSinglePageAsync(nextPageLink, certificateListNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param certificateListNextOptions Additional parameters for the operation
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<Certificate>> listNextAsync(final String nextPageLink, final CertificateListNextOptions certificateListNextOptions, final ServiceFuture<List<Certificate>> serviceFuture, final ListOperationCallback<Certificate> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listNextSinglePageAsync(nextPageLink, certificateListNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(String nextPageLink) {
                    return listNextSinglePageAsync(nextPageLink, certificateListNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param certificateListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<Page<Certificate>> listNextAsync(final String nextPageLink, final CertificateListNextOptions certificateListNextOptions) {
        return listNextWithServiceResponseAsync(nextPageLink, certificateListNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Page<Certificate>>() {
                @Override
                public Page<Certificate> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param certificateListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;Certificate&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listNextWithServiceResponseAsync(final String nextPageLink, final CertificateListNextOptions certificateListNextOptions) {
        return listNextSinglePageAsync(nextPageLink, certificateListNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listNextWithServiceResponseAsync(nextPageLink, certificateListNextOptions));
                }
            });
    }

    /**
     * Lists all of the Certificates that have been added to the specified Account.
     * Warning: This operation is deprecated and will be removed after February, 2024. Please use the [Azure KeyVault Extension](https://learn.microsoft.com/azure/batch/batch-certificate-migration-guide) instead.
     *
    ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> * @param certificateListNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;Certificate&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> listNextSinglePageAsync(final String nextPageLink, final CertificateListNextOptions certificateListNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(certificateListNextOptions);
        UUID clientRequestId = null;
        if (certificateListNextOptions != null) {
            clientRequestId = certificateListNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (certificateListNextOptions != null) {
            returnClientRequestId = certificateListNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (certificateListNextOptions != null) {
            ocpDate = certificateListNextOptions.ocpDate();
        }
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> result = listNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<Certificate>, CertificateListHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponseWithHeaders<PageImpl<Certificate>, CertificateListHeaders> listNextDelegate(Response<ResponseBody> response) throws BatchErrorException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<PageImpl<Certificate>, BatchErrorException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<PageImpl<Certificate>>() { }.getType())
                .registerError(BatchErrorException.class)
                .buildWithHeaders(response, CertificateListHeaders.class);
    }

}
