/**
 * 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.Accounts;
import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.batch.protocol.models.AccountListPoolNodeCountsHeaders;
import com.microsoft.azure.batch.protocol.models.AccountListPoolNodeCountsNextOptions;
import com.microsoft.azure.batch.protocol.models.AccountListPoolNodeCountsOptions;
import com.microsoft.azure.batch.protocol.models.AccountListSupportedImagesHeaders;
import com.microsoft.azure.batch.protocol.models.AccountListSupportedImagesNextOptions;
import com.microsoft.azure.batch.protocol.models.AccountListSupportedImagesOptions;
import com.microsoft.azure.batch.protocol.models.BatchErrorException;
import com.microsoft.azure.batch.protocol.models.ImageInformation;
import com.microsoft.azure.batch.protocol.models.PageImpl;
import com.microsoft.azure.batch.protocol.models.PoolNodeCounts;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
import com.microsoft.rest.DateTimeRfc1123;
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.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
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 Accounts.
 */
public class AccountsImpl implements Accounts {
    /** The Retrofit service to perform REST calls. */
    private AccountsService service;
    /** The service client containing this operation class. */
    private BatchServiceClientImpl client;

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

    /**
     * The interface defining all the services for Accounts to be
     * used by Retrofit to perform actually REST calls.
     */
    interface AccountsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Accounts listSupportedImages" })
        @GET("supportedimages")
        Observable<Response<ResponseBody>> listSupportedImages(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$filter") String filter, @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.Accounts listPoolNodeCounts" })
        @GET("nodecounts")
        Observable<Response<ResponseBody>> listPoolNodeCounts(@Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Query("$filter") String filter, @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.Accounts listSupportedImagesNext" })
        @GET
        Observable<Response<ResponseBody>> listSupportedImagesNext(@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);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.batch.protocol.Accounts listPoolNodeCountsNext" })
        @GET
        Observable<Response<ResponseBody>> listPoolNodeCountsNext(@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);

    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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;ImageInformation&gt; object if successful.
     */
    public PagedList<ImageInformation> listSupportedImages() {
        ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response = listSupportedImagesSinglePageAsync().toBlocking().single();
        return new PagedList<ImageInformation>(response.body()) {
            @Override
            public Page<ImageInformation> nextPage(String nextPageLink) {
                return listSupportedImagesNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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<ImageInformation>> listSupportedImagesAsync(final ListOperationCallback<ImageInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSupportedImagesSinglePageAsync(),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(String nextPageLink) {
                    return listSupportedImagesNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<Page<ImageInformation>> listSupportedImagesAsync() {
        return listSupportedImagesWithServiceResponseAsync()
            .map(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Page<ImageInformation>>() {
                @Override
                public Page<ImageInformation> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesWithServiceResponseAsync() {
        return listSupportedImagesSinglePageAsync()
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listSupportedImagesNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;ImageInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesSinglePageAsync() {
        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 AccountListSupportedImagesOptions accountListSupportedImagesOptions = null;
        String filter = 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.listSupportedImages(this.client.apiVersion(), this.client.acceptLanguage(), filter, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> result = listSupportedImagesDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param accountListSupportedImagesOptions 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;ImageInformation&gt; object if successful.
     */
    public PagedList<ImageInformation> listSupportedImages(final AccountListSupportedImagesOptions accountListSupportedImagesOptions) {
        ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response = listSupportedImagesSinglePageAsync(accountListSupportedImagesOptions).toBlocking().single();
        return new PagedList<ImageInformation>(response.body()) {
            @Override
            public Page<ImageInformation> nextPage(String nextPageLink) {
                AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions = null;
                if (accountListSupportedImagesOptions != null) {
                    accountListSupportedImagesNextOptions = new AccountListSupportedImagesNextOptions();
                    accountListSupportedImagesNextOptions.withClientRequestId(accountListSupportedImagesOptions.clientRequestId());
                    accountListSupportedImagesNextOptions.withReturnClientRequestId(accountListSupportedImagesOptions.returnClientRequestId());
                    accountListSupportedImagesNextOptions.withOcpDate(accountListSupportedImagesOptions.ocpDate());
                }
                return listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param accountListSupportedImagesOptions 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<ImageInformation>> listSupportedImagesAsync(final AccountListSupportedImagesOptions accountListSupportedImagesOptions, final ListOperationCallback<ImageInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSupportedImagesSinglePageAsync(accountListSupportedImagesOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(String nextPageLink) {
                    AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions = null;
                    if (accountListSupportedImagesOptions != null) {
                        accountListSupportedImagesNextOptions = new AccountListSupportedImagesNextOptions();
                        accountListSupportedImagesNextOptions.withClientRequestId(accountListSupportedImagesOptions.clientRequestId());
                        accountListSupportedImagesNextOptions.withReturnClientRequestId(accountListSupportedImagesOptions.returnClientRequestId());
                        accountListSupportedImagesNextOptions.withOcpDate(accountListSupportedImagesOptions.ocpDate());
                    }
                    return listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param accountListSupportedImagesOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<Page<ImageInformation>> listSupportedImagesAsync(final AccountListSupportedImagesOptions accountListSupportedImagesOptions) {
        return listSupportedImagesWithServiceResponseAsync(accountListSupportedImagesOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Page<ImageInformation>>() {
                @Override
                public Page<ImageInformation> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param accountListSupportedImagesOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesWithServiceResponseAsync(final AccountListSupportedImagesOptions accountListSupportedImagesOptions) {
        return listSupportedImagesSinglePageAsync(accountListSupportedImagesOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions = null;
                    if (accountListSupportedImagesOptions != null) {
                        accountListSupportedImagesNextOptions = new AccountListSupportedImagesNextOptions();
                        accountListSupportedImagesNextOptions.withClientRequestId(accountListSupportedImagesOptions.clientRequestId());
                        accountListSupportedImagesNextOptions.withReturnClientRequestId(accountListSupportedImagesOptions.returnClientRequestId());
                        accountListSupportedImagesNextOptions.withOcpDate(accountListSupportedImagesOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listSupportedImagesNextWithServiceResponseAsync(nextPageLink, accountListSupportedImagesNextOptions));
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
    ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> * @param accountListSupportedImagesOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;ImageInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesSinglePageAsync(final AccountListSupportedImagesOptions accountListSupportedImagesOptions) {
        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(accountListSupportedImagesOptions);
        String filter = null;
        if (accountListSupportedImagesOptions != null) {
            filter = accountListSupportedImagesOptions.filter();
        }
        Integer maxResults = null;
        if (accountListSupportedImagesOptions != null) {
            maxResults = accountListSupportedImagesOptions.maxResults();
        }
        Integer timeout = null;
        if (accountListSupportedImagesOptions != null) {
            timeout = accountListSupportedImagesOptions.timeout();
        }
        UUID clientRequestId = null;
        if (accountListSupportedImagesOptions != null) {
            clientRequestId = accountListSupportedImagesOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (accountListSupportedImagesOptions != null) {
            returnClientRequestId = accountListSupportedImagesOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (accountListSupportedImagesOptions != null) {
            ocpDate = accountListSupportedImagesOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listSupportedImages(this.client.apiVersion(), this.client.acceptLanguage(), filter, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> result = listSupportedImagesDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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;PoolNodeCounts&gt; object if successful.
     */
    public PagedList<PoolNodeCounts> listPoolNodeCounts() {
        ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response = listPoolNodeCountsSinglePageAsync().toBlocking().single();
        return new PagedList<PoolNodeCounts>(response.body()) {
            @Override
            public Page<PoolNodeCounts> nextPage(String nextPageLink) {
                return listPoolNodeCountsNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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<PoolNodeCounts>> listPoolNodeCountsAsync(final ListOperationCallback<PoolNodeCounts> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPoolNodeCountsSinglePageAsync(),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(String nextPageLink) {
                    return listPoolNodeCountsNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<Page<PoolNodeCounts>> listPoolNodeCountsAsync() {
        return listPoolNodeCountsWithServiceResponseAsync()
            .map(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Page<PoolNodeCounts>>() {
                @Override
                public Page<PoolNodeCounts> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsWithServiceResponseAsync() {
        return listPoolNodeCountsSinglePageAsync()
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;PoolNodeCounts&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsSinglePageAsync() {
        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 AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions = null;
        String filter = 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.listPoolNodeCounts(this.client.apiVersion(), this.client.acceptLanguage(), filter, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> result = listPoolNodeCountsDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param accountListPoolNodeCountsOptions 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;PoolNodeCounts&gt; object if successful.
     */
    public PagedList<PoolNodeCounts> listPoolNodeCounts(final AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions) {
        ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response = listPoolNodeCountsSinglePageAsync(accountListPoolNodeCountsOptions).toBlocking().single();
        return new PagedList<PoolNodeCounts>(response.body()) {
            @Override
            public Page<PoolNodeCounts> nextPage(String nextPageLink) {
                AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions = null;
                if (accountListPoolNodeCountsOptions != null) {
                    accountListPoolNodeCountsNextOptions = new AccountListPoolNodeCountsNextOptions();
                    accountListPoolNodeCountsNextOptions.withClientRequestId(accountListPoolNodeCountsOptions.clientRequestId());
                    accountListPoolNodeCountsNextOptions.withReturnClientRequestId(accountListPoolNodeCountsOptions.returnClientRequestId());
                    accountListPoolNodeCountsNextOptions.withOcpDate(accountListPoolNodeCountsOptions.ocpDate());
                }
                return listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param accountListPoolNodeCountsOptions 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<PoolNodeCounts>> listPoolNodeCountsAsync(final AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions, final ListOperationCallback<PoolNodeCounts> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPoolNodeCountsSinglePageAsync(accountListPoolNodeCountsOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(String nextPageLink) {
                    AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions = null;
                    if (accountListPoolNodeCountsOptions != null) {
                        accountListPoolNodeCountsNextOptions = new AccountListPoolNodeCountsNextOptions();
                        accountListPoolNodeCountsNextOptions.withClientRequestId(accountListPoolNodeCountsOptions.clientRequestId());
                        accountListPoolNodeCountsNextOptions.withReturnClientRequestId(accountListPoolNodeCountsOptions.returnClientRequestId());
                        accountListPoolNodeCountsNextOptions.withOcpDate(accountListPoolNodeCountsOptions.ocpDate());
                    }
                    return listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param accountListPoolNodeCountsOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<Page<PoolNodeCounts>> listPoolNodeCountsAsync(final AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions) {
        return listPoolNodeCountsWithServiceResponseAsync(accountListPoolNodeCountsOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Page<PoolNodeCounts>>() {
                @Override
                public Page<PoolNodeCounts> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param accountListPoolNodeCountsOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsWithServiceResponseAsync(final AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions) {
        return listPoolNodeCountsSinglePageAsync(accountListPoolNodeCountsOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions = null;
                    if (accountListPoolNodeCountsOptions != null) {
                        accountListPoolNodeCountsNextOptions = new AccountListPoolNodeCountsNextOptions();
                        accountListPoolNodeCountsNextOptions.withClientRequestId(accountListPoolNodeCountsOptions.clientRequestId());
                        accountListPoolNodeCountsNextOptions.withReturnClientRequestId(accountListPoolNodeCountsOptions.returnClientRequestId());
                        accountListPoolNodeCountsNextOptions.withOcpDate(accountListPoolNodeCountsOptions.ocpDate());
                    }
                    return Observable.just(page).concatWith(listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink, accountListPoolNodeCountsNextOptions));
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
    ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> * @param accountListPoolNodeCountsOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;PoolNodeCounts&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsSinglePageAsync(final AccountListPoolNodeCountsOptions accountListPoolNodeCountsOptions) {
        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(accountListPoolNodeCountsOptions);
        String filter = null;
        if (accountListPoolNodeCountsOptions != null) {
            filter = accountListPoolNodeCountsOptions.filter();
        }
        Integer maxResults = null;
        if (accountListPoolNodeCountsOptions != null) {
            maxResults = accountListPoolNodeCountsOptions.maxResults();
        }
        Integer timeout = null;
        if (accountListPoolNodeCountsOptions != null) {
            timeout = accountListPoolNodeCountsOptions.timeout();
        }
        UUID clientRequestId = null;
        if (accountListPoolNodeCountsOptions != null) {
            clientRequestId = accountListPoolNodeCountsOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (accountListPoolNodeCountsOptions != null) {
            returnClientRequestId = accountListPoolNodeCountsOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (accountListPoolNodeCountsOptions != null) {
            ocpDate = accountListPoolNodeCountsOptions.ocpDate();
        }
        String parameterizedHost = Joiner.on(", ").join("{batchUrl}", this.client.batchUrl());
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        return service.listPoolNodeCounts(this.client.apiVersion(), this.client.acceptLanguage(), filter, maxResults, timeout, clientRequestId, returnClientRequestId, ocpDateConverted, parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> result = listPoolNodeCountsDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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;ImageInformation&gt; object if successful.
     */
    public PagedList<ImageInformation> listSupportedImagesNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response = listSupportedImagesNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<ImageInformation>(response.body()) {
            @Override
            public Page<ImageInformation> nextPage(String nextPageLink) {
                return listSupportedImagesNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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<ImageInformation>> listSupportedImagesNextAsync(final String nextPageLink, final ServiceFuture<List<ImageInformation>> serviceFuture, final ListOperationCallback<ImageInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSupportedImagesNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(String nextPageLink) {
                    return listSupportedImagesNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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;ImageInformation&gt; object
     */
    public Observable<Page<ImageInformation>> listSupportedImagesNextAsync(final String nextPageLink) {
        return listSupportedImagesNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Page<ImageInformation>>() {
                @Override
                public Page<ImageInformation> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @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;ImageInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesNextWithServiceResponseAsync(final String nextPageLink) {
        return listSupportedImagesNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listSupportedImagesNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;ImageInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions = 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.listSupportedImagesNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> result = listSupportedImagesNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListSupportedImagesNextOptions 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;ImageInformation&gt; object if successful.
     */
    public PagedList<ImageInformation> listSupportedImagesNext(final String nextPageLink, final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions) {
        ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response = listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions).toBlocking().single();
        return new PagedList<ImageInformation>(response.body()) {
            @Override
            public Page<ImageInformation> nextPage(String nextPageLink) {
                return listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListSupportedImagesNextOptions 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<ImageInformation>> listSupportedImagesNextAsync(final String nextPageLink, final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions, final ServiceFuture<List<ImageInformation>> serviceFuture, final ListOperationCallback<ImageInformation> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(String nextPageLink) {
                    return listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListSupportedImagesNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<Page<ImageInformation>> listSupportedImagesNextAsync(final String nextPageLink, final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions) {
        return listSupportedImagesNextWithServiceResponseAsync(nextPageLink, accountListSupportedImagesNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Page<ImageInformation>>() {
                @Override
                public Page<ImageInformation> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListSupportedImagesNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;ImageInformation&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesNextWithServiceResponseAsync(final String nextPageLink, final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions) {
        return listSupportedImagesNextSinglePageAsync(nextPageLink, accountListSupportedImagesNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listSupportedImagesNextWithServiceResponseAsync(nextPageLink, accountListSupportedImagesNextOptions));
                }
            });
    }

    /**
     * Lists all Virtual Machine Images supported by the Azure Batch service.
     *
    ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> * @param accountListSupportedImagesNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;ImageInformation&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> listSupportedImagesNextSinglePageAsync(final String nextPageLink, final AccountListSupportedImagesNextOptions accountListSupportedImagesNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(accountListSupportedImagesNextOptions);
        UUID clientRequestId = null;
        if (accountListSupportedImagesNextOptions != null) {
            clientRequestId = accountListSupportedImagesNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (accountListSupportedImagesNextOptions != null) {
            returnClientRequestId = accountListSupportedImagesNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (accountListSupportedImagesNextOptions != null) {
            ocpDate = accountListSupportedImagesNextOptions.ocpDate();
        }
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listSupportedImagesNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<ImageInformation>, AccountListSupportedImagesHeaders> result = listSupportedImagesNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<ImageInformation>, AccountListSupportedImagesHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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;PoolNodeCounts&gt; object if successful.
     */
    public PagedList<PoolNodeCounts> listPoolNodeCountsNext(final String nextPageLink) {
        ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response = listPoolNodeCountsNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<PoolNodeCounts>(response.body()) {
            @Override
            public Page<PoolNodeCounts> nextPage(String nextPageLink) {
                return listPoolNodeCountsNextSinglePageAsync(nextPageLink, null).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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<PoolNodeCounts>> listPoolNodeCountsNextAsync(final String nextPageLink, final ServiceFuture<List<PoolNodeCounts>> serviceFuture, final ListOperationCallback<PoolNodeCounts> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPoolNodeCountsNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(String nextPageLink) {
                    return listPoolNodeCountsNextSinglePageAsync(nextPageLink, null);
                }
            },
            serviceCallback);
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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;PoolNodeCounts&gt; object
     */
    public Observable<Page<PoolNodeCounts>> listPoolNodeCountsNextAsync(final String nextPageLink) {
        return listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Page<PoolNodeCounts>>() {
                @Override
                public Page<PoolNodeCounts> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @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;PoolNodeCounts&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsNextWithServiceResponseAsync(final String nextPageLink) {
        return listPoolNodeCountsNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink, null));
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;PoolNodeCounts&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions = 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.listPoolNodeCountsNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> result = listPoolNodeCountsNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListPoolNodeCountsNextOptions 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;PoolNodeCounts&gt; object if successful.
     */
    public PagedList<PoolNodeCounts> listPoolNodeCountsNext(final String nextPageLink, final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions) {
        ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response = listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions).toBlocking().single();
        return new PagedList<PoolNodeCounts>(response.body()) {
            @Override
            public Page<PoolNodeCounts> nextPage(String nextPageLink) {
                return listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions).toBlocking().single().body();
            }
        };
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListPoolNodeCountsNextOptions 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<PoolNodeCounts>> listPoolNodeCountsNextAsync(final String nextPageLink, final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions, final ServiceFuture<List<PoolNodeCounts>> serviceFuture, final ListOperationCallback<PoolNodeCounts> serviceCallback) {
        return AzureServiceFuture.fromHeaderPageResponse(
            listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions),
            new Func1<String, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(String nextPageLink) {
                    return listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions);
                }
            },
            serviceCallback);
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListPoolNodeCountsNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<Page<PoolNodeCounts>> listPoolNodeCountsNextAsync(final String nextPageLink, final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions) {
        return listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink, accountListPoolNodeCountsNextOptions)
            .map(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Page<PoolNodeCounts>>() {
                @Override
                public Page<PoolNodeCounts> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> response) {
                    return response.body();
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param accountListPoolNodeCountsNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;PoolNodeCounts&gt; object
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsNextWithServiceResponseAsync(final String nextPageLink, final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions) {
        return listPoolNodeCountsNextSinglePageAsync(nextPageLink, accountListPoolNodeCountsNextOptions)
            .concatMap(new Func1<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listPoolNodeCountsNextWithServiceResponseAsync(nextPageLink, accountListPoolNodeCountsNextOptions));
                }
            });
    }

    /**
     * Gets the number of Compute Nodes in each state, grouped by Pool. Note that the numbers returned may not always be up to date. If you need exact node counts, use a list query.
     *
    ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> * @param nextPageLink The NextLink from the previous successful call to List operation.
    ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> * @param accountListPoolNodeCountsNextOptions Additional parameters for the operation
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;PoolNodeCounts&gt; object wrapped in {@link ServiceResponseWithHeaders} if successful.
     */
    public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> listPoolNodeCountsNextSinglePageAsync(final String nextPageLink, final AccountListPoolNodeCountsNextOptions accountListPoolNodeCountsNextOptions) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        Validator.validate(accountListPoolNodeCountsNextOptions);
        UUID clientRequestId = null;
        if (accountListPoolNodeCountsNextOptions != null) {
            clientRequestId = accountListPoolNodeCountsNextOptions.clientRequestId();
        }
        Boolean returnClientRequestId = null;
        if (accountListPoolNodeCountsNextOptions != null) {
            returnClientRequestId = accountListPoolNodeCountsNextOptions.returnClientRequestId();
        }
        DateTime ocpDate = null;
        if (accountListPoolNodeCountsNextOptions != null) {
            ocpDate = accountListPoolNodeCountsNextOptions.ocpDate();
        }
        DateTimeRfc1123 ocpDateConverted = null;
        if (ocpDate != null) {
            ocpDateConverted = new DateTimeRfc1123(ocpDate);
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listPoolNodeCountsNext(nextUrl, this.client.acceptLanguage(), clientRequestId, returnClientRequestId, ocpDateConverted, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>>>() {
                @Override
                public Observable<ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponseWithHeaders<PageImpl<PoolNodeCounts>, AccountListPoolNodeCountsHeaders> result = listPoolNodeCountsNextDelegate(response);
                        return Observable.just(new ServiceResponseWithHeaders<Page<PoolNodeCounts>, AccountListPoolNodeCountsHeaders>(result.body(), result.headers(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

}
